summaryrefslogtreecommitdiff
path: root/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2010-11-14 23:31:53 +0000
committerJordan Woyak <jordan.woyak@gmail.com>2010-11-14 23:31:53 +0000
commit0da42fcca7fb51966794608d51ee7cbb3bc7913b (patch)
treee0320ce43b79faefe908b37caa6a9742218336dd /Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp
parent2378b443c109f2052c5608ddcbef9dc5d581bd70 (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.cpp340
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);
-}
-
-