diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2010-11-14 23:31:53 +0000 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2010-11-14 23:31:53 +0000 |
| commit | 0da42fcca7fb51966794608d51ee7cbb3bc7913b (patch) | |
| tree | e0320ce43b79faefe908b37caa6a9742218336dd /Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp | |
| parent | 2378b443c109f2052c5608ddcbef9dc5d581bd70 (diff) | |
Merged some FramebufferManager code into VideoCommon.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6417 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp')
| -rw-r--r-- | Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp | 340 |
1 files changed, 96 insertions, 244 deletions
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index a6abe4b32d..758759c8c6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -19,17 +19,39 @@ #include "FramebufferManager.h" #include "TextureConverter.h" -#include "XFB.h" #include "Render.h" extern bool s_bHaveFramebufferBlit; // comes from Render.cpp -FramebufferManager g_framebufferManager; +int FramebufferManager::m_targetWidth; +int FramebufferManager::m_targetHeight; +int FramebufferManager::m_msaaSamples; +int FramebufferManager::m_msaaCoverageSamples; -void FramebufferManager::Init(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples) +GLuint FramebufferManager::m_efbFramebuffer; +GLuint FramebufferManager::m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise +GLuint FramebufferManager::m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise + +// Only used in MSAA mode. +GLuint FramebufferManager::m_resolvedFramebuffer; +GLuint FramebufferManager::m_resolvedColorTexture; +GLuint FramebufferManager::m_resolvedDepthTexture; + +GLuint FramebufferManager::m_xfbFramebuffer; // Only used in MSAA mode + +FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples) { + m_efbFramebuffer = 0; + m_efbColor = 0; + m_efbDepth = 0; + m_resolvedFramebuffer = 0; + m_resolvedColorTexture = 0; + m_resolvedDepthTexture = 0; + m_xfbFramebuffer = 0; + m_targetWidth = targetWidth; m_targetHeight = targetHeight; + m_msaaSamples = msaaSamples; m_msaaCoverageSamples = msaaCoverageSamples; @@ -147,7 +169,7 @@ void FramebufferManager::Init(int targetWidth, int targetHeight, int msaaSamples // EFB framebuffer is currently bound. } -void FramebufferManager::Shutdown() +FramebufferManager::~FramebufferManager() { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); @@ -164,11 +186,9 @@ void FramebufferManager::Shutdown() glObj[0] = m_resolvedColorTexture; glObj[1] = m_resolvedDepthTexture; - glObj[2] = m_realXFBSource.texture; - glDeleteTextures(3, glObj); + glDeleteTextures(2, glObj); m_resolvedColorTexture = 0; m_resolvedDepthTexture = 0; - m_realXFBSource.texture = 0; glObj[0] = m_efbColor; glObj[1] = m_efbDepth; @@ -178,15 +198,9 @@ void FramebufferManager::Shutdown() glDeleteRenderbuffersEXT(2, glObj); m_efbColor = 0; m_efbDepth = 0; - - for (VirtualXFBListType::iterator it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it) - { - glDeleteTextures(1, &it->xfbSource.texture); - } - m_virtualXFBList.clear(); } -GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) const +GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) { if (m_msaaSamples <= 1) { @@ -216,7 +230,7 @@ GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) cons } } -GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) const +GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) { if (m_msaaSamples <= 1) { @@ -246,84 +260,7 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) cons } } -void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) -{ - if (g_ActiveConfig.bUseRealXFB) - copyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc); - else - copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc); -} - -const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) -{ - if (g_ActiveConfig.bUseRealXFB) - return getRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); - else - return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); -} - -FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height) -{ - u32 srcLower = xfbAddr; - u32 srcUpper = xfbAddr + 2 * width * height; - - VirtualXFBListType::iterator it; - for (it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it) - { - u32 dstLower = it->xfbAddr; - u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; - - if (dstLower >= srcLower && dstUpper <= srcUpper) - return it; - } - - // That address is not in the Virtual XFB list. - return m_virtualXFBList.end(); -} - -void FramebufferManager::replaceVirtualXFB() -{ - VirtualXFBListType::iterator it = m_virtualXFBList.begin(); - - s32 srcLower = it->xfbAddr; - s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; - s32 lineSize = 2 * it->xfbWidth; - - ++it; - - while (it != m_virtualXFBList.end()) - { - s32 dstLower = it->xfbAddr; - s32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; - - if (dstLower >= srcLower && dstUpper <= srcUpper) - { - // Invalidate the data - it->xfbAddr = 0; - it->xfbHeight = 0; - it->xfbWidth = 0; - } - else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) - { - s32 upperOverlap = (srcUpper - dstLower) / lineSize; - s32 lowerOverlap = (dstUpper - srcLower) / lineSize; - - if (upperOverlap > 0 && lowerOverlap < 0) - { - it->xfbAddr += lineSize * upperOverlap; - it->xfbHeight -= upperOverlap; - } - else if (lowerOverlap > 0) - { - it->xfbHeight -= lowerOverlap; - } - } - - ++it; - } -} - -void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) { u8* xfb_in_ram = Memory_GetPtr(xfbAddr); if (!xfb_in_ram) @@ -332,93 +269,61 @@ void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c return; } - XFB_Write(xfb_in_ram, sourceRc, fbWidth, fbHeight); + TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc); + TextureConverter::EncodeToRamYUYV(ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, fbWidth, fbHeight); } -void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void FramebufferManager::SetFramebuffer(GLuint fb) { - GLuint xfbTexture; - - VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight); - - if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) - { - // Replace the last virtual XFB - --it; - } - - if (it != m_virtualXFBList.end()) - { - // Overwrite an existing Virtual XFB. - - it->xfbAddr = xfbAddr; - it->xfbWidth = fbWidth; - it->xfbHeight = fbHeight; - - it->xfbSource.srcAddr = xfbAddr; - it->xfbSource.srcWidth = fbWidth; - it->xfbSource.srcHeight = fbHeight; - - it->xfbSource.texWidth = Renderer::GetTargetWidth(); - it->xfbSource.texHeight = Renderer::GetTargetHeight(); - it->xfbSource.sourceRc = Renderer::ConvertEFBRectangle(sourceRc); - - xfbTexture = it->xfbSource.texture; - - // Move this Virtual XFB to the front of the list. - m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, it); - - // Keep stale XFB data from being used - replaceVirtualXFB(); - } - else - { - // Create a new Virtual XFB and place it at the front of the list. - - glGenTextures(1, &xfbTexture); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : GetEFBFramebuffer()); +} -#if 0// XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible. - if (m_msaaSamples > 1) -#else - if (s_bHaveFramebufferBlit) -#endif - { - // In MSAA mode, allocate the texture image here. In non-MSAA mode, - // the image will be allocated by glCopyTexImage2D (later). +// Apply AA if enabled +GLuint FramebufferManager::ResolveAndGetRenderTarget(const EFBRectangle &source_rect) +{ + return GetEFBColorTexture(source_rect); +} - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, xfbTexture); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, m_targetWidth, m_targetHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); +GLuint FramebufferManager::ResolveAndGetDepthTarget(const EFBRectangle &source_rect) +{ + return GetEFBDepthTexture(source_rect); +} - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); - } +void XFBSource::Draw(const MathUtil::Rectangle<float> &sourcerc, + const MathUtil::Rectangle<float> &drawrc, int width, int height) const +{ + // Texture map xfbSource->texture onto the main buffer - VirtualXFB newVirt; + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); - newVirt.xfbAddr = xfbAddr; - newVirt.xfbWidth = fbWidth; - newVirt.xfbHeight = fbHeight; + glBegin(GL_QUADS); + glTexCoord2f(sourcerc.left, sourcerc.bottom); + glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0); + glVertex2f(drawrc.left, drawrc.bottom); - newVirt.xfbSource.srcAddr = xfbAddr; - newVirt.xfbSource.srcWidth = fbWidth; - newVirt.xfbSource.srcHeight = fbHeight; + glTexCoord2f(sourcerc.left, sourcerc.top); + glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1); + glVertex2f(drawrc.left, drawrc.top); - newVirt.xfbSource.texture = xfbTexture; - newVirt.xfbSource.texWidth = m_targetWidth; - newVirt.xfbSource.texHeight = m_targetHeight; - newVirt.xfbSource.sourceRc = Renderer::ConvertEFBRectangle(sourceRc); + glTexCoord2f(sourcerc.right, sourcerc.top); + glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1); + glVertex2f(drawrc.right, drawrc.top); - // Add the new Virtual XFB to the list + glTexCoord2f(sourcerc.right, sourcerc.bottom); + glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0); + glVertex2f(drawrc.right, drawrc.bottom); + glEnd(); - if ((int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) - { - // List overflowed; delete the oldest. - glDeleteTextures(1, &m_virtualXFBList.back().xfbSource.texture); - m_virtualXFBList.pop_back(); - } + GL_REPORT_ERRORD(); +} - m_virtualXFBList.push_front(newVirt); - } +void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) +{ + TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, texture); +} +void XFBSource::CopyEFB() +{ // Copy EFB data to XFB and restore render target again #if 0 @@ -429,10 +334,10 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight { // Just copy the EFB directly. - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer()); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, xfbTexture); - glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, 0, 0, m_targetWidth, m_targetHeight, 0); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); + glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, 0, 0, texWidth, texHeight, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); } @@ -441,16 +346,16 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight // OpenGL cannot copy directly from a multisampled framebuffer, so use // EXT_framebuffer_blit. - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_xfbFramebuffer); + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer()); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, FramebufferManager::GetXFBFramebuffer()); // Bind texture. - glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, xfbTexture, 0); + glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, texture, 0); GL_REPORT_FBO_ERROR(); glBlitFramebufferEXT( - 0, 0, m_targetWidth, m_targetHeight, - 0, 0, m_targetWidth, m_targetHeight, + 0, 0, texWidth, texHeight, + 0, 0, texWidth, texHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST ); @@ -458,89 +363,36 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); // Return to EFB. - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer()); } } -const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) +XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) { - xfbCount = 1; - - m_realXFBSource.texWidth = MAX_XFB_WIDTH; - m_realXFBSource.texHeight = MAX_XFB_HEIGHT; + GLuint texture; - m_realXFBSource.srcAddr = xfbAddr; - m_realXFBSource.srcWidth = fbWidth; - m_realXFBSource.srcHeight = fbHeight; + glGenTextures(1, &texture); - // OpenGL texture coordinates originate at the lower left, which is why - // sourceRc.top = fbHeight and sourceRc.bottom = 0. - m_realXFBSource.sourceRc.left = 0; - m_realXFBSource.sourceRc.top = fbHeight; - m_realXFBSource.sourceRc.right = fbWidth; - m_realXFBSource.sourceRc.bottom = 0; - - if (!m_realXFBSource.texture) +#if 0// XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible. + if (m_msaaSamples > 1) +#else + if (s_bHaveFramebufferBlit) +#endif { - glGenTextures(1, &m_realXFBSource.texture); + // In MSAA mode, allocate the texture image here. In non-MSAA mode, + // the image will be allocated by glCopyTexImage2D (later). - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_realXFBSource.texture); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, target_width, target_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); } - // Decode YUYV data from GameCube RAM - TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, m_realXFBSource.texture); - - m_overlappingXFBArray[0] = &m_realXFBSource; - - return &m_overlappingXFBArray[0]; -} - -const XFBSource** FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) -{ - xfbCount = 0; - - if (m_virtualXFBList.size() == 0) - { - // No Virtual XFBs available. - return NULL; - } - - u32 srcLower = xfbAddr; - u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight; - - VirtualXFBListType::reverse_iterator it; - for (it = m_virtualXFBList.rbegin(); it != m_virtualXFBList.rend(); ++it) - { - u32 dstLower = it->xfbAddr; - u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; - - if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) - { - m_overlappingXFBArray[xfbCount] = &(it->xfbSource); - xfbCount++; - } - } - - return &m_overlappingXFBArray[0]; -} - -void FramebufferManager::SetFramebuffer(GLuint fb) -{ - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : GetEFBFramebuffer()); + return new XFBSource(texture); } -// Apply AA if enabled -GLuint FramebufferManager::ResolveAndGetRenderTarget(const EFBRectangle &source_rect) +void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) { - return GetEFBColorTexture(source_rect); + *width = m_targetWidth; + *height = m_targetHeight; } - -GLuint FramebufferManager::ResolveAndGetDepthTarget(const EFBRectangle &source_rect) -{ - return GetEFBDepthTexture(source_rect); -} - - |
