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 | |
| 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')
27 files changed, 787 insertions, 1266 deletions
diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index f5a3ff2e2d..986ffe84af 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -4,6 +4,7 @@ set(SRCS Src/BPMemory.cpp Src/CPMemory.cpp Src/DLCache.cpp Src/Fifo.cpp + Src/FramebufferManagerBase.cpp Src/HiresTextures.cpp Src/ImageWrite.cpp Src/IndexGenerator.cpp diff --git a/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp b/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp new file mode 100644 index 0000000000..8dc21e88c4 --- /dev/null +++ b/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp @@ -0,0 +1,225 @@ +
+#include "FramebufferManagerBase.h"
+
+#include "Render.h"
+#include "VideoConfig.h"
+
+FramebufferManagerBase *g_framebuffer_manager;
+
+XFBSourceBase *FramebufferManagerBase::m_realXFBSource; // Only used in Real XFB mode
+FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
+const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[MAX_VIRTUAL_XFB];
+
+FramebufferManagerBase::FramebufferManagerBase()
+{
+ m_realXFBSource = NULL;
+
+ // can't hurt
+ memset(m_overlappingXFBArray, 0, sizeof(m_overlappingXFBArray));
+}
+
+FramebufferManagerBase::~FramebufferManagerBase()
+{
+ VirtualXFBListType::iterator
+ it = m_virtualXFBList.begin(),
+ vlend = m_virtualXFBList.end();
+ for (; it != vlend; ++it)
+ delete it->xfbSource;
+
+ m_virtualXFBList.clear();
+
+ delete m_realXFBSource;
+}
+
+const XFBSourceBase* const* FramebufferManagerBase::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);
+}
+
+const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
+{
+ xfbCount = 1;
+
+ if (!m_realXFBSource)
+ m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight);
+
+ m_realXFBSource->srcAddr = xfbAddr;
+
+ m_realXFBSource->srcWidth = MAX_XFB_WIDTH;
+ m_realXFBSource->srcHeight = MAX_XFB_HEIGHT;
+
+ m_realXFBSource->texWidth = fbWidth;
+ m_realXFBSource->texHeight = fbHeight;
+
+ // TODO: stuff only used by OGL... :/
+ // 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;
+
+ // Decode YUYV data from GameCube RAM
+ m_realXFBSource->DecodeToTexture(xfbAddr, fbWidth, fbHeight);
+
+ m_overlappingXFBArray[0] = m_realXFBSource;
+ return &m_overlappingXFBArray[0];
+}
+
+const XFBSourceBase* const* FramebufferManagerBase::GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
+{
+ xfbCount = 0;
+
+ if (m_virtualXFBList.empty()) // no Virtual XFBs available
+ return NULL;
+
+ u32 srcLower = xfbAddr;
+ u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
+
+ VirtualXFBListType::reverse_iterator
+ it = m_virtualXFBList.rbegin(),
+ vlend = m_virtualXFBList.rend();
+ for (; it != vlend; ++it)
+ {
+ VirtualXFB* vxfb = &*it;
+
+ u32 dstLower = vxfb->xfbAddr;
+ u32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
+
+ if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
+ {
+ m_overlappingXFBArray[xfbCount] = vxfb->xfbSource;
+ ++xfbCount;
+ }
+ }
+
+ return &m_overlappingXFBArray[0];
+}
+
+void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
+{
+ if (g_ActiveConfig.bUseRealXFB)
+ g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
+ else
+ CopyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
+}
+
+void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
+{
+ VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, fbWidth, fbHeight);
+
+ if (m_virtualXFBList.end() == vxfb)
+ {
+ if (m_virtualXFBList.size() < MAX_VIRTUAL_XFB)
+ {
+ // create a new Virtual XFB and place it at the front of the list
+ VirtualXFB v;
+ m_virtualXFBList.push_front(v);
+ vxfb = m_virtualXFBList.begin();
+ }
+ else
+ {
+ // Replace the last virtual XFB
+ --vxfb;
+ }
+ }
+ //else // replace existing virtual XFB
+
+ // move this Virtual XFB to the front of the list.
+ if (m_virtualXFBList.begin() != vxfb)
+ m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, vxfb);
+
+ unsigned int target_width, target_height;
+ g_framebuffer_manager->GetTargetSize(&target_width, &target_height, sourceRc);
+
+ // recreate if needed
+ if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height))
+ {
+ //delete vxfb->xfbSource;
+ //vxfb->xfbSource = NULL;
+ }
+
+ if (!vxfb->xfbSource)
+ {
+ vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height);
+ vxfb->xfbSource->texWidth = target_width;
+ vxfb->xfbSource->texHeight = target_height;
+ }
+
+ vxfb->xfbSource->srcAddr = vxfb->xfbAddr = xfbAddr;
+ vxfb->xfbSource->srcWidth = vxfb->xfbWidth = fbWidth;
+ vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight;
+
+ vxfb->xfbSource->sourceRc = Renderer::ConvertEFBRectangle(sourceRc);
+
+ // keep stale XFB data from being used
+ ReplaceVirtualXFB();
+
+ Renderer::ResetAPIState(); // reset any game specific settings
+
+ // Copy EFB data to XFB and restore render target again
+ vxfb->xfbSource->CopyEFB();
+
+ Renderer::RestoreAPIState();
+}
+
+FramebufferManagerBase::VirtualXFBListType::iterator FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height)
+{
+ const u32 srcLower = xfbAddr;
+ const u32 srcUpper = xfbAddr + 2 * width * height;
+
+ VirtualXFBListType::iterator it = m_virtualXFBList.begin();
+ for (; it != m_virtualXFBList.end(); ++it)
+ {
+ const u32 dstLower = it->xfbAddr;
+ const u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
+
+ if (dstLower >= srcLower && dstUpper <= srcUpper)
+ break;
+ }
+
+ return it;
+}
+
+void FramebufferManagerBase::ReplaceVirtualXFB()
+{
+ VirtualXFBListType::iterator it = m_virtualXFBList.begin();
+
+ const s32 srcLower = it->xfbAddr;
+ const s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
+ const s32 lineSize = 2 * it->xfbWidth;
+
+ ++it;
+
+ for (; it != m_virtualXFBList.end(); ++it)
+ {
+ 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;
+ }
+ }
+ }
+}
diff --git a/Source/Core/VideoCommon/Src/FramebufferManagerBase.h b/Source/Core/VideoCommon/Src/FramebufferManagerBase.h new file mode 100644 index 0000000000..a67346fe7b --- /dev/null +++ b/Source/Core/VideoCommon/Src/FramebufferManagerBase.h @@ -0,0 +1,92 @@ +
+#ifndef _FRAMEBUFFERMANAGER_H
+#define _FRAMEBUFFERMANAGER_H
+
+#include <list>
+
+#include "VideoCommon.h"
+
+inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
+{
+ return !((aLower >= bUpper) || (bLower >= aUpper));
+}
+
+struct XFBSourceBase
+{
+ virtual ~XFBSourceBase() {}
+
+ // TODO: only DX9 uses the width/height params
+ virtual void Draw(const MathUtil::Rectangle<float> &sourcerc,
+ const MathUtil::Rectangle<float> &drawrc, int width, int height) const = 0;
+
+ virtual void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) = 0;
+
+ virtual void CopyEFB() = 0;
+
+ u32 srcAddr;
+ u32 srcWidth;
+ u32 srcHeight;
+
+ int texWidth;
+ int texHeight;
+
+ // TODO: only used by OGL
+ TargetRectangle sourceRc;
+};
+
+class FramebufferManagerBase
+{
+public:
+ enum
+ {
+ // There may be multiple XFBs in GameCube RAM. This is the maximum number to
+ // virtualize.
+ MAX_VIRTUAL_XFB = 8
+ };
+
+ FramebufferManagerBase();
+ virtual ~FramebufferManagerBase();
+
+ static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
+ static const XFBSourceBase* const* GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
+
+protected:
+ struct VirtualXFB
+ {
+ VirtualXFB() : xfbSource(NULL) {}
+
+ // Address and size in GameCube RAM
+ u32 xfbAddr;
+ u32 xfbWidth;
+ u32 xfbHeight;
+
+ XFBSourceBase *xfbSource;
+ };
+
+ typedef std::list<VirtualXFB> VirtualXFBListType;
+
+private:
+ virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) = 0;
+ // TODO: figure out why OGL is different for this guy
+ virtual void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) = 0;
+
+ static VirtualXFBListType::iterator FindVirtualXFB(u32 xfbAddr, u32 width, u32 height);
+
+ static void ReplaceVirtualXFB();
+
+ // TODO: merge these virtual funcs, they are nearly all the same
+ virtual void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) = 0;
+ static void CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
+
+ static const XFBSourceBase* const* GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
+ static const XFBSourceBase* const* GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
+
+ static XFBSourceBase *m_realXFBSource; // Only used in Real XFB mode
+ static VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
+
+ static const XFBSourceBase* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
+};
+
+extern FramebufferManagerBase *g_framebuffer_manager;
+
+#endif
diff --git a/Source/Core/VideoCommon/Src/SConscript b/Source/Core/VideoCommon/Src/SConscript index fd1ffe83b4..a48e419957 100644 --- a/Source/Core/VideoCommon/Src/SConscript +++ b/Source/Core/VideoCommon/Src/SConscript @@ -29,6 +29,7 @@ files = [ 'VertexLoader_TextCoord.cpp', 'TextureConversionShader.cpp', 'ImageWrite.cpp', + 'FramebufferManagerBase.cpp', 'VertexManagerBase.cpp', 'TextureCacheBase.cpp', 'Statistics.cpp', diff --git a/Source/Core/VideoCommon/VideoCommon.vcproj b/Source/Core/VideoCommon/VideoCommon.vcproj index 5a932c3363..b023fd13bd 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcproj +++ b/Source/Core/VideoCommon/VideoCommon.vcproj @@ -731,6 +731,14 @@ Name="Base" > <File + RelativePath=".\Src\FramebufferManagerBase.cpp" + > + </File> + <File + RelativePath=".\Src\FramebufferManagerBase.h" + > + </File> + <File RelativePath=".\Src\TextureCacheBase.cpp" > </File> diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp index 4f38b8c483..332c792d88 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp @@ -24,7 +24,7 @@ #include "PixelShaderCache.h" #include "VertexShaderCache.h" -FramebufferManager g_framebufferManager; +FramebufferManager::Efb FramebufferManager::m_efb; D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; } ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; } @@ -33,10 +33,17 @@ D3DTexture2D* &FramebufferManager::GetEFBDepthTexture() { return m_efb.depth_tex D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; } ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; } -void FramebufferManager::Create() +FramebufferManager::FramebufferManager() { + m_efb.color_tex = NULL; + m_efb.color_staging_buf = NULL; + m_efb.depth_tex = NULL; + m_efb.depth_staging_buf = NULL; + m_efb.depth_read_texture = NULL; + unsigned int target_width = Renderer::GetFullTargetWidth(); unsigned int target_height = Renderer::GetFullTargetHeight(); + ID3D11Texture2D* buf; D3D11_TEXTURE2D_DESC texdesc; HRESULT hr; @@ -80,228 +87,72 @@ void FramebufferManager::Create() D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)"); } -void FramebufferManager::Destroy() +FramebufferManager::~FramebufferManager() { SAFE_RELEASE(m_efb.color_tex); SAFE_RELEASE(m_efb.color_staging_buf); SAFE_RELEASE(m_efb.depth_tex); SAFE_RELEASE(m_efb.depth_staging_buf); SAFE_RELEASE(m_efb.depth_read_texture); - - for (VirtualXFBListType::iterator it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it) - SAFE_RELEASE(it->xfbSource.tex); - - m_virtualXFBList.clear(); - SAFE_RELEASE(m_realXFBSource.tex); } -void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) { - copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc); + // TODO + PanicAlert("CopyToRealXFB not implemented, yet\n"); } -const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) +XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) { - return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + return new XFBSource(D3DTexture2D::Create(target_width, target_height, + (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), + D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM)); } -FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height) +void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) { - u32 srcLower = xfbAddr; - u32 srcUpper = xfbAddr + 2 * width * height; + const float scaleX = Renderer::GetXFBScaleX(); + const float scaleY = Renderer::GetXFBScaleY(); - 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; + TargetRectangle targetSource; - if (dstLower >= srcLower && dstUpper <= srcUpper) - return it; - } + targetSource.top = (int)(sourceRc.top *scaleY); + targetSource.bottom = (int)(sourceRc.bottom *scaleY); + targetSource.left = (int)(sourceRc.left *scaleX); + targetSource.right = (int)(sourceRc.right * scaleX); - // That address is not in the Virtual XFB list. - return m_virtualXFBList.end(); + *width = targetSource.right - targetSource.left; + *height = targetSource.bottom - targetSource.top; } -void FramebufferManager::replaceVirtualXFB() +void XFBSource::Draw(const MathUtil::Rectangle<float> &sourcerc, + const MathUtil::Rectangle<float> &drawrc, int width, int height) const { - 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; - } + D3D::drawShadedTexSubQuad(tex->GetSRV(), &sourcerc, + texWidth, texHeight, &drawrc, PixelShaderCache::GetColorCopyProgram(), + VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); } -void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) { - // TODO - PanicAlert("copyToRealXFB not implemented, yet\n"); + // TODO: + PanicAlert("RealXFB not implemented, yet\n"); } -void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void XFBSource::CopyEFB() { - D3DTexture2D* xfbTex; - HRESULT hr = 0; - - VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight); - - if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) - { - // Replace the last virtual XFB (might cause glitches, but better than allocating 50 XFBs...) - // TODO: Reencode last virtual XFB to RAM to avoid glitches? - --it; - } - - float scaleX = Renderer::GetXFBScaleX(); - float scaleY = Renderer::GetXFBScaleY(); - TargetRectangle targetSource,efbSource; - efbSource = Renderer::ConvertEFBRectangle(sourceRc); - targetSource.top = (int)(sourceRc.top * scaleY); - targetSource.bottom = (int)(sourceRc.bottom * scaleY); - targetSource.left = (int)(sourceRc.left * scaleX); - targetSource.right = (int)(sourceRc.right * scaleX); - unsigned int target_width = targetSource.right - targetSource.left; - unsigned int target_height = targetSource.bottom - targetSource.top; - 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; - - if (it->xfbSource.texWidth != target_width || it->xfbSource.texHeight != target_height || !(it->xfbSource.tex)) - { - SAFE_RELEASE(it->xfbSource.tex); - it->xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM); - if (it->xfbSource.tex == NULL) PanicAlert("Failed to create XFB texture\n"); - } - xfbTex = it->xfbSource.tex; - - it->xfbSource.texWidth = target_width; - it->xfbSource.texHeight = target_height; - - // 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. - VirtualXFB newVirt; - - newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM); - if (newVirt.xfbSource.tex == NULL) PanicAlert("Failed to create a new virtual XFB"); - - newVirt.xfbAddr = xfbAddr; - newVirt.xfbWidth = fbWidth; - newVirt.xfbHeight = fbHeight; - - xfbTex = newVirt.xfbSource.tex; - newVirt.xfbSource.texWidth = target_width; - newVirt.xfbSource.texHeight = target_height; - - // Add the new Virtual XFB to the list - if (m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) - { - // List overflowed; delete the oldest. - m_virtualXFBList.back().xfbSource.tex->Release(); - m_virtualXFBList.pop_back(); - WARN_LOG(VIDEO, "Virtual XFB list overflown, releasing oldest virtual XFB"); - } - m_virtualXFBList.push_front(newVirt); - } - if (!xfbTex->GetRTV()) return; - - Renderer::ResetAPIState(); // reset any game specific settings - // Copy EFB data to XFB and restore render target again - D3D11_RECT sourcerect = CD3D11_RECT(efbSource.left, efbSource.top, efbSource.right, efbSource.bottom); - D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)target_width, (float)target_height); + const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight); + D3D::context->RSSetViewports(1, &vp); - D3D::context->OMSetRenderTargets(1, &xfbTex->GetRTV(), NULL); + D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL); D3D::SetLinearCopySampler(); - D3D::drawShadedTexQuad(GetEFBColorTexture()->GetSRV(), &sourcerect, - Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), - PixelShaderCache::GetColorCopyProgram(), VertexShaderCache::GetSimpleVertexShader(), - VertexShaderCache::GetSimpleInputLayout()); - D3D::context->OMSetRenderTargets(1, &GetEFBColorTexture()->GetRTV(), GetEFBDepthTexture()->GetDSV()); - Renderer::RestoreAPIState(); -} - -const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) -{ - PanicAlert("getRealXFBSource not implemented, yet\n"); - return NULL; -} - -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::iterator it; - for (it = m_virtualXFBList.end(); it != m_virtualXFBList.begin();) - { - --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]; + + D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(), + Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), + PixelShaderCache::GetColorCopyProgram(), VertexShaderCache::GetSimpleVertexShader(), + VertexShaderCache::GetSimpleInputLayout()); + + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), + FramebufferManager::GetEFBDepthTexture()->GetDSV()); } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h index 5ec009bda1..f8cebb8b56 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h @@ -18,8 +18,9 @@ #ifndef _FBMANAGER_D3D_H_ #define _FBMANAGER_D3D_H_ -#include <list> #include "D3DBase.h" +#include "D3DTexture.h" +#include "FramebufferManagerBase.h" // On the GameCube, the game sends a request for the graphics processor to // transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM @@ -52,82 +53,40 @@ // There may be multiple XFBs in GameCube RAM. This is the maximum number to // virtualize. -const int MAX_VIRTUAL_XFB = 8; -inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) +struct XFBSource : public XFBSourceBase { - return !((aLower >= bUpper) || (bLower >= aUpper)); -} + XFBSource(D3DTexture2D *_tex) : tex(_tex) {} + ~XFBSource() { tex->Release(); } -struct XFBSource -{ - XFBSource() : srcAddr(0), srcWidth(0), srcHeight(0), tex(NULL), texWidth(0), texHeight(0) {} - - u32 srcAddr; - u32 srcWidth; - u32 srcHeight; + void Draw(const MathUtil::Rectangle<float> &sourcerc, + const MathUtil::Rectangle<float> &drawrc, int width, int height) const; + void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight); + void CopyEFB(); - D3DTexture2D* tex; - unsigned int texWidth; - unsigned int texHeight; + D3DTexture2D* const tex; }; -class FramebufferManager +class FramebufferManager : public FramebufferManagerBase { public: - FramebufferManager() - { - m_efb.color_tex = NULL; - m_efb.color_staging_buf = NULL; - m_efb.depth_tex = NULL; - m_efb.depth_staging_buf = NULL; - m_efb.depth_read_texture = NULL; - - m_realXFBSource.tex = NULL; - } + FramebufferManager(); + ~FramebufferManager(); - void Create(); - void Destroy(); + static D3DTexture2D* &GetEFBColorTexture(); + static ID3D11Texture2D* &GetEFBColorStagingBuffer(); - void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); - - D3DTexture2D* &GetEFBColorTexture(); - ID3D11Texture2D* &GetEFBColorStagingBuffer(); - - D3DTexture2D* &GetEFBDepthTexture(); - D3DTexture2D* &GetEFBDepthReadTexture(); - ID3D11Texture2D* &GetEFBDepthStagingBuffer(); + static D3DTexture2D* &GetEFBDepthTexture(); + static D3DTexture2D* &GetEFBDepthReadTexture(); + static ID3D11Texture2D* &GetEFBDepthStagingBuffer(); private: + XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height); + void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc); - struct VirtualXFB - { - // Address and size in GameCube RAM - u32 xfbAddr; - u32 xfbWidth; - u32 xfbHeight; - - XFBSource xfbSource; - }; + void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - typedef std::list<VirtualXFB> VirtualXFBListType; - - VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height); - - void replaceVirtualXFB(); - - void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); - const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); - - XFBSource m_realXFBSource; // Only used in Real XFB mode - VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode - - const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB]; - - struct + static struct Efb { D3DTexture2D* color_tex; ID3D11Texture2D* color_staging_buf; @@ -138,6 +97,4 @@ private: } m_efb; }; -extern FramebufferManager g_framebufferManager; - #endif diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index aed30f1c96..227d87c091 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -237,7 +237,7 @@ static const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] = void SetupDeviceObjects() { - g_framebufferManager.Create(); + g_framebuffer_manager = new FramebufferManager; HRESULT hr; float colmat[20]= {0.0f}; @@ -319,7 +319,8 @@ void SetupDeviceObjects() // Kill off all POOL_DEFAULT device objects. void TeardownDeviceObjects() { - g_framebufferManager.Destroy(); + delete g_framebuffer_manager; + SAFE_RELEASE(access_efb_cbuf); SAFE_RELEASE(clearblendstates[0]); SAFE_RELEASE(clearblendstates[1]); @@ -383,14 +384,14 @@ bool Renderer::Init() D3D::gfxstate->samplerdesc[stage].MaxAnisotropy = g_ActiveConfig.iMaxAnisotropy; float ClearColor[4] = { 0.f, 0.f, 0.f, 0.f }; - D3D::context->ClearRenderTargetView(g_framebufferManager.GetEFBColorTexture()->GetRTV(), ClearColor); - D3D::context->ClearDepthStencilView(g_framebufferManager.GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0); + D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), ClearColor); + D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0); D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)(s_Fulltarget_width - s_target_width) / 2.f, (float)(s_Fulltarget_height - s_target_height) / 2.f, (float)s_target_width, (float)s_target_height); D3D::context->RSSetViewports(1, &vp); - D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); D3D::BeginFrame(); D3D::gfxstate->rastdesc.ScissorEnable = TRUE; @@ -560,7 +561,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect // just use progressive. if (g_ActiveConfig.bUseXFB) { - g_framebufferManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); + FramebufferManager::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); } else { @@ -700,9 +701,9 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 1.f, 1.f); D3D::context->RSSetViewports(1, &vp); D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf); - D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBDepthReadTexture()->GetRTV(), NULL); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), NULL); D3D::SetPointCopySampler(); - D3D::drawShadedTexQuad(g_framebufferManager.GetEFBDepthTexture()->GetSRV(), + D3D::drawShadedTexQuad(FramebufferManager::GetEFBDepthTexture()->GetSRV(), &RectToLock, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), @@ -710,12 +711,12 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); - D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); // copy to system memory D3D11_BOX box = CD3D11_BOX(0, 0, 0, 1, 1, 1); - read_tex = g_framebufferManager.GetEFBDepthStagingBuffer(); - D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBDepthReadTexture()->GetTex(), 0, &box); + read_tex = FramebufferManager::GetEFBDepthStagingBuffer(); + D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBDepthReadTexture()->GetTex(), 0, &box); RestoreAPIState(); // restore game state @@ -732,9 +733,9 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) else if (type == PEEK_COLOR) { // we can directly copy to system memory here - read_tex = g_framebufferManager.GetEFBColorStagingBuffer(); + read_tex = FramebufferManager::GetEFBColorStagingBuffer(); D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1); - D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBColorTexture()->GetTex(), 0, &box); + D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBColorTexture()->GetTex(), 0, &box); // read the data from system memory D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map); @@ -755,7 +756,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // TODO: The first five PE registers may change behavior of EFB pokes, this isn't implemented, yet. ResetAPIState(); - D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), NULL); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), NULL); D3D::drawColorQuad(rgbaColor, (float)RectToLock.left * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f, - (float)RectToLock.top * 2.f / (float)Renderer::GetFullTargetHeight() + 1.f, (float)RectToLock.right * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f, @@ -838,9 +839,11 @@ void UpdateViewport() else { D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); - g_framebufferManager.Destroy(); - g_framebufferManager.Create(); - D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV()); + + delete g_framebuffer_manager; + g_framebuffer_manager = new FramebufferManager; + + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); } } @@ -917,7 +920,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; u32 xfbCount = 0; - const XFBSource** xfbSourceList = g_framebufferManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { g_VideoInitialize.pCopiedToXFB(false); @@ -956,7 +959,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if(g_ActiveConfig.bUseXFB) { - const XFBSource* xfbSource; + const XFBSourceBase* xfbSource; // draw each xfb source for (u32 i = 0; i < xfbCount; ++i) @@ -1000,13 +1003,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons drawRc.right = 1; } - D3D::drawShadedTexSubQuad(xfbSource->tex->GetSRV(), &sourceRc, xfbSource->texWidth, xfbSource->texHeight, &drawRc, PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); + xfbSource->Draw(sourceRc, drawRc, 0, 0); } } else { TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); - D3DTexture2D* read_texture = g_framebufferManager.GetEFBColorTexture(); + D3DTexture2D* read_texture = FramebufferManager::GetEFBColorTexture(); D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); } // done with drawing the game stuff, good moment to save a screenshot @@ -1140,14 +1143,15 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons s_target_height = (int)(EFB_HEIGHT * EFByScale); D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); - g_framebufferManager.Destroy(); - g_framebufferManager.Create(); + + delete g_framebuffer_manager; + g_framebuffer_manager = new FramebufferManager; } // begin next frame Renderer::RestoreAPIState(); D3D::BeginFrame(); - D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); UpdateViewport(); VertexShaderManager::SetViewportChanged(); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index ee799ea407..e69e6865d4 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -147,12 +147,12 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL); D3D::drawShadedTexQuad( - (bFromZBuffer) ? g_framebufferManager.GetEFBDepthTexture()->GetSRV() : g_framebufferManager.GetEFBColorTexture()->GetSRV(), + (bFromZBuffer) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(), &sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), (bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); - D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); Renderer::RestoreAPIState(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp index 2673977191..75fd76b2da 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp @@ -501,15 +501,15 @@ static void DX9DebuggerUpdateScreen() D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->StretchRect(g_framebufferManager.GetEFBColorRTSurface(), NULL, + D3D::dev->StretchRect(FramebufferManager::GetEFBColorRTSurface(), NULL, D3D::GetBackBufferSurface(), NULL, D3DTEXF_LINEAR); D3D::dev->EndScene(); D3D::dev->Present(NULL, NULL, NULL, NULL); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); D3D::dev->BeginScene(); } else diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp index 85b4b724f7..6bf677fdfe 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp @@ -23,117 +23,84 @@ #include "VertexShaderCache.h" #include "TextureConverter.h" +// TODO: this is probably somewhere else +#define SAFE_RELEASE(p) if (p) { (p)->Release(); (p) = NULL; } + #undef CHECK #define CHECK(hr, Message, ...) if (FAILED(hr)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); } -FramebufferManager g_framebufferManager; - -LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorRTSurface() -{ - return s_efb_color_surface; -} - -LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthRTSurface() -{ - return s_efb_depth_surface; -} - -LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorOffScreenRTSurface() -{ - return s_efb_color_OffScreenReadBuffer; -} +FramebufferManager::Efb FramebufferManager::s_efb; -LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthOffScreenRTSurface() +FramebufferManager::FramebufferManager() { - return s_efb_depth_OffScreenReadBuffer; -} + s_efb.color_texture = NULL; + s_efb.colorRead_texture = NULL; + s_efb.depth_texture = NULL; + s_efb.depthRead_texture = NULL; -LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorReadSurface() -{ - return s_efb_color_ReadBuffer; -} + s_efb.depth_surface = NULL; + s_efb.color_surface = NULL; + s_efb.color_ReadBuffer = NULL; + s_efb.depth_ReadBuffer = NULL; + s_efb.color_OffScreenReadBuffer = NULL; + s_efb.depth_OffScreenReadBuffer = NULL; -LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthReadSurface() -{ - return s_efb_depth_ReadBuffer; -} + s_efb.color_surface_Format = D3DFMT_FORCE_DWORD; + s_efb.depth_surface_Format = D3DFMT_FORCE_DWORD; + s_efb.depth_ReadBuffer_Format = D3DFMT_FORCE_DWORD; -D3DFORMAT FramebufferManager::GetEFBDepthRTSurfaceFormat() -{ - return s_efb_depth_surface_Format; -} - -D3DFORMAT FramebufferManager::GetEFBDepthReadSurfaceFormat() -{ - return s_efb_depth_ReadBuffer_Format; -} - -D3DFORMAT FramebufferManager::GetEFBColorRTSurfaceFormat() -{ - return s_efb_color_surface_Format; -} - -LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBColorTexture() -{ - return s_efb_color_texture; -} - -LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBDepthTexture() -{ - return s_efb_depth_texture; -} - -void FramebufferManager::Create() -{ // Simplest possible setup to start with. int target_width = Renderer::GetFullTargetWidth(); int target_height = Renderer::GetFullTargetHeight(); - s_efb_color_surface_Format = D3DFMT_A8R8G8B8; + s_efb.color_surface_Format = D3DFMT_A8R8G8B8; // Get the framebuffer texture - HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format, - D3DPOOL_DEFAULT, &s_efb_color_texture, NULL); - if(s_efb_color_texture) + HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb.color_surface_Format, + D3DPOOL_DEFAULT, &s_efb.color_texture, NULL); + if (s_efb.color_texture) { - hr = s_efb_color_texture->GetSurfaceLevel(0, &s_efb_color_surface); + hr = s_efb.color_texture->GetSurfaceLevel(0, &s_efb.color_surface); } CHECK(hr, "Create color texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); - hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format, - D3DPOOL_DEFAULT, &s_efb_colorRead_texture, NULL); + hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb.color_surface_Format, + D3DPOOL_DEFAULT, &s_efb.colorRead_texture, NULL); CHECK(hr, "Create Color Read Texture (hr=%#x)", hr); - if(s_efb_colorRead_texture) + if (s_efb.colorRead_texture) { - s_efb_colorRead_texture->GetSurfaceLevel(0, &s_efb_color_ReadBuffer); + s_efb.colorRead_texture->GetSurfaceLevel(0, &s_efb.color_ReadBuffer); } // Create an offscreen surface that we can lock to retrieve the data - hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, s_efb_color_surface_Format, D3DPOOL_SYSTEMMEM, &s_efb_color_OffScreenReadBuffer, NULL); + hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, s_efb.color_surface_Format, D3DPOOL_SYSTEMMEM, &s_efb.color_OffScreenReadBuffer, NULL); CHECK(hr, "Create offscreen color surface (hr=%#x)", hr); // Select a Z-buffer format with hardware support - D3DFORMAT *DepthTexFormats = new D3DFORMAT[5]; - DepthTexFormats[0] = FOURCC_INTZ; - DepthTexFormats[1] = FOURCC_DF24; - DepthTexFormats[2] = FOURCC_RAWZ; - DepthTexFormats[3] = FOURCC_DF16; - DepthTexFormats[4] = D3DFMT_D24X8; - - for(int i = 0; i < 5; i++) + D3DFORMAT DepthTexFormats[5] = { + FOURCC_INTZ, + FOURCC_DF24, + FOURCC_RAWZ, + FOURCC_DF16, + D3DFMT_D24X8 + }; + + for (int i = 0; i < 5; ++i) { - s_efb_depth_surface_Format = DepthTexFormats[i]; + s_efb.depth_surface_Format = DepthTexFormats[i]; // Create the framebuffer depth texture - hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_DEPTHSTENCIL, s_efb_depth_surface_Format, - D3DPOOL_DEFAULT, &s_efb_depth_texture, NULL); + hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_DEPTHSTENCIL, s_efb.depth_surface_Format, + D3DPOOL_DEFAULT, &s_efb.depth_texture, NULL); if (!FAILED(hr)) break; } + CHECK(hr, "Framebuffer depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); // Get the Surface - if(s_efb_depth_texture) + if (s_efb.depth_texture) { - s_efb_depth_texture->GetSurfaceLevel(0, &s_efb_depth_surface); + s_efb.depth_texture->GetSurfaceLevel(0, &s_efb.depth_surface); } + // Create a 4x4 pixel texture to work as a buffer for peeking - if(s_efb_depth_surface_Format == FOURCC_RAWZ || s_efb_depth_surface_Format == D3DFMT_D24X8) + if (s_efb.depth_surface_Format == FOURCC_RAWZ || s_efb.depth_surface_Format == D3DFMT_D24X8) { DepthTexFormats[0] = D3DFMT_A8R8G8B8; } @@ -141,161 +108,82 @@ void FramebufferManager::Create() { DepthTexFormats[0] = D3DFMT_R32F; } + DepthTexFormats[1] = D3DFMT_A8R8G8B8; - for(int i = 0; i < 2; i++) + for (int i = 0; i < 2; ++i) { - s_efb_depth_ReadBuffer_Format = DepthTexFormats[i]; + s_efb.depth_ReadBuffer_Format = DepthTexFormats[i]; // Get the framebuffer Depth texture - hr = D3D::dev->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, s_efb_depth_ReadBuffer_Format, - D3DPOOL_DEFAULT, &s_efb_depthRead_texture, NULL); + hr = D3D::dev->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, s_efb.depth_ReadBuffer_Format, + D3DPOOL_DEFAULT, &s_efb.depthRead_texture, NULL); if (!FAILED(hr)) break; } CHECK(hr, "Create depth read texture (hr=%#x)", hr); - if(s_efb_depthRead_texture) + if (s_efb.depthRead_texture) { - s_efb_depthRead_texture->GetSurfaceLevel(0, &s_efb_depth_ReadBuffer); + s_efb.depthRead_texture->GetSurfaceLevel(0, &s_efb.depth_ReadBuffer); } + // Create an offscreen surface that we can lock to retrieve the data - hr = D3D::dev->CreateOffscreenPlainSurface(4, 4, s_efb_depth_ReadBuffer_Format, D3DPOOL_SYSTEMMEM, &s_efb_depth_OffScreenReadBuffer, NULL); + hr = D3D::dev->CreateOffscreenPlainSurface(4, 4, s_efb.depth_ReadBuffer_Format, D3DPOOL_SYSTEMMEM, &s_efb.depth_OffScreenReadBuffer, NULL); CHECK(hr, "Create depth offscreen surface (hr=%#x)", hr); - delete [] DepthTexFormats; } -void FramebufferManager::Destroy() +FramebufferManager::~FramebufferManager() { - if (s_efb_depth_surface) - s_efb_depth_surface->Release(); - s_efb_depth_surface = NULL; - - if (s_efb_color_surface) - s_efb_color_surface->Release(); - s_efb_color_surface = NULL; - - if (s_efb_color_ReadBuffer) - s_efb_color_ReadBuffer->Release(); - s_efb_color_ReadBuffer = NULL; - - if (s_efb_depth_ReadBuffer) - s_efb_depth_ReadBuffer->Release(); - s_efb_depth_ReadBuffer = NULL; - - if (s_efb_color_OffScreenReadBuffer) - s_efb_color_OffScreenReadBuffer->Release(); - s_efb_color_OffScreenReadBuffer = NULL; - - if (s_efb_depth_OffScreenReadBuffer) - s_efb_depth_OffScreenReadBuffer->Release(); - s_efb_depth_OffScreenReadBuffer = NULL; - - if (s_efb_color_texture) - s_efb_color_texture->Release(); - s_efb_color_texture = NULL; - - if (s_efb_colorRead_texture) - s_efb_colorRead_texture->Release(); - s_efb_colorRead_texture = NULL; - - if (s_efb_depth_texture) - s_efb_depth_texture->Release(); - s_efb_depth_texture = NULL; - - if (s_efb_depthRead_texture) - s_efb_depthRead_texture->Release(); - s_efb_depthRead_texture = NULL; - - for (VirtualXFBListType::iterator it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it) - { - if(it->xfbSource.texture) - it->xfbSource.texture->Release(); - } - m_virtualXFBList.clear(); - if(m_realXFBSource.texture) - m_realXFBSource.texture->Release(); - m_realXFBSource.texture = NULL; - + SAFE_RELEASE(s_efb.depth_surface); + SAFE_RELEASE(s_efb.color_surface); + SAFE_RELEASE(s_efb.color_ReadBuffer); + SAFE_RELEASE(s_efb.depth_ReadBuffer); + SAFE_RELEASE(s_efb.color_OffScreenReadBuffer); + SAFE_RELEASE(s_efb.depth_OffScreenReadBuffer); + SAFE_RELEASE(s_efb.color_texture); + SAFE_RELEASE(s_efb.colorRead_texture); + SAFE_RELEASE(s_efb.depth_texture); + SAFE_RELEASE(s_efb.depthRead_texture); } -void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) { - if (g_ActiveConfig.bUseRealXFB) - copyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc); - else - copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc); -} + LPDIRECT3DTEXTURE9 tex; + D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, + s_efb.color_surface_Format, D3DPOOL_DEFAULT, &tex, NULL); -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); + return new XFBSource(tex); } -FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height) +void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) { - u32 srcLower = xfbAddr; - u32 srcUpper = xfbAddr + 2 * width * height; + const float scaleX = Renderer::GetXFBScaleX(); + const float scaleY = Renderer::GetXFBScaleY(); - 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; + TargetRectangle targetSource; - if (dstLower >= srcLower && dstUpper <= srcUpper) - return it; - } + targetSource.top = (int)(sourceRc.top *scaleY); + targetSource.bottom = (int)(sourceRc.bottom *scaleY); + targetSource.left = (int)(sourceRc.left *scaleX); + targetSource.right = (int)(sourceRc.right * scaleX); - // That address is not in the Virtual XFB list. - return m_virtualXFBList.end(); + *width = targetSource.right - targetSource.left; + *height = targetSource.bottom - targetSource.top; } -void FramebufferManager::replaceVirtualXFB() +void XFBSource::Draw(const MathUtil::Rectangle<float> &sourcerc, + const MathUtil::Rectangle<float> &drawrc, int width, int height) const { - 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; + D3D::drawShadedTexSubQuad(texture, &sourcerc, texWidth, texHeight, &drawrc, width , height, + PixelShaderCache::GetColorCopyProgram(0), VertexShaderCache::GetSimpleVertexShader(0)); +} - 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 XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) +{ + TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, texture); } -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) @@ -308,190 +196,47 @@ void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, fbWidth, fbHeight); } -void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void XFBSource::CopyEFB() { - LPDIRECT3DTEXTURE9 xfbTexture; - HRESULT hr = 0; - - 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; - } - - float scaleX = Renderer::GetXFBScaleX(); - float scaleY = Renderer::GetXFBScaleY(); - TargetRectangle targetSource,efbSource; - efbSource = Renderer::ConvertEFBRectangle(sourceRc); - targetSource.top = (int)(sourceRc.top *scaleY); - targetSource.bottom = (int)(sourceRc.bottom *scaleY); - targetSource.left = (int)(sourceRc.left *scaleX); - targetSource.right = (int)(sourceRc.right * scaleX); - int target_width = targetSource.right - targetSource.left; - int target_height = targetSource.bottom - targetSource.top; - 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; - - if(it->xfbSource.texWidth != target_width || it->xfbSource.texHeight != target_height || !(it->xfbSource.texture)) - { - if(it->xfbSource.texture) - it->xfbSource.texture->Release(); - it->xfbSource.texture = NULL; - hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format, - D3DPOOL_DEFAULT, &(it->xfbSource.texture), NULL); - - } - - xfbTexture = it->xfbSource.texture; - - it->xfbSource.texWidth = target_width; - it->xfbSource.texHeight = target_height; - - // 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. - - D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format, - D3DPOOL_DEFAULT, &xfbTexture, NULL); - VirtualXFB newVirt; - - newVirt.xfbAddr = xfbAddr; - newVirt.xfbWidth = fbWidth; - newVirt.xfbHeight = fbHeight; - - newVirt.xfbSource.texture = xfbTexture; - newVirt.xfbSource.texWidth = target_width; - newVirt.xfbSource.texHeight = target_height; - - // Add the new Virtual XFB to the list - - if ((int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) - { - // List overflowed; delete the oldest. - m_virtualXFBList.back().xfbSource.texture->Release(); - m_virtualXFBList.pop_back(); - } - - m_virtualXFBList.push_front(newVirt); - } - // Copy EFB data to XFB and restore render target again - if(!xfbTexture) - return; - LPDIRECT3DTEXTURE9 read_texture = GetEFBColorTexture(); - - Renderer::ResetAPIState(); // Reset any game specific settings LPDIRECT3DSURFACE9 Rendersurf = NULL; - - xfbTexture->GetSurfaceLevel(0, &Rendersurf); + texture->GetSurfaceLevel(0, &Rendersurf); D3D::dev->SetDepthStencilSurface(NULL); D3D::dev->SetRenderTarget(0, Rendersurf); - - D3DVIEWPORT9 vp; + D3DVIEWPORT9 vp; vp.X = 0; vp.Y = 0; - vp.Width = target_width; - vp.Height = target_height; + vp.Width = texWidth; + vp.Height = texHeight; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; D3D::dev->SetViewport(&vp); + RECT sourcerect; - sourcerect.bottom = efbSource.bottom; - sourcerect.left = efbSource.left; - sourcerect.right = efbSource.right; - sourcerect.top = efbSource.top; + sourcerect.bottom = sourceRc.bottom; + sourcerect.left = sourceRc.left; + sourcerect.right = sourceRc.right; + sourcerect.top = sourceRc.top; D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); D3D::drawShadedTexQuad( - read_texture, + FramebufferManager::GetEFBColorTexture(), &sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), - target_width, - target_height, + texWidth, + texHeight, PixelShaderCache::GetColorCopyProgram( g_ActiveConfig.iMultisampleMode), VertexShaderCache::GetSimpleVertexShader( g_ActiveConfig.iMultisampleMode)); - - + D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); D3D::SetTexture(0, NULL); - D3D::dev->SetRenderTarget(0, GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(GetEFBDepthRTSurface()); - Renderer::RestoreAPIState(); - Rendersurf->Release(); -} - -const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) -{ - xfbCount = 1; - - m_realXFBSource.texWidth = fbWidth; - m_realXFBSource.texHeight = fbHeight; - - m_realXFBSource.srcAddr = xfbAddr; - m_realXFBSource.srcWidth = fbWidth; - m_realXFBSource.srcHeight = fbHeight; - - if (!m_realXFBSource.texture) - { - D3D::dev->CreateTexture(fbWidth, fbHeight, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format, - D3DPOOL_DEFAULT, &m_realXFBSource.texture, NULL); - } - - // 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; + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - 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]; + Rendersurf->Release(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h index 23be22b507..b6bd0a44ee 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h @@ -18,8 +18,8 @@ #ifndef _FRAMEBUFFERMANAGER_D3D_H_ #define _FRAMEBUFFERMANAGER_D3D_H_ -#include <list> #include "D3DBase.h" +#include "FramebufferManagerBase.h" // On the GameCube, the game sends a request for the graphics processor to // transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM @@ -50,124 +50,65 @@ // Disadvantages: If the GameCube CPU writes directly to the XFB (which is // possible but uncommon), the Virtual XFB will not capture this information. -// There may be multiple XFBs in GameCube RAM. This is the maximum number to -// virtualize. -const int MAX_VIRTUAL_XFB = 8; - -inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) +struct XFBSource : public XFBSourceBase { - return !((aLower >= bUpper) || (bLower >= aUpper)); -} + XFBSource(LPDIRECT3DTEXTURE9 tex) : texture(tex) {} + ~XFBSource() { texture->Release(); } -struct XFBSource -{ - XFBSource() - { - this->srcAddr = 0; - this->srcWidth = 0; - this->srcHeight = 0; - this->texture = 0; - this->texWidth = 0; - this->texHeight = 0; - } - - u32 srcAddr; - u32 srcWidth; - u32 srcHeight; - - LPDIRECT3DTEXTURE9 texture; - int texWidth; - int texHeight; + void Draw(const MathUtil::Rectangle<float> &sourcerc, + const MathUtil::Rectangle<float> &drawrc, int width, int height) const; + void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight); + void CopyEFB(); + + LPDIRECT3DTEXTURE9 const texture; }; -class FramebufferManager +class FramebufferManager : public FramebufferManagerBase { -private: - - struct VirtualXFB - { - // Address and size in GameCube RAM - u32 xfbAddr; - u32 xfbWidth; - u32 xfbHeight; - - XFBSource xfbSource; - }; - - typedef std::list<VirtualXFB> VirtualXFBListType; +public: + FramebufferManager(); + ~FramebufferManager(); - VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height); + static LPDIRECT3DTEXTURE9 GetEFBColorTexture() { return s_efb.color_texture; } + static LPDIRECT3DTEXTURE9 GetEFBDepthTexture() { return s_efb.depth_texture; } - void replaceVirtualXFB(); + static LPDIRECT3DSURFACE9 GetEFBColorRTSurface() { return s_efb.color_surface; } + static LPDIRECT3DSURFACE9 GetEFBDepthRTSurface() { return s_efb.depth_surface; } - void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); - const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); + static LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface() { return s_efb.color_OffScreenReadBuffer; } + static LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface() { return s_efb.depth_OffScreenReadBuffer; } - XFBSource m_realXFBSource; // Only used in Real XFB mode - VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode + static D3DFORMAT GetEFBDepthRTSurfaceFormat() { return s_efb.depth_surface_Format; } + static D3DFORMAT GetEFBColorRTSurfaceFormat() { return s_efb.color_surface_Format; } + static D3DFORMAT GetEFBDepthReadSurfaceFormat() { return s_efb.depth_ReadBuffer_Format; } - const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB]; + static LPDIRECT3DSURFACE9 GetEFBColorReadSurface() { return s_efb.color_ReadBuffer; } + static LPDIRECT3DSURFACE9 GetEFBDepthReadSurface() { return s_efb.depth_ReadBuffer; } - LPDIRECT3DTEXTURE9 s_efb_color_texture;//Texture thats contains the color data of the render target - LPDIRECT3DTEXTURE9 s_efb_colorRead_texture;//1 pixel texture for temporal data store - LPDIRECT3DTEXTURE9 s_efb_depth_texture;//Texture thats contains the depth data of the render target - LPDIRECT3DTEXTURE9 s_efb_depthRead_texture;//4 pixel texture for temporal data store +private: + XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height); + void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc); - LPDIRECT3DSURFACE9 s_efb_depth_surface;//Depth Surface - LPDIRECT3DSURFACE9 s_efb_color_surface;//Color Surface - LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;//Surface 0 of s_efb_colorRead_texture - LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;//Surface 0 of s_efb_depthRead_texture - LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data - LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data + void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - D3DFORMAT s_efb_color_surface_Format;//Format of the color Surface - D3DFORMAT s_efb_depth_surface_Format;//Format of the Depth Surface - D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface -public: - FramebufferManager() + static struct Efb { - s_efb_color_texture = NULL; - s_efb_colorRead_texture = NULL; - s_efb_depth_texture = NULL; - s_efb_depthRead_texture = NULL; - - s_efb_depth_surface = NULL; - s_efb_color_surface = NULL; - s_efb_color_ReadBuffer = NULL; - s_efb_depth_ReadBuffer = NULL; - s_efb_color_OffScreenReadBuffer = NULL; - s_efb_depth_OffScreenReadBuffer = NULL; - - s_efb_color_surface_Format = D3DFMT_FORCE_DWORD; - s_efb_depth_surface_Format = D3DFMT_FORCE_DWORD; - s_efb_depth_ReadBuffer_Format = D3DFMT_FORCE_DWORD; - m_realXFBSource.texture = NULL; - } - - void Create(); - void Destroy(); - - void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); - - LPDIRECT3DTEXTURE9 GetEFBColorTexture(); - LPDIRECT3DTEXTURE9 GetEFBDepthTexture(); - - LPDIRECT3DSURFACE9 GetEFBColorRTSurface(); - LPDIRECT3DSURFACE9 GetEFBDepthRTSurface(); - LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface(); - LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface(); - D3DFORMAT GetEFBDepthRTSurfaceFormat(); - D3DFORMAT GetEFBColorRTSurfaceFormat(); - D3DFORMAT GetEFBDepthReadSurfaceFormat(); - LPDIRECT3DSURFACE9 GetEFBColorReadSurface(); - LPDIRECT3DSURFACE9 GetEFBDepthReadSurface(); - - + LPDIRECT3DTEXTURE9 color_texture;//Texture thats contains the color data of the render target + LPDIRECT3DTEXTURE9 colorRead_texture;//1 pixel texture for temporal data store + LPDIRECT3DTEXTURE9 depth_texture;//Texture thats contains the depth data of the render target + LPDIRECT3DTEXTURE9 depthRead_texture;//4 pixel texture for temporal data store + + LPDIRECT3DSURFACE9 depth_surface;//Depth Surface + LPDIRECT3DSURFACE9 color_surface;//Color Surface + LPDIRECT3DSURFACE9 color_ReadBuffer;//Surface 0 of colorRead_texture + LPDIRECT3DSURFACE9 depth_ReadBuffer;//Surface 0 of depthRead_texture + LPDIRECT3DSURFACE9 color_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data + LPDIRECT3DSURFACE9 depth_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data + + D3DFORMAT color_surface_Format;//Format of the color Surface + D3DFORMAT depth_surface_Format;//Format of the Depth Surface + D3DFORMAT depth_ReadBuffer_Format;//Format of the Depth color Read Surface + } s_efb; }; -extern FramebufferManager g_framebufferManager; - #endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index d4c02ccd07..bab80162e4 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -244,7 +244,7 @@ void SetupDeviceObjects() { D3D::font.Init(); VertexLoaderManager::Init(); - g_framebufferManager.Create(); + g_framebuffer_manager = new FramebufferManager; VertexShaderManager::Dirty(); PixelShaderManager::Dirty(); @@ -264,7 +264,7 @@ void TeardownDeviceObjects() ScreenShootMEMSurface = NULL; D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); - g_framebufferManager.Destroy(); + delete g_framebuffer_manager; D3D::font.Shutdown(); TextureCache::Invalidate(false); VertexLoaderManager::Shutdown(); @@ -373,8 +373,8 @@ bool Renderer::Init() D3D::dev->SetViewport(&vp); D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); vp.X = (s_Fulltarget_width - s_target_width) / 2; vp.Y = (s_Fulltarget_height - s_target_height) / 2; vp.Width = s_target_width; @@ -617,7 +617,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect // just use progressive. if (g_ActiveConfig.bUseXFB) { - g_framebufferManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); + FramebufferManager::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); } else { @@ -729,15 +729,15 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) LPDIRECT3DSURFACE9 pEFBSurf, pBufferRT, pSystemBuf; if(type == PEEK_Z || type == POKE_Z) { - pEFBSurf = g_framebufferManager.GetEFBDepthRTSurface(); - pBufferRT = g_framebufferManager.GetEFBDepthReadSurface(); - pSystemBuf = g_framebufferManager.GetEFBDepthOffScreenRTSurface(); + pEFBSurf = FramebufferManager::GetEFBDepthRTSurface(); + pBufferRT = FramebufferManager::GetEFBDepthReadSurface(); + pSystemBuf = FramebufferManager::GetEFBDepthOffScreenRTSurface(); } else //if(type == PEEK_COLOR || type == POKE_COLOR) { - pEFBSurf = g_framebufferManager.GetEFBColorRTSurface(); - pBufferRT = g_framebufferManager.GetEFBColorReadSurface(); - pSystemBuf = g_framebufferManager.GetEFBColorOffScreenRTSurface(); + pEFBSurf = FramebufferManager::GetEFBColorRTSurface(); + pBufferRT = FramebufferManager::GetEFBColorReadSurface(); + pSystemBuf = FramebufferManager::GetEFBColorOffScreenRTSurface(); } // Buffer not found alert @@ -763,7 +763,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) RectToLock.top = targetPixelRc.top; if (type == PEEK_Z) { - if (g_framebufferManager.GetEFBDepthRTSurfaceFormat() == D3DFMT_D24X8) + if (FramebufferManager::GetEFBDepthRTSurfaceFormat() == D3DFMT_D24X8) return 0; RECT PixelRect; @@ -798,7 +798,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) float fConstAdd[4] = {0.0f}; colmat[0] = colmat[5] = colmat[10] = 1.0f; PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation - LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBDepthTexture(); + LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBDepthTexture(); D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); @@ -808,13 +808,13 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), 4, 4, - (g_framebufferManager.GetEFBDepthRTSurfaceFormat() == FOURCC_RAWZ) ? PixelShaderCache::GetColorMatrixProgram(0) : PixelShaderCache::GetDepthMatrixProgram(0), + (FramebufferManager::GetEFBDepthRTSurfaceFormat() == FOURCC_RAWZ) ? PixelShaderCache::GetColorMatrixProgram(0) : PixelShaderCache::GetDepthMatrixProgram(0), VertexShaderCache::GetSimpleVertexShader(0)); D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); RestoreAPIState(); // Retrieve the pixel data to the local memory buffer @@ -831,7 +831,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) float val = 0.0f; u32 z = 0; - switch (g_framebufferManager.GetEFBDepthReadSurfaceFormat()) + switch (FramebufferManager::GetEFBDepthReadSurfaceFormat()) { case D3DFMT_R32F: val = ((float*)drect.pBits)[6]; @@ -973,10 +973,12 @@ void UpdateViewport() { D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); - g_framebufferManager.Destroy(); - g_framebufferManager.Create(); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + + delete g_framebuffer_manager; + g_framebuffer_manager = new FramebufferManager; + + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); } } vp.X = X; @@ -1052,7 +1054,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; u32 xfbCount = 0; - const XFBSource** xfbSourceList = g_framebufferManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + const XFBSourceBase *const *xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { g_VideoInitialize.pCopiedToXFB(false); @@ -1133,7 +1135,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - const XFBSource* xfbSource = NULL; + const XFBSourceBase* xfbSource = NULL; if(g_ActiveConfig.bUseXFB) { @@ -1181,13 +1183,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons drawRc.right = 1; } - D3D::drawShadedTexSubQuad(xfbSource->texture,&sourceRc,xfbSource->texWidth,xfbSource->texHeight,&drawRc,Width,Height,PixelShaderCache::GetColorCopyProgram(0),VertexShaderCache::GetSimpleVertexShader(0)); + xfbSource->Draw(sourceRc, drawRc, Width, Height); } } else { TargetRectangle targetRc = ConvertEFBRectangle(rc); - LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBColorTexture(); + LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBColorTexture(); D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(),Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),Width,Height,PixelShaderCache::GetColorCopyProgram(g_Config.iMultisampleMode),VertexShaderCache::GetSimpleVertexShader(g_Config.iMultisampleMode)); } D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); @@ -1375,11 +1377,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } else { - g_framebufferManager.Destroy(); - g_framebufferManager.Create(); + delete g_framebuffer_manager; + g_framebuffer_manager = new FramebufferManager; } - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); } // Place messages on the picture, then copy it to the screen @@ -1407,8 +1409,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3D::BeginFrame(); RestoreAPIState(); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); UpdateViewport(); VertexShaderManager::SetViewportChanged(); // For testing zbuffer targets. diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 5a289e1895..7fecb82704 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -74,8 +74,8 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB bool bIsIntensityFmt, u32 copyfmt) { const LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ? - g_framebufferManager.GetEFBDepthTexture() : - g_framebufferManager.GetEFBColorTexture(); + FramebufferManager::GetEFBDepthTexture() : + FramebufferManager::GetEFBColorTexture(); if (!isDynamic || g_ActiveConfig.bCopyEFBToTexture) { @@ -128,7 +128,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); } - D3DFORMAT bformat = g_framebufferManager.GetEFBDepthRTSurfaceFormat(); + D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat(); int SSAAMode = g_ActiveConfig.iMultisampleMode; D3D::drawShadedTexQuad(read_texture, &sourcerect, @@ -163,8 +163,8 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); D3D::SetTexture(0, NULL); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); } TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, unsigned int height, diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp index 3ae3ab9cb7..d47ea677b3 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp @@ -325,7 +325,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf u8 *dest_ptr = Memory_GetPtr(address); - LPDIRECT3DTEXTURE9 source_texture = bFromZBuffer ? g_framebufferManager.GetEFBDepthTexture() : g_framebufferManager.GetEFBColorTexture(); + LPDIRECT3DTEXTURE9 source_texture = bFromZBuffer ? FramebufferManager::GetEFBDepthTexture() : FramebufferManager::GetEFBColorTexture(); int width = (source.right - source.left) >> bScaleByHalf; int height = (source.bottom - source.top) >> bScaleByHalf; @@ -374,8 +374,8 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); Renderer::ResetAPIState(); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); Renderer::RestoreAPIState(); } @@ -461,8 +461,8 @@ void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourc (float)Renderer::GetFullTargetHeight()); Renderer::ResetAPIState(); EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); Renderer::RestoreAPIState(); } @@ -534,8 +534,8 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); D3D::SetTexture(0,NULL); - D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); Renderer::RestoreAPIState(); Rendersurf->Release(); s_srcTexture->Release(); diff --git a/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt b/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt index 102be90e66..a87becf5f2 100644 --- a/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt +++ b/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt @@ -10,8 +10,7 @@ set(SRCS Src/BPFunctions.cpp Src/TextureCache.cpp Src/TextureConverter.cpp Src/VertexShaderCache.cpp - Src/VertexManager.cpp - Src/XFB.cpp) + Src/VertexManager.cpp) set(LIBS videocommon GLEW diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj index 3a31a30a27..ee336ced66 100644 --- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj +++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj @@ -781,14 +781,6 @@ RelativePath=".\Src\VertexShaderCache.h" > </File> - <File - RelativePath=".\Src\XFB.cpp" - > - </File> - <File - RelativePath=".\Src\XFB.h" - > - </File> </Filter> <Filter Name="GUI" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp index 690e2ecdfd..1d27a1b600 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp @@ -24,7 +24,6 @@ #include "TextureCache.h" #include "TextureConverter.h" #include "VertexShaderManager.h" -#include "XFB.h" #include "main.h" namespace BPFunctions 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); -} - - diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h index cb114b5af7..bff6c771c0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h @@ -18,8 +18,8 @@ #ifndef _FRAMEBUFFERMANAGER_H_ #define _FRAMEBUFFERMANAGER_H_ -#include <list> #include "GLUtil.h" +#include "FramebufferManagerBase.h" // On the GameCube, the game sends a request for the graphics processor to // transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM @@ -52,116 +52,70 @@ // There may be multiple XFBs in GameCube RAM. This is the maximum number to // virtualize. -const int MAX_VIRTUAL_XFB = 8; -inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) +struct XFBSource : public XFBSourceBase { - return !((aLower >= bUpper) || (bLower >= aUpper)); -} + XFBSource(GLuint tex) : texture(tex) {} + ~XFBSource() { glDeleteTextures(1, &texture); } -struct XFBSource -{ - XFBSource() : - texture(0) - {} - - u32 srcAddr; - u32 srcWidth; - u32 srcHeight; + void CopyEFB(); + void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight); + void Draw(const MathUtil::Rectangle<float> &sourcerc, + const MathUtil::Rectangle<float> &drawrc, int width, int height) const; - GLuint texture; - int texWidth; - int texHeight; - - TargetRectangle sourceRc; + const GLuint texture; }; -class FramebufferManager +class FramebufferManager : public FramebufferManagerBase { public: - FramebufferManager() : - m_efbFramebuffer(0), - m_efbColor(0), - m_efbDepth(0), - m_resolvedFramebuffer(0), - m_resolvedColorTexture(0), - m_resolvedDepthTexture(0), - m_xfbFramebuffer(0) - {} - - void Init(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples); - void Shutdown(); - - void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - - const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); + FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples); + ~FramebufferManager(); // To get the EFB in texture form, these functions may have to transfer // the EFB to a resolved texture first. - GLuint GetEFBColorTexture(const EFBRectangle& sourceRc) const; - GLuint GetEFBDepthTexture(const EFBRectangle& sourceRc) const; + static GLuint GetEFBColorTexture(const EFBRectangle& sourceRc); + static GLuint GetEFBDepthTexture(const EFBRectangle& sourceRc); - GLuint GetEFBFramebuffer() const { return m_efbFramebuffer; } + static GLuint GetEFBFramebuffer() { return m_efbFramebuffer; } + static GLuint GetXFBFramebuffer() { return m_xfbFramebuffer; } // Resolved framebuffer is only used in MSAA mode. - GLuint GetResolvedFramebuffer() const { return m_resolvedFramebuffer; } + static GLuint GetResolvedFramebuffer() { return m_resolvedFramebuffer; } - void SetFramebuffer(GLuint fb); + static void SetFramebuffer(GLuint fb); // If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID. // Thus, this call may be expensive. Don't repeat it unnecessarily. // If not in MSAA mode, will just return the render target texture ID. // After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to. - GLuint ResolveAndGetRenderTarget(const EFBRectangle &rect); + static GLuint ResolveAndGetRenderTarget(const EFBRectangle &rect); // Same as above but for the depth Target. // After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to. - GLuint ResolveAndGetDepthTarget(const EFBRectangle &rect); + static GLuint ResolveAndGetDepthTarget(const EFBRectangle &rect); private: + XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height); + void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc); - struct VirtualXFB - { - // Address and size in GameCube RAM - u32 xfbAddr; - u32 xfbWidth; - u32 xfbHeight; - - XFBSource xfbSource; - }; + void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - typedef std::list<VirtualXFB> VirtualXFBListType; + static int m_targetWidth; + static int m_targetHeight; + static int m_msaaSamples; + static int m_msaaCoverageSamples; - VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height); - - void replaceVirtualXFB(); - - void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); - const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); - - int m_targetWidth; - int m_targetHeight; - int m_msaaSamples; - int m_msaaCoverageSamples; - - GLuint m_efbFramebuffer; - GLuint m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise - GLuint m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise + static GLuint m_efbFramebuffer; + static GLuint m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise + static GLuint m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise // Only used in MSAA mode. - GLuint m_resolvedFramebuffer; - GLuint m_resolvedColorTexture; - GLuint m_resolvedDepthTexture; - - GLuint m_xfbFramebuffer; // Only used in MSAA mode - XFBSource m_realXFBSource; // Only used in Real XFB mode - VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode + static GLuint m_resolvedFramebuffer; + static GLuint m_resolvedColorTexture; + static GLuint m_resolvedDepthTexture; - const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB]; + static GLuint m_xfbFramebuffer; // Only used in MSAA mode }; -extern FramebufferManager g_framebufferManager; - #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index e4015bb837..ba1fcd7298 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -52,7 +52,6 @@ #include "VertexLoader.h" #include "PostProcessing.h" #include "TextureConverter.h" -#include "XFB.h" #include "OnScreenDisplay.h" #include "Timer.h" #include "StringUtil.h" @@ -397,7 +396,7 @@ bool Renderer::Init() bSuccess = false; // Initialize the FramebufferManager - g_framebufferManager.Init(s_target_width, s_target_height, + g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, s_MSAASamples, s_MSAACoverageSamples); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); @@ -529,7 +528,7 @@ void Renderer::Shutdown() delete scrshotThread; #endif - g_framebufferManager.Shutdown(); + delete g_framebuffer_manager; #if defined _WIN32 || defined HAVE_AVCODEC if(s_bAVIDumping) @@ -781,7 +780,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect // just use progressive. if (g_ActiveConfig.bUseXFB) { - g_framebufferManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); + FramebufferManager::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); } else { @@ -893,8 +892,8 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) if (s_MSAASamples > 1) { // Resolve our rectangle. - g_framebufferManager.GetEFBDepthTexture(efbPixelRc); - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, g_framebufferManager.GetResolvedFramebuffer()); + FramebufferManager::GetEFBDepthTexture(efbPixelRc); + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer()); } // Sample from the center of the target region. @@ -926,8 +925,8 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) if (s_MSAASamples > 1) { // Resolve our rectangle. - g_framebufferManager.GetEFBColorTexture(efbPixelRc); - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, g_framebufferManager.GetResolvedFramebuffer()); + FramebufferManager::GetEFBColorTexture(efbPixelRc); + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer()); } // Sample from the center of the target region. @@ -1125,7 +1124,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; u32 xfbCount = 0; - const XFBSource** xfbSourceList = g_framebufferManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { g_VideoInitialize.pCopiedToXFB(false); @@ -1164,7 +1163,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // care of disabling it in that case. It returns false in case of no post processing. bool applyShader = PostProcessing::ApplyShader(); - const XFBSource* xfbSource = NULL; + const XFBSourceBase* xfbSource = NULL; if(g_ActiveConfig.bUseXFB) { @@ -1176,10 +1175,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { xfbSource = xfbSourceList[i]; - TargetRectangle sourceRc; - - sourceRc = xfbSource->sourceRc; - MathUtil::Rectangle<float> drawRc; if (!g_ActiveConfig.bUseRealXFB) @@ -1214,57 +1209,25 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Tell the OSD Menu about the current internal resolution OSDInternalW = xfbSource->sourceRc.GetWidth(); OSDInternalH = xfbSource->sourceRc.GetHeight(); - // Texture map xfbSource->texture onto the main buffer - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, xfbSource->texture); + MathUtil::Rectangle<float> sourceRc; + sourceRc.left = xfbSource->sourceRc.left; + sourceRc.right = xfbSource->sourceRc.right; + sourceRc.top = xfbSource->sourceRc.top; + sourceRc.bottom = xfbSource->sourceRc.bottom; + + xfbSource->Draw(sourceRc, drawRc, 0, 0); // We must call ApplyShader here even if no post proc is selected. // It takes care of disabling it in that case. It returns false in // case of no post processing. if (applyShader) - { - glBegin(GL_QUADS); - glTexCoord2f(sourceRc.left, sourceRc.bottom); - glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0); - glVertex2f(drawRc.left, drawRc.bottom); - - glTexCoord2f(sourceRc.left, sourceRc.top); - glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1); - glVertex2f(drawRc.left, drawRc.top); - - glTexCoord2f(sourceRc.right, sourceRc.top); - glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1); - glVertex2f(drawRc.right, drawRc.top); - - glTexCoord2f(sourceRc.right, sourceRc.bottom); - glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0); - glVertex2f(drawRc.right, drawRc.bottom); - glEnd(); PixelShaderCache::DisableShader(); - } - else - { - glBegin(GL_QUADS); - glTexCoord2f(sourceRc.left, sourceRc.bottom); - glVertex2f(drawRc.left, drawRc.bottom); - - glTexCoord2f(sourceRc.left, sourceRc.top); - glVertex2f(drawRc.left, drawRc.top); - - glTexCoord2f(sourceRc.right, sourceRc.top); - glVertex2f(drawRc.right, drawRc.top); - - glTexCoord2f(sourceRc.right, sourceRc.bottom); - glVertex2f(drawRc.right, drawRc.bottom); - glEnd(); - } - - GL_REPORT_ERRORD(); } } else { TargetRectangle targetRc = ConvertEFBRectangle(rc); - GLuint read_texture = g_framebufferManager.ResolveAndGetRenderTarget(rc); + GLuint read_texture = FramebufferManager::ResolveAndGetRenderTarget(rc); // Render to the real buffer now. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); @@ -1502,8 +1465,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons s_Fulltarget_width = s_target_width; s_Fulltarget_height = s_target_height; - g_framebufferManager.Shutdown(); - g_framebufferManager.Init(s_target_width, s_target_height, + delete g_framebuffer_manager; + g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, s_MSAASamples, s_MSAACoverageSamples); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); } @@ -1579,7 +1542,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons stats.ResetFrame(); // Render to the framebuffer. - g_framebufferManager.SetFramebuffer(0); + FramebufferManager::SetFramebuffer(0); GL_REPORT_ERRORD(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/SConscript b/Source/Plugins/Plugin_VideoOGL/Src/SConscript index e83b6a37c6..110aeeb9f2 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/SConscript +++ b/Source/Plugins/Plugin_VideoOGL/Src/SConscript @@ -16,7 +16,6 @@ files = [ 'VertexShaderCache.cpp', 'TextureConverter.cpp', 'VertexManager.cpp', - 'XFB.cpp', 'PostProcessing.cpp', 'FramebufferManager.cpp', 'main.cpp', diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index 39cfe41144..0b2f7419dc 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -273,8 +273,8 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB // Make sure to resolve anything we need to read from. const GLuint read_texture = bFromZBuffer ? - g_framebufferManager.ResolveAndGetDepthTarget(source_rect) : - g_framebufferManager.ResolveAndGetRenderTarget(source_rect); + FramebufferManager::ResolveAndGetDepthTarget(source_rect) : + FramebufferManager::ResolveAndGetRenderTarget(source_rect); // TODO: move const float xScale = Renderer::GetTargetScaleX(); @@ -287,7 +287,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB if (s_TempFramebuffer == 0) glGenFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer); - g_framebufferManager.SetFramebuffer(s_TempFramebuffer); + FramebufferManager::SetFramebuffer(s_TempFramebuffer); // Bind texture to temporary framebuffer glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0); GL_REPORT_FBO_ERROR(); @@ -334,7 +334,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB source_rect); } - g_framebufferManager.SetFramebuffer(0); + FramebufferManager::SetFramebuffer(0); VertexShaderManager::SetViewportChanged(); DisableStage(0); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index dd4d321665..5c614ed5e3 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -174,7 +174,7 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar // switch to texture converter frame buffer // attach render buffer as color destination - g_framebufferManager.SetFramebuffer(s_texConvFrameBuffer); + FramebufferManager::SetFramebuffer(s_texConvFrameBuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_dstRenderBuffer); @@ -264,7 +264,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf u8 *dest_ptr = Memory_GetPtr(address); - GLuint source_texture = bFromZBuffer ? g_framebufferManager.ResolveAndGetDepthTarget(source) : g_framebufferManager.ResolveAndGetRenderTarget(source); + GLuint source_texture = bFromZBuffer ? FramebufferManager::ResolveAndGetDepthTarget(source) : FramebufferManager::ResolveAndGetRenderTarget(source); int width = (source.right - source.left) >> bScaleByHalf; int height = (source.bottom - source.top) >> bScaleByHalf; @@ -310,7 +310,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); Renderer::ResetAPIState(); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); - g_framebufferManager.SetFramebuffer(0); + FramebufferManager::SetFramebuffer(0); VertexShaderManager::SetViewportChanged(); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); TextureCache::DisableStage(0); @@ -388,7 +388,7 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* des { Renderer::ResetAPIState(); EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); - g_framebufferManager.SetFramebuffer(0); + FramebufferManager::SetFramebuffer(0); VertexShaderManager::SetViewportChanged(); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); TextureCache::DisableStage(0); @@ -413,7 +413,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur // switch to texture converter frame buffer // attach destTexture as color destination - g_framebufferManager.SetFramebuffer(s_texConvFrameBuffer); + FramebufferManager::SetFramebuffer(s_texConvFrameBuffer); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, destTexture); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, destTexture, 0); @@ -460,7 +460,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur VertexShaderManager::SetViewportChanged(); - g_framebufferManager.SetFramebuffer(0); + FramebufferManager::SetFramebuffer(0); Renderer::RestoreAPIState(); GL_REPORT_ERRORD(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp b/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp deleted file mode 100644 index 6ac6289eac..0000000000 --- a/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - - -// ---------------------------------------------------------------------------------------------------------- -// This file handles the External Frame Buffer (XFB). The XFB is a storage point when the picture is resized -// by the system to the correct display format for output to the TV. In most cases its function can be -// supplemented by the equivalent adjustments in glScissor and glViewport (or their DirectX equivalents). But -// for some homebrew games these functions are necessary because the homebrew game communicate directly with -// them. -// ---------------------------------------------------------------------------------------------------------- - -#include "Globals.h" -#include "XFB.h" -#include "Render.h" -#include "TextureConverter.h" -#include "FramebufferManager.h" - -void XFB_Write(u8 *xfb_in_ram, const EFBRectangle& sourceRc, u32 dstWd, u32 dstHt) -{ - TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc); - TextureConverter::EncodeToRamYUYV(g_framebufferManager.ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, dstWd, dstHt); -} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/XFB.h b/Source/Plugins/Plugin_VideoOGL/Src/XFB.h deleted file mode 100644 index afdf6264e1..0000000000 --- a/Source/Plugins/Plugin_VideoOGL/Src/XFB.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _XFB_H_ -#define _XFB_H_ - -#include "GLUtil.h" - -// write the EFB to the XFB -void XFB_Write(u8 *xfb_in_ram, const EFBRectangle& sourceRc, u32 dstWd, u32 dstHt); - -#endif // _XFB_H_ diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 002b88458f..199359ce36 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -82,7 +82,6 @@ GFXConfigDialogOGL *m_ConfigFrame = NULL; #include "PixelShaderManager.h" #include "VertexShaderCache.h" #include "VertexShaderManager.h" -#include "XFB.h" #include "XFBConvert.h" #include "CommandProcessor.h" #include "PixelEngine.h" |
