mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-14 14:21:39 +00:00
Reformat all the things. Have fun with merge conflicts.
This commit is contained in:
parent
2115e8a4a6
commit
3570c7f03a
1116 changed files with 187405 additions and 180344 deletions
|
@ -2,18 +2,21 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "VideoCommon/FramebufferManagerBase.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include "VideoCommon/FramebufferManagerBase.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
std::unique_ptr<FramebufferManagerBase> g_framebuffer_manager;
|
||||
|
||||
std::unique_ptr<XFBSourceBase> FramebufferManagerBase::m_realXFBSource; // Only used in Real XFB mode
|
||||
FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
|
||||
std::array<const XFBSourceBase*, FramebufferManagerBase::MAX_VIRTUAL_XFB> FramebufferManagerBase::m_overlappingXFBArray;
|
||||
std::unique_ptr<XFBSourceBase>
|
||||
FramebufferManagerBase::m_realXFBSource; // Only used in Real XFB mode
|
||||
FramebufferManagerBase::VirtualXFBListType
|
||||
FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
|
||||
std::array<const XFBSourceBase*, FramebufferManagerBase::MAX_VIRTUAL_XFB>
|
||||
FramebufferManagerBase::m_overlappingXFBArray;
|
||||
|
||||
unsigned int FramebufferManagerBase::s_last_xfb_width = 1;
|
||||
unsigned int FramebufferManagerBase::s_last_xfb_height = 1;
|
||||
|
@ -22,229 +25,240 @@ unsigned int FramebufferManagerBase::m_EFBLayers = 1;
|
|||
|
||||
FramebufferManagerBase::FramebufferManagerBase()
|
||||
{
|
||||
// Can't hurt
|
||||
m_overlappingXFBArray.fill(nullptr);
|
||||
// Can't hurt
|
||||
m_overlappingXFBArray.fill(nullptr);
|
||||
}
|
||||
|
||||
FramebufferManagerBase::~FramebufferManagerBase()
|
||||
{
|
||||
// Necessary, as these are static members
|
||||
// (they really shouldn't be and should be refactored at some point).
|
||||
m_virtualXFBList.clear();
|
||||
m_realXFBSource.reset();
|
||||
// Necessary, as these are static members
|
||||
// (they really shouldn't be and should be refactored at some point).
|
||||
m_virtualXFBList.clear();
|
||||
m_realXFBSource.reset();
|
||||
}
|
||||
|
||||
const XFBSourceBase* const* FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32* xfbCountP)
|
||||
const XFBSourceBase* const* FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth,
|
||||
u32 fbHeight, u32* xfbCountP)
|
||||
{
|
||||
if (!g_ActiveConfig.bUseXFB)
|
||||
return nullptr;
|
||||
if (!g_ActiveConfig.bUseXFB)
|
||||
return nullptr;
|
||||
|
||||
if (g_ActiveConfig.bUseRealXFB)
|
||||
return GetRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCountP);
|
||||
else
|
||||
return GetVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCountP);
|
||||
if (g_ActiveConfig.bUseRealXFB)
|
||||
return GetRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCountP);
|
||||
else
|
||||
return GetVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCountP);
|
||||
}
|
||||
|
||||
const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32* xfbCountP)
|
||||
const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr, u32 fbWidth,
|
||||
u32 fbHeight, u32* xfbCountP)
|
||||
{
|
||||
*xfbCountP = 1;
|
||||
*xfbCountP = 1;
|
||||
|
||||
// recreate if needed
|
||||
if (m_realXFBSource && (m_realXFBSource->texWidth != fbWidth || m_realXFBSource->texHeight != fbHeight))
|
||||
m_realXFBSource.reset();
|
||||
// recreate if needed
|
||||
if (m_realXFBSource &&
|
||||
(m_realXFBSource->texWidth != fbWidth || m_realXFBSource->texHeight != fbHeight))
|
||||
m_realXFBSource.reset();
|
||||
|
||||
if (!m_realXFBSource && g_framebuffer_manager)
|
||||
m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight, 1);
|
||||
if (!m_realXFBSource && g_framebuffer_manager)
|
||||
m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight, 1);
|
||||
|
||||
if (!m_realXFBSource)
|
||||
return nullptr;
|
||||
if (!m_realXFBSource)
|
||||
return nullptr;
|
||||
|
||||
m_realXFBSource->srcAddr = xfbAddr;
|
||||
m_realXFBSource->srcAddr = xfbAddr;
|
||||
|
||||
m_realXFBSource->srcWidth = MAX_XFB_WIDTH;
|
||||
m_realXFBSource->srcHeight = MAX_XFB_HEIGHT;
|
||||
m_realXFBSource->srcWidth = MAX_XFB_WIDTH;
|
||||
m_realXFBSource->srcHeight = MAX_XFB_HEIGHT;
|
||||
|
||||
m_realXFBSource->texWidth = fbWidth;
|
||||
m_realXFBSource->texHeight = fbHeight;
|
||||
m_realXFBSource->texWidth = fbWidth;
|
||||
m_realXFBSource->texHeight = fbHeight;
|
||||
|
||||
m_realXFBSource->sourceRc.left = 0;
|
||||
m_realXFBSource->sourceRc.top = 0;
|
||||
m_realXFBSource->sourceRc.right = fbWidth;
|
||||
m_realXFBSource->sourceRc.bottom = fbHeight;
|
||||
m_realXFBSource->sourceRc.left = 0;
|
||||
m_realXFBSource->sourceRc.top = 0;
|
||||
m_realXFBSource->sourceRc.right = fbWidth;
|
||||
m_realXFBSource->sourceRc.bottom = fbHeight;
|
||||
|
||||
// Decode YUYV data from GameCube RAM
|
||||
m_realXFBSource->DecodeToTexture(xfbAddr, fbWidth, fbHeight);
|
||||
// Decode YUYV data from GameCube RAM
|
||||
m_realXFBSource->DecodeToTexture(xfbAddr, fbWidth, fbHeight);
|
||||
|
||||
m_overlappingXFBArray[0] = m_realXFBSource.get();
|
||||
return &m_overlappingXFBArray[0];
|
||||
m_overlappingXFBArray[0] = m_realXFBSource.get();
|
||||
return &m_overlappingXFBArray[0];
|
||||
}
|
||||
|
||||
const XFBSourceBase* const* FramebufferManagerBase::GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32* xfbCountP)
|
||||
const XFBSourceBase* const*
|
||||
FramebufferManagerBase::GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32* xfbCountP)
|
||||
{
|
||||
u32 xfbCount = 0;
|
||||
u32 xfbCount = 0;
|
||||
|
||||
if (m_virtualXFBList.empty()) // no Virtual XFBs available
|
||||
return nullptr;
|
||||
if (m_virtualXFBList.empty()) // no Virtual XFBs available
|
||||
return nullptr;
|
||||
|
||||
u32 srcLower = xfbAddr;
|
||||
u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
||||
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;
|
||||
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;
|
||||
u32 dstLower = vxfb->xfbAddr;
|
||||
u32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
|
||||
|
||||
if (AddressRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
||||
{
|
||||
m_overlappingXFBArray[xfbCount] = vxfb->xfbSource.get();
|
||||
++xfbCount;
|
||||
}
|
||||
}
|
||||
if (AddressRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
||||
{
|
||||
m_overlappingXFBArray[xfbCount] = vxfb->xfbSource.get();
|
||||
++xfbCount;
|
||||
}
|
||||
}
|
||||
|
||||
*xfbCountP = xfbCount;
|
||||
return &m_overlappingXFBArray[0];
|
||||
*xfbCountP = xfbCount;
|
||||
return &m_overlappingXFBArray[0];
|
||||
}
|
||||
|
||||
void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma)
|
||||
void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight,
|
||||
const EFBRectangle& sourceRc, float Gamma)
|
||||
{
|
||||
if (g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
if (g_framebuffer_manager)
|
||||
g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyToVirtualXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma);
|
||||
}
|
||||
if (g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
if (g_framebuffer_manager)
|
||||
g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyToVirtualXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma);
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma)
|
||||
void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight,
|
||||
const EFBRectangle& sourceRc, float Gamma)
|
||||
{
|
||||
if (!g_framebuffer_manager)
|
||||
return;
|
||||
if (!g_framebuffer_manager)
|
||||
return;
|
||||
|
||||
VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, sourceRc.GetWidth(), fbHeight);
|
||||
VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, sourceRc.GetWidth(), 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
|
||||
m_virtualXFBList.emplace_front();
|
||||
vxfb = m_virtualXFBList.begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace the last virtual XFB
|
||||
--vxfb;
|
||||
}
|
||||
}
|
||||
//else // replace existing virtual XFB
|
||||
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
|
||||
m_virtualXFBList.emplace_front();
|
||||
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);
|
||||
// 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);
|
||||
unsigned int target_width, target_height;
|
||||
g_framebuffer_manager->GetTargetSize(&target_width, &target_height);
|
||||
|
||||
// recreate if needed
|
||||
if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height))
|
||||
vxfb->xfbSource.reset();
|
||||
// recreate if needed
|
||||
if (vxfb->xfbSource &&
|
||||
(vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height))
|
||||
vxfb->xfbSource.reset();
|
||||
|
||||
if (!vxfb->xfbSource)
|
||||
{
|
||||
vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height, m_EFBLayers);
|
||||
if (!vxfb->xfbSource)
|
||||
return;
|
||||
if (!vxfb->xfbSource)
|
||||
{
|
||||
vxfb->xfbSource =
|
||||
g_framebuffer_manager->CreateXFBSource(target_width, target_height, m_EFBLayers);
|
||||
if (!vxfb->xfbSource)
|
||||
return;
|
||||
|
||||
vxfb->xfbSource->texWidth = target_width;
|
||||
vxfb->xfbSource->texHeight = target_height;
|
||||
}
|
||||
vxfb->xfbSource->texWidth = target_width;
|
||||
vxfb->xfbSource->texHeight = target_height;
|
||||
}
|
||||
|
||||
vxfb->xfbSource->srcAddr = vxfb->xfbAddr = xfbAddr;
|
||||
vxfb->xfbSource->srcWidth = vxfb->xfbWidth = sourceRc.GetWidth();
|
||||
vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight;
|
||||
vxfb->xfbSource->srcAddr = vxfb->xfbAddr = xfbAddr;
|
||||
vxfb->xfbSource->srcWidth = vxfb->xfbWidth = sourceRc.GetWidth();
|
||||
vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight;
|
||||
|
||||
vxfb->xfbSource->sourceRc = g_renderer->ConvertEFBRectangle(sourceRc);
|
||||
vxfb->xfbSource->sourceRc = g_renderer->ConvertEFBRectangle(sourceRc);
|
||||
|
||||
// keep stale XFB data from being used
|
||||
ReplaceVirtualXFB();
|
||||
// keep stale XFB data from being used
|
||||
ReplaceVirtualXFB();
|
||||
|
||||
// Copy EFB data to XFB and restore render target again
|
||||
vxfb->xfbSource->CopyEFB(Gamma);
|
||||
// Copy EFB data to XFB and restore render target again
|
||||
vxfb->xfbSource->CopyEFB(Gamma);
|
||||
}
|
||||
|
||||
FramebufferManagerBase::VirtualXFBListType::iterator FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
||||
FramebufferManagerBase::VirtualXFBListType::iterator
|
||||
FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
||||
{
|
||||
const u32 srcLower = xfbAddr;
|
||||
const u32 srcUpper = xfbAddr + 2 * width * height;
|
||||
const u32 srcLower = xfbAddr;
|
||||
const u32 srcUpper = xfbAddr + 2 * width * height;
|
||||
|
||||
return std::find_if(m_virtualXFBList.begin(), m_virtualXFBList.end(), [srcLower, srcUpper](const VirtualXFB& xfb) {
|
||||
const u32 dstLower = xfb.xfbAddr;
|
||||
const u32 dstUpper = xfb.xfbAddr + 2 * xfb.xfbWidth * xfb.xfbHeight;
|
||||
return std::find_if(m_virtualXFBList.begin(), m_virtualXFBList.end(),
|
||||
[srcLower, srcUpper](const VirtualXFB& xfb) {
|
||||
const u32 dstLower = xfb.xfbAddr;
|
||||
const u32 dstUpper = xfb.xfbAddr + 2 * xfb.xfbWidth * xfb.xfbHeight;
|
||||
|
||||
return dstLower >= srcLower && dstUpper <= srcUpper;
|
||||
});
|
||||
return dstLower >= srcLower && dstUpper <= srcUpper;
|
||||
});
|
||||
}
|
||||
|
||||
void FramebufferManagerBase::ReplaceVirtualXFB()
|
||||
{
|
||||
VirtualXFBListType::iterator it = m_virtualXFBList.begin();
|
||||
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;
|
||||
const s32 srcLower = it->xfbAddr;
|
||||
const s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
|
||||
const s32 lineSize = 2 * it->xfbWidth;
|
||||
|
||||
++it;
|
||||
++it;
|
||||
|
||||
for (; it != m_virtualXFBList.end(); ++it)
|
||||
{
|
||||
s32 dstLower = it->xfbAddr;
|
||||
s32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
|
||||
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 (AddressRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
||||
{
|
||||
s32 upperOverlap = (srcUpper - dstLower) / lineSize;
|
||||
s32 lowerOverlap = (dstUpper - srcLower) / lineSize;
|
||||
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
||||
{
|
||||
// Invalidate the data
|
||||
it->xfbAddr = 0;
|
||||
it->xfbHeight = 0;
|
||||
it->xfbWidth = 0;
|
||||
}
|
||||
else if (AddressRangesOverlap(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (upperOverlap > 0 && lowerOverlap < 0)
|
||||
{
|
||||
it->xfbAddr += lineSize * upperOverlap;
|
||||
it->xfbHeight -= upperOverlap;
|
||||
}
|
||||
else if (lowerOverlap > 0)
|
||||
{
|
||||
it->xfbHeight -= lowerOverlap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x)
|
||||
{
|
||||
if (g_ActiveConfig.RealXFBEnabled())
|
||||
return x;
|
||||
if (g_ActiveConfig.RealXFBEnabled())
|
||||
return x;
|
||||
|
||||
return x * (int)Renderer::GetTargetRectangle().GetWidth() / (int)FramebufferManagerBase::LastXfbWidth();
|
||||
return x * (int)Renderer::GetTargetRectangle().GetWidth() /
|
||||
(int)FramebufferManagerBase::LastXfbWidth();
|
||||
}
|
||||
|
||||
int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y)
|
||||
{
|
||||
if (g_ActiveConfig.RealXFBEnabled())
|
||||
return y;
|
||||
if (g_ActiveConfig.RealXFBEnabled())
|
||||
return y;
|
||||
|
||||
return y * (int)Renderer::GetTargetRectangle().GetHeight() / (int)FramebufferManagerBase::LastXfbHeight();
|
||||
return y * (int)Renderer::GetTargetRectangle().GetHeight() /
|
||||
(int)FramebufferManagerBase::LastXfbHeight();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue