summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorNeoBrainX <NeoBrainX@gmail.com>2012-10-02 22:11:15 +0200
committerNeoBrainX <NeoBrainX@gmail.com>2012-11-19 13:10:32 +0100
commitb02bb7617fe5bdcda524d065b5601834e0a3ed4a (patch)
treefb996e164bd077a1453b89927ee61502e01ebac6 /Source/Core/VideoCommon
parentf88e7d3b73e99908e29b243c22210c4b8d47353b (diff)
Fix some fractional EFB scaling issues.
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp20
-rw-r--r--Source/Core/VideoCommon/Src/FramebufferManagerBase.h4
-rw-r--r--Source/Core/VideoCommon/Src/RenderBase.cpp100
-rw-r--r--Source/Core/VideoCommon/Src/RenderBase.h9
4 files changed, 98 insertions, 35 deletions
diff --git a/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp b/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp
index 090c1c7872..c883714daf 100644
--- a/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp
+++ b/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp
@@ -10,8 +10,8 @@ XFBSourceBase *FramebufferManagerBase::m_realXFBSource; // Only used in Real XFB
FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[MAX_VIRTUAL_XFB];
-unsigned int FramebufferManagerBase::s_last_xfb_width;
-unsigned int FramebufferManagerBase::s_last_xfb_height;
+unsigned int FramebufferManagerBase::s_last_xfb_width = 1;
+unsigned int FramebufferManagerBase::s_last_xfb_height = 1;
FramebufferManagerBase::FramebufferManagerBase()
{
@@ -230,30 +230,30 @@ void FramebufferManagerBase::ReplaceVirtualXFB()
}
}
-unsigned int FramebufferManagerBase::ScaleToVirtualXfbWidth(unsigned int width, unsigned int backbuffer_width)
+int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x, unsigned int backbuffer_width)
{
if (g_ActiveConfig.RealXFBEnabled())
- return width;
+ return x;
if (g_ActiveConfig.b3DVision)
{
// This works, yet the version in the else doesn't. No idea why.
- return width * backbuffer_width / FramebufferManagerBase::LastXfbWidth();
+ return x * (int)backbuffer_width / (int)FramebufferManagerBase::LastXfbWidth();
}
else
- return width * Renderer::GetTargetRectangle().GetWidth() / FramebufferManagerBase::LastXfbWidth();
+ return x * (int)Renderer::GetTargetRectangle().GetWidth() / (int)FramebufferManagerBase::LastXfbWidth();
}
-unsigned int FramebufferManagerBase::ScaleToVirtualXfbHeight(unsigned int height, unsigned int backbuffer_height)
+int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height)
{
if (g_ActiveConfig.RealXFBEnabled())
- return height;
+ return y;
if (g_ActiveConfig.b3DVision)
{
// This works, yet the version in the else doesn't. No idea why.
- return height * backbuffer_height / FramebufferManagerBase::LastXfbHeight();
+ return y * (int)backbuffer_height / (int)FramebufferManagerBase::LastXfbHeight();
}
else
- return height * Renderer::GetTargetRectangle().GetHeight() / FramebufferManagerBase::LastXfbHeight();
+ return y * (int)Renderer::GetTargetRectangle().GetHeight() / (int)FramebufferManagerBase::LastXfbHeight();
}
diff --git a/Source/Core/VideoCommon/Src/FramebufferManagerBase.h b/Source/Core/VideoCommon/Src/FramebufferManagerBase.h
index d915130ac4..e529bb1a39 100644
--- a/Source/Core/VideoCommon/Src/FramebufferManagerBase.h
+++ b/Source/Core/VideoCommon/Src/FramebufferManagerBase.h
@@ -55,8 +55,8 @@ public:
static unsigned int LastXfbWidth() { return s_last_xfb_width; }
static unsigned int LastXfbHeight() { return s_last_xfb_height; }
- static unsigned int ScaleToVirtualXfbWidth(unsigned int width, unsigned int backbuffer_width);
- static unsigned int ScaleToVirtualXfbHeight(unsigned int height, unsigned int backbuffer_height);
+ static int ScaleToVirtualXfbWidth(int x, unsigned int backbuffer_width);
+ static int ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height);
protected:
struct VirtualXFB
diff --git a/Source/Core/VideoCommon/Src/RenderBase.cpp b/Source/Core/VideoCommon/Src/RenderBase.cpp
index 8bb6ab6750..f83ce29e49 100644
--- a/Source/Core/VideoCommon/Src/RenderBase.cpp
+++ b/Source/Core/VideoCommon/Src/RenderBase.cpp
@@ -76,6 +76,11 @@ bool Renderer::XFBWrited;
bool Renderer::s_EnableDLCachingAfterRecording;
unsigned int Renderer::prev_efb_format = (unsigned int)-1;
+unsigned int Renderer::efb_scale_numeratorX = 1;
+unsigned int Renderer::efb_scale_numeratorY = 1;
+unsigned int Renderer::efb_scale_denominatorX = 1;
+unsigned int Renderer::efb_scale_denominatorY = 1;
+unsigned int Renderer::ssaa_multiplier = 1;
Renderer::Renderer() : frame_data(NULL), bLastFrameDumped(false)
@@ -93,6 +98,8 @@ Renderer::~Renderer()
// invalidate previous efb format
prev_efb_format = (unsigned int)-1;
+ efb_scale_numeratorX = efb_scale_numeratorY = efb_scale_denominatorX = efb_scale_denominatorY = ssaa_multiplier = 1;
+
#if defined _WIN32 || defined HAVE_LIBAV
if (g_ActiveConfig.bDumpFrames && bLastFrameDumped && bAVIDumping)
AVIDump::Stop();
@@ -129,41 +136,86 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
}
}
-void Renderer::CalculateTargetScale(int x, int y, int &scaledX, int &scaledY)
+int Renderer::EFBToScaledX(int x)
+{
+ switch (g_ActiveConfig.iEFBScale)
+ {
+ case 0: // fractional
+ return (int)ssaa_multiplier * FramebufferManagerBase::ScaleToVirtualXfbWidth(x, s_backbuffer_width);
+
+ default:
+ return x * (int)ssaa_multiplier * (int)efb_scale_numeratorX / (int)efb_scale_denominatorX;
+ };
+}
+
+int Renderer::EFBToScaledY(int y)
{
switch (g_ActiveConfig.iEFBScale)
{
+ case 0: // fractional
+ return (int)ssaa_multiplier * FramebufferManagerBase::ScaleToVirtualXfbHeight(y, s_backbuffer_height);
+
+ default:
+ return y * (int)ssaa_multiplier * (int)efb_scale_numeratorY / (int)efb_scale_denominatorY;
+ };
+}
+
+void Renderer::CalculateTargetScale(int x, int y, int &scaledX, int &scaledY)
+{
+ if (g_ActiveConfig.iEFBScale == 0 || g_ActiveConfig.iEFBScale == 1)
+ {
+ scaledX = x;
+ scaledY = y;
+ }
+ else
+ {
+ scaledX = x * (int)efb_scale_numeratorX / (int)efb_scale_denominatorX;
+ scaledY = y * (int)efb_scale_numeratorY / (int)efb_scale_denominatorY;
+ }
+}
+
+// return true if target size changed
+bool Renderer::CalculateTargetSize(unsigned int framebuffer_width, unsigned int framebuffer_height, int multiplier)
+{
+ int newEFBWidth, newEFBHeight;
+
+ // TODO: Ugly. Clean up
+ switch (s_LastEFBScale)
+ {
+ case 2: // 1x
+ efb_scale_numeratorX = efb_scale_numeratorY = 1;
+ efb_scale_denominatorX = efb_scale_denominatorY = 1;
+ break;
+
case 3: // 1.5x
- scaledX = (x / 2) * 3;
- scaledY = (y / 2) * 3;
+ efb_scale_numeratorX = efb_scale_numeratorY = 3;
+ efb_scale_denominatorX = efb_scale_denominatorY = 2;
break;
+
case 4: // 2x
- scaledX = x * 2;
- scaledY = y * 2;
+ efb_scale_numeratorX = efb_scale_numeratorY = 2;
+ efb_scale_denominatorX = efb_scale_denominatorY = 1;
break;
+
case 5: // 2.5x
- scaledX = (x / 2) * 5;
- scaledY = (y / 2) * 5;
+ efb_scale_numeratorX = efb_scale_numeratorY = 5;
+ efb_scale_denominatorX = efb_scale_denominatorY = 2;
break;
+
case 6: // 3x
- scaledX = x * 3;
- scaledY = y * 3;
+ efb_scale_numeratorX = efb_scale_numeratorY = 3;
+ efb_scale_denominatorX = efb_scale_denominatorY = 1;
break;
+
case 7: // 4x
- scaledX = x * 4;
- scaledY = y * 4;
+ efb_scale_numeratorX = efb_scale_numeratorY = 4;
+ efb_scale_denominatorX = efb_scale_denominatorY = 1;
break;
- default:
- scaledX = x;
- scaledY = y;
+
+ default: // fractional & integral handled later
break;
- };
-}
+ }
-// return true if target size changed
-bool Renderer::CalculateTargetSize(unsigned int framebuffer_width, unsigned int framebuffer_height, int multiplier)
-{
- int newEFBWidth, newEFBHeight;
switch (s_LastEFBScale)
{
case 0: // fractional
@@ -171,13 +223,18 @@ bool Renderer::CalculateTargetSize(unsigned int framebuffer_width, unsigned int
newEFBWidth = FramebufferManagerBase::ScaleToVirtualXfbWidth(EFB_WIDTH, framebuffer_width);
newEFBHeight = FramebufferManagerBase::ScaleToVirtualXfbHeight(EFB_HEIGHT, framebuffer_height);
- if (s_LastEFBScale)
+ if (s_LastEFBScale == 1)
{
newEFBWidth = ((newEFBWidth-1) / EFB_WIDTH + 1) * EFB_WIDTH;
newEFBHeight = ((newEFBHeight-1) / EFB_HEIGHT + 1) * EFB_HEIGHT;
}
+ efb_scale_numeratorX = newEFBWidth;
+ efb_scale_denominatorX = EFB_WIDTH;
+ efb_scale_numeratorY = newEFBHeight;
+ efb_scale_denominatorY = EFB_HEIGHT;
break;
+
default:
CalculateTargetScale(EFB_WIDTH, EFB_HEIGHT, newEFBWidth, newEFBHeight);
break;
@@ -185,6 +242,7 @@ bool Renderer::CalculateTargetSize(unsigned int framebuffer_width, unsigned int
newEFBWidth *= multiplier;
newEFBHeight *= multiplier;
+ ssaa_multiplier = multiplier;
if (newEFBWidth != s_target_width || newEFBHeight != s_target_height)
{
diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h
index 534aa732fe..4da80c9752 100644
--- a/Source/Core/VideoCommon/Src/RenderBase.h
+++ b/Source/Core/VideoCommon/Src/RenderBase.h
@@ -86,8 +86,8 @@ public:
// Use this to upscale native EFB coordinates to IDEAL internal resolution
- static unsigned int EFBToScaledX(int x) { return x * GetTargetWidth() / EFB_WIDTH; }
- static unsigned int EFBToScaledY(int y) { return y * GetTargetHeight() / EFB_HEIGHT; }
+ static int EFBToScaledX(int x);
+ static int EFBToScaledY(int y);
// Floating point versions of the above - only use them if really necessary
static float EFBToScaledXf(float x) { return x * ((float)GetTargetWidth() / (float)EFB_WIDTH); }
@@ -170,6 +170,11 @@ protected:
private:
static unsigned int prev_efb_format;
+ static unsigned int efb_scale_numeratorX;
+ static unsigned int efb_scale_numeratorY;
+ static unsigned int efb_scale_denominatorX;
+ static unsigned int efb_scale_denominatorY;
+ static unsigned int ssaa_multiplier;
};
extern Renderer *g_renderer;