mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-30 01:29:42 -06:00
Remove old XFB logic
This commit is contained in:
@ -14,145 +14,7 @@
|
||||
|
||||
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;
|
||||
|
||||
unsigned int FramebufferManagerBase::m_EFBLayers = 1;
|
||||
|
||||
FramebufferManagerBase::FramebufferManagerBase()
|
||||
{
|
||||
// Can't hurt
|
||||
m_overlappingXFBArray.fill(nullptr);
|
||||
}
|
||||
FramebufferManagerBase::~FramebufferManagerBase() = default;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void FramebufferManagerBase::CopyToXFB(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;
|
||||
|
||||
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
|
||||
|
||||
// move this Virtual XFB to the front of the list.
|
||||
if (m_virtualXFBList.begin() != vxfb)
|
||||
m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, vxfb);
|
||||
|
||||
u32 target_width, target_height;
|
||||
std::tie(target_width, target_height) = g_framebuffer_manager->GetTargetSize();
|
||||
|
||||
// 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;
|
||||
|
||||
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->sourceRc = g_renderer->ConvertEFBRectangle(sourceRc);
|
||||
|
||||
// keep stale XFB data from being used
|
||||
ReplaceVirtualXFB();
|
||||
|
||||
// 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)
|
||||
{
|
||||
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 dstLower >= srcLower && dstUpper <= srcUpper;
|
||||
});
|
||||
}
|
||||
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,76 +17,16 @@ inline bool AddressRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||
}
|
||||
|
||||
struct XFBSourceBase
|
||||
{
|
||||
virtual ~XFBSourceBase() {}
|
||||
|
||||
virtual void CopyEFB(float Gamma) = 0;
|
||||
|
||||
u32 srcAddr;
|
||||
u32 srcWidth;
|
||||
u32 srcHeight;
|
||||
|
||||
unsigned int texWidth;
|
||||
unsigned 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 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,
|
||||
float Gamma);
|
||||
|
||||
static unsigned int GetEFBLayers() { return m_EFBLayers; }
|
||||
virtual std::pair<u32, u32> GetTargetSize() const = 0;
|
||||
|
||||
protected:
|
||||
struct VirtualXFB
|
||||
{
|
||||
VirtualXFB() {}
|
||||
// Address and size in GameCube RAM
|
||||
u32 xfbAddr = 0;
|
||||
u32 xfbWidth = 0;
|
||||
u32 xfbHeight = 0;
|
||||
|
||||
std::unique_ptr<XFBSourceBase> xfbSource;
|
||||
};
|
||||
|
||||
typedef std::list<VirtualXFB> VirtualXFBListType;
|
||||
|
||||
static unsigned int m_EFBLayers;
|
||||
|
||||
private:
|
||||
virtual std::unique_ptr<XFBSourceBase>
|
||||
CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) = 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 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,
|
||||
float Gamma = 1.0f) = 0;
|
||||
static void CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,
|
||||
float Gamma = 1.0f);
|
||||
|
||||
static std::unique_ptr<XFBSourceBase> m_realXFBSource; // Only used in Real XFB mode
|
||||
static VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
|
||||
|
||||
static std::array<const XFBSourceBase*, MAX_VIRTUAL_XFB> m_overlappingXFBArray;
|
||||
};
|
||||
|
||||
extern std::unique_ptr<FramebufferManagerBase> g_framebuffer_manager;
|
||||
|
@ -112,8 +112,6 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStri
|
||||
|
||||
if (!fbStride || !fbHeight)
|
||||
return;
|
||||
|
||||
m_xfb_written = true;
|
||||
}
|
||||
|
||||
unsigned int Renderer::GetEFBScale() const
|
||||
@ -412,34 +410,6 @@ std::tuple<float, float> Renderer::ScaleToDisplayAspectRatio(const int width,
|
||||
return std::make_tuple(scaled_width, scaled_height);
|
||||
}
|
||||
|
||||
TargetRectangle Renderer::CalculateFrameDumpDrawRectangle() const
|
||||
{
|
||||
// No point including any borders in the frame dump image, since they'd have to be cropped anyway.
|
||||
TargetRectangle rc;
|
||||
rc.left = 0;
|
||||
rc.top = 0;
|
||||
|
||||
// If full-resolution frame dumping is disabled, just use the window draw rectangle.
|
||||
if (!g_ActiveConfig.bInternalResolutionFrameDumps)
|
||||
{
|
||||
// But still remove the borders, since the caller expects this.
|
||||
rc.right = m_target_rectangle.GetWidth();
|
||||
rc.bottom = m_target_rectangle.GetHeight();
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Grab the dimensions of the EFB textures, we scale either of these depending on the ratio.
|
||||
u32 efb_width, efb_height;
|
||||
std::tie(efb_width, efb_height) = g_framebuffer_manager->GetTargetSize();
|
||||
|
||||
float draw_width, draw_height;
|
||||
std::tie(draw_width, draw_height) = ScaleToDisplayAspectRatio(efb_width, efb_height);
|
||||
|
||||
rc.right = static_cast<int>(std::ceil(draw_width));
|
||||
rc.bottom = static_cast<int>(std::ceil(draw_height));
|
||||
return rc;
|
||||
}
|
||||
|
||||
void Renderer::UpdateDrawRectangle()
|
||||
{
|
||||
// The rendering window size
|
||||
@ -693,7 +663,6 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const
|
||||
stats.ResetFrame();
|
||||
|
||||
Core::Callback_VideoCopiedToXFB(update_frame_count);
|
||||
m_xfb_written = false;
|
||||
}
|
||||
|
||||
bool Renderer::IsFrameDumping()
|
||||
|
@ -96,7 +96,6 @@ public:
|
||||
float CalculateDrawAspectRatio() const;
|
||||
|
||||
std::tuple<float, float> ScaleToDisplayAspectRatio(int width, int height) const;
|
||||
TargetRectangle CalculateFrameDumpDrawRectangle() const;
|
||||
void UpdateDrawRectangle();
|
||||
|
||||
// Use this to convert a single target rectangle to two stereo rectangles
|
||||
@ -167,7 +166,6 @@ protected:
|
||||
int m_backbuffer_width = 0;
|
||||
int m_backbuffer_height = 0;
|
||||
TargetRectangle m_target_rectangle = {};
|
||||
bool m_xfb_written = false;
|
||||
|
||||
FPSCounter m_fps_counter;
|
||||
|
||||
|
Reference in New Issue
Block a user