Merge branch 'efb_scaling_fixes'.
This commit is contained in:
commit
4ff9e03509
|
@ -10,6 +10,9 @@ XFBSourceBase *FramebufferManagerBase::m_realXFBSource; // Only used in Real XFB
|
||||||
FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
|
FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
|
||||||
const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
||||||
|
|
||||||
|
unsigned int FramebufferManagerBase::s_last_xfb_width = 1;
|
||||||
|
unsigned int FramebufferManagerBase::s_last_xfb_height = 1;
|
||||||
|
|
||||||
FramebufferManagerBase::FramebufferManagerBase()
|
FramebufferManagerBase::FramebufferManagerBase()
|
||||||
{
|
{
|
||||||
m_realXFBSource = NULL;
|
m_realXFBSource = NULL;
|
||||||
|
@ -226,3 +229,31 @@ void FramebufferManagerBase::ReplaceVirtualXFB()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x, unsigned int backbuffer_width)
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.RealXFBEnabled())
|
||||||
|
return x;
|
||||||
|
|
||||||
|
if (g_ActiveConfig.b3DVision)
|
||||||
|
{
|
||||||
|
// This works, yet the version in the else doesn't. No idea why.
|
||||||
|
return x * (int)backbuffer_width / (int)FramebufferManagerBase::LastXfbWidth();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return x * (int)Renderer::GetTargetRectangle().GetWidth() / (int)FramebufferManagerBase::LastXfbWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height)
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.RealXFBEnabled())
|
||||||
|
return y;
|
||||||
|
|
||||||
|
if (g_ActiveConfig.b3DVision)
|
||||||
|
{
|
||||||
|
// This works, yet the version in the else doesn't. No idea why.
|
||||||
|
return y * (int)backbuffer_height / (int)FramebufferManagerBase::LastXfbHeight();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return y * (int)Renderer::GetTargetRectangle().GetHeight() / (int)FramebufferManagerBase::LastXfbHeight();
|
||||||
|
}
|
||||||
|
|
|
@ -50,6 +50,14 @@ public:
|
||||||
static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma);
|
static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma);
|
||||||
static const XFBSourceBase* const* GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
static const XFBSourceBase* const* GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
|
|
||||||
|
static void SetLastXfbWidth(unsigned int width) { s_last_xfb_width = width; }
|
||||||
|
static void SetLastXfbHeight(unsigned int height) { s_last_xfb_height = height; }
|
||||||
|
static unsigned int LastXfbWidth() { return s_last_xfb_width; }
|
||||||
|
static unsigned int LastXfbHeight() { return s_last_xfb_height; }
|
||||||
|
|
||||||
|
static int ScaleToVirtualXfbWidth(int x, unsigned int backbuffer_width);
|
||||||
|
static int ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct VirtualXFB
|
struct VirtualXFB
|
||||||
{
|
{
|
||||||
|
@ -85,6 +93,9 @@ private:
|
||||||
static VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
|
static VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
|
||||||
|
|
||||||
static const XFBSourceBase* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
static const XFBSourceBase* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
||||||
|
|
||||||
|
static unsigned int s_last_xfb_width;
|
||||||
|
static unsigned int s_last_xfb_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FramebufferManagerBase *g_framebuffer_manager;
|
extern FramebufferManagerBase *g_framebuffer_manager;
|
||||||
|
|
|
@ -67,12 +67,7 @@ int Renderer::s_target_height;
|
||||||
int Renderer::s_backbuffer_width;
|
int Renderer::s_backbuffer_width;
|
||||||
int Renderer::s_backbuffer_height;
|
int Renderer::s_backbuffer_height;
|
||||||
|
|
||||||
// ratio of backbuffer size and render area size
|
TargetRectangle Renderer::target_rc;
|
||||||
float Renderer::xScale;
|
|
||||||
float Renderer::yScale;
|
|
||||||
|
|
||||||
unsigned int Renderer::s_XFB_width;
|
|
||||||
unsigned int Renderer::s_XFB_height;
|
|
||||||
|
|
||||||
int Renderer::s_LastEFBScale;
|
int Renderer::s_LastEFBScale;
|
||||||
|
|
||||||
|
@ -81,6 +76,11 @@ bool Renderer::XFBWrited;
|
||||||
bool Renderer::s_EnableDLCachingAfterRecording;
|
bool Renderer::s_EnableDLCachingAfterRecording;
|
||||||
|
|
||||||
unsigned int Renderer::prev_efb_format = (unsigned int)-1;
|
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)
|
Renderer::Renderer() : frame_data(NULL), bLastFrameDumped(false)
|
||||||
|
@ -98,6 +98,8 @@ Renderer::~Renderer()
|
||||||
// invalidate previous efb format
|
// invalidate previous efb format
|
||||||
prev_efb_format = (unsigned int)-1;
|
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 defined _WIN32 || defined HAVE_LIBAV
|
||||||
if (g_ActiveConfig.bDumpFrames && bLastFrameDumped && bAVIDumping)
|
if (g_ActiveConfig.bDumpFrames && bLastFrameDumped && bAVIDumping)
|
||||||
AVIDump::Stop();
|
AVIDump::Stop();
|
||||||
|
@ -121,64 +123,117 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
||||||
VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight);
|
VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight);
|
||||||
XFBWrited = true;
|
XFBWrited = true;
|
||||||
|
|
||||||
// XXX: Without the VI, how would we know what kind of field this is? So
|
|
||||||
// just use progressive.
|
|
||||||
if (g_ActiveConfig.bUseXFB)
|
if (g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
FramebufferManagerBase::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc,Gamma);
|
FramebufferManagerBase::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc,Gamma);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// XXX: Without the VI, how would we know what kind of field this is? So
|
||||||
|
// just use progressive.
|
||||||
g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc,Gamma);
|
g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc,Gamma);
|
||||||
Common::AtomicStoreRelease(s_swapRequested, false);
|
Common::AtomicStoreRelease(s_swapRequested, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::CalculateTargetScale(int x, int y, int &scaledX, int &scaledY)
|
int Renderer::EFBToScaledX(int x)
|
||||||
{
|
{
|
||||||
switch (g_ActiveConfig.iEFBScale)
|
switch (g_ActiveConfig.iEFBScale)
|
||||||
{
|
{
|
||||||
case 3: // 1.5x
|
case 0: // fractional
|
||||||
scaledX = (x / 2) * 3;
|
return (int)ssaa_multiplier * FramebufferManagerBase::ScaleToVirtualXfbWidth(x, s_backbuffer_width);
|
||||||
scaledY = (y / 2) * 3;
|
|
||||||
break;
|
|
||||||
case 4: // 2x
|
|
||||||
scaledX = x * 2;
|
|
||||||
scaledY = y * 2;
|
|
||||||
break;
|
|
||||||
case 5: // 2.5x
|
|
||||||
scaledX = (x / 2) * 5;
|
|
||||||
scaledY = (y / 2) * 5;
|
|
||||||
break;
|
|
||||||
case 6: // 3x
|
|
||||||
scaledX = x * 3;
|
|
||||||
scaledY = y * 3;
|
|
||||||
break;
|
|
||||||
case 7: // 4x
|
|
||||||
scaledX = x * 4;
|
|
||||||
scaledY = y * 4;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
scaledX = x;
|
return x * (int)ssaa_multiplier * (int)efb_scale_numeratorX / (int)efb_scale_denominatorX;
|
||||||
scaledY = y;
|
|
||||||
break;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// return true if target size changed
|
||||||
bool Renderer::CalculateTargetSize(int multiplier)
|
bool Renderer::CalculateTargetSize(unsigned int framebuffer_width, unsigned int framebuffer_height, int multiplier)
|
||||||
{
|
{
|
||||||
int newEFBWidth, newEFBHeight;
|
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
|
||||||
|
efb_scale_numeratorX = efb_scale_numeratorY = 3;
|
||||||
|
efb_scale_denominatorX = efb_scale_denominatorY = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // 2x
|
||||||
|
efb_scale_numeratorX = efb_scale_numeratorY = 2;
|
||||||
|
efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: // 2.5x
|
||||||
|
efb_scale_numeratorX = efb_scale_numeratorY = 5;
|
||||||
|
efb_scale_denominatorX = efb_scale_denominatorY = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6: // 3x
|
||||||
|
efb_scale_numeratorX = efb_scale_numeratorY = 3;
|
||||||
|
efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: // 4x
|
||||||
|
efb_scale_numeratorX = efb_scale_numeratorY = 4;
|
||||||
|
efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // fractional & integral handled later
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (s_LastEFBScale)
|
switch (s_LastEFBScale)
|
||||||
{
|
{
|
||||||
case 0: // fractional
|
case 0: // fractional
|
||||||
newEFBWidth = (int)(EFB_WIDTH * xScale);
|
|
||||||
newEFBHeight = (int)(EFB_HEIGHT * yScale);
|
|
||||||
break;
|
|
||||||
case 1: // integral
|
case 1: // integral
|
||||||
newEFBWidth = EFB_WIDTH * (int)ceilf(xScale);
|
newEFBWidth = FramebufferManagerBase::ScaleToVirtualXfbWidth(EFB_WIDTH, framebuffer_width);
|
||||||
newEFBHeight = EFB_HEIGHT * (int)ceilf(yScale);
|
newEFBHeight = FramebufferManagerBase::ScaleToVirtualXfbHeight(EFB_HEIGHT, framebuffer_height);
|
||||||
|
|
||||||
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CalculateTargetScale(EFB_WIDTH, EFB_HEIGHT, newEFBWidth, newEFBHeight);
|
CalculateTargetScale(EFB_WIDTH, EFB_HEIGHT, newEFBWidth, newEFBHeight);
|
||||||
break;
|
break;
|
||||||
|
@ -186,6 +241,7 @@ bool Renderer::CalculateTargetSize(int multiplier)
|
||||||
|
|
||||||
newEFBWidth *= multiplier;
|
newEFBWidth *= multiplier;
|
||||||
newEFBHeight *= multiplier;
|
newEFBHeight *= multiplier;
|
||||||
|
ssaa_multiplier = multiplier;
|
||||||
|
|
||||||
if (newEFBWidth != s_target_width || newEFBHeight != s_target_height)
|
if (newEFBWidth != s_target_width || newEFBHeight != s_target_height)
|
||||||
{
|
{
|
||||||
|
@ -311,27 +367,125 @@ void Renderer::DrawDebugText()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::CalculateXYScale(const TargetRectangle& dst_rect)
|
// TODO: remove
|
||||||
|
extern bool g_aspect_wide;
|
||||||
|
|
||||||
|
void Renderer::UpdateDrawRectangle(int backbuffer_width, int backbuffer_height)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)
|
float FloatGLWidth = (float)backbuffer_width;
|
||||||
|
float FloatGLHeight = (float)backbuffer_height;
|
||||||
|
float FloatXOffset = 0;
|
||||||
|
float FloatYOffset = 0;
|
||||||
|
|
||||||
|
// The rendering window size
|
||||||
|
const float WinWidth = FloatGLWidth;
|
||||||
|
const float WinHeight = FloatGLHeight;
|
||||||
|
|
||||||
|
// Handle aspect ratio.
|
||||||
|
// Default to auto.
|
||||||
|
bool use16_9 = g_aspect_wide;
|
||||||
|
|
||||||
|
// Update aspect ratio hack values
|
||||||
|
// Won't take effect until next frame
|
||||||
|
// Don't know if there is a better place for this code so there isn't a 1 frame delay
|
||||||
|
if ( g_ActiveConfig.bWidescreenHack )
|
||||||
{
|
{
|
||||||
xScale = 1.0f;
|
float source_aspect = use16_9 ? (16.0f / 9.0f) : (4.0f / 3.0f);
|
||||||
yScale = 1.0f;
|
float target_aspect;
|
||||||
}
|
|
||||||
else
|
switch ( g_ActiveConfig.iAspectRatio )
|
||||||
{
|
|
||||||
if (g_ActiveConfig.b3DVision)
|
|
||||||
{
|
{
|
||||||
// This works, yet the version in the else doesn't. No idea why.
|
case ASPECT_FORCE_16_9 :
|
||||||
xScale = (float)(s_backbuffer_width-1) / (float)(s_XFB_width-1);
|
target_aspect = 16.0f / 9.0f;
|
||||||
yScale = (float)(s_backbuffer_height-1) / (float)(s_XFB_height-1);
|
break;
|
||||||
|
case ASPECT_FORCE_4_3 :
|
||||||
|
target_aspect = 4.0f / 3.0f;
|
||||||
|
break;
|
||||||
|
case ASPECT_STRETCH :
|
||||||
|
target_aspect = WinWidth / WinHeight;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
// ASPECT_AUTO == no hacking
|
||||||
|
target_aspect = source_aspect;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float adjust = source_aspect / target_aspect;
|
||||||
|
if ( adjust > 1 )
|
||||||
|
{
|
||||||
|
// Vert+
|
||||||
|
g_Config.fAspectRatioHackW = 1;
|
||||||
|
g_Config.fAspectRatioHackH = 1/adjust;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xScale = (float)(dst_rect.right - dst_rect.left - 1) / (float)(s_XFB_width-1);
|
// Hor+
|
||||||
yScale = (float)(dst_rect.bottom - dst_rect.top - 1) / (float)(s_XFB_height-1);
|
g_Config.fAspectRatioHackW = adjust;
|
||||||
|
g_Config.fAspectRatioHackH = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hack is disabled
|
||||||
|
g_Config.fAspectRatioHackW = 1;
|
||||||
|
g_Config.fAspectRatioHackH = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for force-settings and override.
|
||||||
|
if (g_ActiveConfig.iAspectRatio == ASPECT_FORCE_16_9)
|
||||||
|
use16_9 = true;
|
||||||
|
else if (g_ActiveConfig.iAspectRatio == ASPECT_FORCE_4_3)
|
||||||
|
use16_9 = false;
|
||||||
|
|
||||||
|
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH)
|
||||||
|
{
|
||||||
|
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
|
||||||
|
float Ratio = (WinWidth / WinHeight) / (!use16_9 ? (4.0f / 3.0f) : (16.0f / 9.0f));
|
||||||
|
// Check if height or width is the limiting factor. If ratio > 1 the picture is too wide and have to limit the width.
|
||||||
|
if (Ratio > 1.0f)
|
||||||
|
{
|
||||||
|
// Scale down and center in the X direction.
|
||||||
|
FloatGLWidth /= Ratio;
|
||||||
|
FloatXOffset = (WinWidth - FloatGLWidth) / 2.0f;
|
||||||
|
}
|
||||||
|
// The window is too high, we have to limit the height
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Scale down and center in the Y direction.
|
||||||
|
FloatGLHeight *= Ratio;
|
||||||
|
FloatYOffset = FloatYOffset + (WinHeight - FloatGLHeight) / 2.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10.
|
||||||
|
// Output: FloatGLWidth, FloatGLHeight, FloatXOffset, FloatYOffset
|
||||||
|
// ------------------
|
||||||
|
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH && g_ActiveConfig.bCrop)
|
||||||
|
{
|
||||||
|
float Ratio = !use16_9 ? ((4.0f / 3.0f) / (5.0f / 4.0f)) : (((16.0f / 9.0f) / (16.0f / 10.0f)));
|
||||||
|
// The width and height we will add (calculate this before FloatGLWidth and FloatGLHeight is adjusted)
|
||||||
|
float IncreasedWidth = (Ratio - 1.0f) * FloatGLWidth;
|
||||||
|
float IncreasedHeight = (Ratio - 1.0f) * FloatGLHeight;
|
||||||
|
// The new width and height
|
||||||
|
FloatGLWidth = FloatGLWidth * Ratio;
|
||||||
|
FloatGLHeight = FloatGLHeight * Ratio;
|
||||||
|
// Adjust the X and Y offset
|
||||||
|
FloatXOffset = FloatXOffset - (IncreasedWidth * 0.5f);
|
||||||
|
FloatYOffset = FloatYOffset - (IncreasedHeight * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int XOffset = (int)(FloatXOffset + 0.5f);
|
||||||
|
int YOffset = (int)(FloatYOffset + 0.5f);
|
||||||
|
int iWhidth = (int)ceil(FloatGLWidth);
|
||||||
|
int iHeight = (int)ceil(FloatGLHeight);
|
||||||
|
iWhidth -= iWhidth % 4; // ensure divisibility by 4 to make it compatible with all the video encoders
|
||||||
|
iHeight -= iHeight % 4;
|
||||||
|
|
||||||
|
target_rc.left = XOffset;
|
||||||
|
target_rc.top = YOffset;
|
||||||
|
target_rc.right = XOffset + iWhidth;
|
||||||
|
target_rc.bottom = YOffset + iHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetWindowSize(int width, int height)
|
void Renderer::SetWindowSize(int width, int height)
|
||||||
|
|
|
@ -74,10 +74,6 @@ public:
|
||||||
static int GetBackbufferWidth() { return s_backbuffer_width; }
|
static int GetBackbufferWidth() { return s_backbuffer_width; }
|
||||||
static int GetBackbufferHeight() { return s_backbuffer_height; }
|
static int GetBackbufferHeight() { return s_backbuffer_height; }
|
||||||
|
|
||||||
// XFB scale - TODO: Remove this and add two XFBToScaled functions instead
|
|
||||||
static float GetXFBScaleX() { return xScale; }
|
|
||||||
static float GetXFBScaleY() { return yScale; }
|
|
||||||
|
|
||||||
static void SetWindowSize(int width, int height);
|
static void SetWindowSize(int width, int height);
|
||||||
|
|
||||||
// EFB coordinate conversion functions
|
// EFB coordinate conversion functions
|
||||||
|
@ -85,9 +81,13 @@ public:
|
||||||
// Use this to convert a whole native EFB rect to backbuffer coordinates
|
// Use this to convert a whole native EFB rect to backbuffer coordinates
|
||||||
virtual TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) = 0;
|
virtual TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) = 0;
|
||||||
|
|
||||||
|
static const TargetRectangle& GetTargetRectangle() { return target_rc; }
|
||||||
|
static void UpdateDrawRectangle(int backbuffer_width, int backbuffer_height);
|
||||||
|
|
||||||
|
|
||||||
// Use this to upscale native EFB coordinates to IDEAL internal resolution
|
// Use this to upscale native EFB coordinates to IDEAL internal resolution
|
||||||
static unsigned int EFBToScaledX(int x) { return x * GetTargetWidth() / EFB_WIDTH; }
|
static int EFBToScaledX(int x);
|
||||||
static unsigned int EFBToScaledY(int y) { return y * GetTargetHeight() / EFB_HEIGHT; }
|
static int EFBToScaledY(int y);
|
||||||
|
|
||||||
// Floating point versions of the above - only use them if really necessary
|
// Floating point versions of the above - only use them if really necessary
|
||||||
static float EFBToScaledXf(float x) { return x * ((float)GetTargetWidth() / (float)EFB_WIDTH); }
|
static float EFBToScaledXf(float x) { return x * ((float)GetTargetWidth() / (float)EFB_WIDTH); }
|
||||||
|
@ -133,8 +133,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static void CalculateTargetScale(int x, int y, int &scaledX, int &scaledY);
|
static void CalculateTargetScale(int x, int y, int &scaledX, int &scaledY);
|
||||||
static bool CalculateTargetSize(int multiplier = 1);
|
static bool CalculateTargetSize(unsigned int framebuffer_width, unsigned int framebuffer_height, int multiplier = 1);
|
||||||
static void CalculateXYScale(const TargetRectangle& dst_rect);
|
|
||||||
|
|
||||||
static void CheckFifoRecording();
|
static void CheckFifoRecording();
|
||||||
static void RecordVideoMemory();
|
static void RecordVideoMemory();
|
||||||
|
@ -159,12 +158,7 @@ protected:
|
||||||
static int s_backbuffer_width;
|
static int s_backbuffer_width;
|
||||||
static int s_backbuffer_height;
|
static int s_backbuffer_height;
|
||||||
|
|
||||||
// ratio of backbuffer size and render area size - TODO: Remove these!
|
static TargetRectangle target_rc;
|
||||||
static float xScale;
|
|
||||||
static float yScale;
|
|
||||||
|
|
||||||
static unsigned int s_XFB_width;
|
|
||||||
static unsigned int s_XFB_height;
|
|
||||||
|
|
||||||
// can probably eliminate this static var
|
// can probably eliminate this static var
|
||||||
static int s_LastEFBScale;
|
static int s_LastEFBScale;
|
||||||
|
@ -176,6 +170,11 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static unsigned int prev_efb_format;
|
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;
|
extern Renderer *g_renderer;
|
||||||
|
|
|
@ -292,125 +292,3 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini)
|
||||||
|
|
||||||
iniFile.Save(game_ini);
|
iniFile.Save(game_ini);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: remove
|
|
||||||
extern bool g_aspect_wide;
|
|
||||||
|
|
||||||
// TODO: Figure out a better place for this function.
|
|
||||||
void ComputeDrawRectangle(int backbuffer_width, int backbuffer_height, bool flip, TargetRectangle *rc)
|
|
||||||
{
|
|
||||||
float FloatGLWidth = (float)backbuffer_width;
|
|
||||||
float FloatGLHeight = (float)backbuffer_height;
|
|
||||||
float FloatXOffset = 0;
|
|
||||||
float FloatYOffset = 0;
|
|
||||||
|
|
||||||
// The rendering window size
|
|
||||||
const float WinWidth = FloatGLWidth;
|
|
||||||
const float WinHeight = FloatGLHeight;
|
|
||||||
|
|
||||||
// Handle aspect ratio.
|
|
||||||
// Default to auto.
|
|
||||||
bool use16_9 = g_aspect_wide;
|
|
||||||
|
|
||||||
// Update aspect ratio hack values
|
|
||||||
// Won't take effect until next frame
|
|
||||||
// Don't know if there is a better place for this code so there isn't a 1 frame delay
|
|
||||||
if ( g_ActiveConfig.bWidescreenHack )
|
|
||||||
{
|
|
||||||
float source_aspect = use16_9 ? (16.0f / 9.0f) : (4.0f / 3.0f);
|
|
||||||
float target_aspect;
|
|
||||||
|
|
||||||
switch ( g_ActiveConfig.iAspectRatio )
|
|
||||||
{
|
|
||||||
case ASPECT_FORCE_16_9 :
|
|
||||||
target_aspect = 16.0f / 9.0f;
|
|
||||||
break;
|
|
||||||
case ASPECT_FORCE_4_3 :
|
|
||||||
target_aspect = 4.0f / 3.0f;
|
|
||||||
break;
|
|
||||||
case ASPECT_STRETCH :
|
|
||||||
target_aspect = WinWidth / WinHeight;
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
// ASPECT_AUTO == no hacking
|
|
||||||
target_aspect = source_aspect;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
float adjust = source_aspect / target_aspect;
|
|
||||||
if ( adjust > 1 )
|
|
||||||
{
|
|
||||||
// Vert+
|
|
||||||
g_Config.fAspectRatioHackW = 1;
|
|
||||||
g_Config.fAspectRatioHackH = 1/adjust;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Hor+
|
|
||||||
g_Config.fAspectRatioHackW = adjust;
|
|
||||||
g_Config.fAspectRatioHackH = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Hack is disabled
|
|
||||||
g_Config.fAspectRatioHackW = 1;
|
|
||||||
g_Config.fAspectRatioHackH = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for force-settings and override.
|
|
||||||
if (g_ActiveConfig.iAspectRatio == ASPECT_FORCE_16_9)
|
|
||||||
use16_9 = true;
|
|
||||||
else if (g_ActiveConfig.iAspectRatio == ASPECT_FORCE_4_3)
|
|
||||||
use16_9 = false;
|
|
||||||
|
|
||||||
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH)
|
|
||||||
{
|
|
||||||
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
|
|
||||||
float Ratio = (WinWidth / WinHeight) / (!use16_9 ? (4.0f / 3.0f) : (16.0f / 9.0f));
|
|
||||||
// Check if height or width is the limiting factor. If ratio > 1 the picture is too wide and have to limit the width.
|
|
||||||
if (Ratio > 1.0f)
|
|
||||||
{
|
|
||||||
// Scale down and center in the X direction.
|
|
||||||
FloatGLWidth /= Ratio;
|
|
||||||
FloatXOffset = (WinWidth - FloatGLWidth) / 2.0f;
|
|
||||||
}
|
|
||||||
// The window is too high, we have to limit the height
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Scale down and center in the Y direction.
|
|
||||||
FloatGLHeight *= Ratio;
|
|
||||||
FloatYOffset = FloatYOffset + (WinHeight - FloatGLHeight) / 2.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
// Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10.
|
|
||||||
// Output: FloatGLWidth, FloatGLHeight, FloatXOffset, FloatYOffset
|
|
||||||
// ------------------
|
|
||||||
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH && g_ActiveConfig.bCrop)
|
|
||||||
{
|
|
||||||
float Ratio = !use16_9 ? ((4.0f / 3.0f) / (5.0f / 4.0f)) : (((16.0f / 9.0f) / (16.0f / 10.0f)));
|
|
||||||
// The width and height we will add (calculate this before FloatGLWidth and FloatGLHeight is adjusted)
|
|
||||||
float IncreasedWidth = (Ratio - 1.0f) * FloatGLWidth;
|
|
||||||
float IncreasedHeight = (Ratio - 1.0f) * FloatGLHeight;
|
|
||||||
// The new width and height
|
|
||||||
FloatGLWidth = FloatGLWidth * Ratio;
|
|
||||||
FloatGLHeight = FloatGLHeight * Ratio;
|
|
||||||
// Adjust the X and Y offset
|
|
||||||
FloatXOffset = FloatXOffset - (IncreasedWidth * 0.5f);
|
|
||||||
FloatYOffset = FloatYOffset - (IncreasedHeight * 0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
int XOffset = (int)(FloatXOffset + 0.5f);
|
|
||||||
int YOffset = (int)(FloatYOffset + 0.5f);
|
|
||||||
int iWhidth = (int)ceil(FloatGLWidth);
|
|
||||||
int iHeight = (int)ceil(FloatGLHeight);
|
|
||||||
iWhidth -= iWhidth % 4; // ensure divisibility by 4 to make it compatible with all the video encoders
|
|
||||||
iHeight -= iHeight % 4;
|
|
||||||
rc->left = XOffset;
|
|
||||||
rc->top = flip ? (int)(YOffset + iHeight) : YOffset;
|
|
||||||
rc->right = XOffset + iWhidth;
|
|
||||||
rc->bottom = flip ? YOffset : (int)(YOffset + iHeight);
|
|
||||||
}
|
|
||||||
|
|
|
@ -163,6 +163,12 @@ struct VideoConfig
|
||||||
bool bSupportsFormatReinterpretation;
|
bool bSupportsFormatReinterpretation;
|
||||||
bool bSupportsPixelLighting;
|
bool bSupportsPixelLighting;
|
||||||
} backend_info;
|
} backend_info;
|
||||||
|
|
||||||
|
// Utility
|
||||||
|
bool RealXFBEnabled() const { return bUseXFB && bUseRealXFB; }
|
||||||
|
bool VirtualXFBEnabled() const { return bUseXFB && !bUseRealXFB; }
|
||||||
|
bool EFBCopiesToTextureEnabled() const { return bEFBCopyEnable && bCopyEFBToTexture; }
|
||||||
|
bool EFBCopiesToRamEnabled() const { return bEFBCopyEnable && !bCopyEFBToTexture; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern VideoConfig g_Config;
|
extern VideoConfig g_Config;
|
||||||
|
@ -171,6 +177,4 @@ extern VideoConfig g_ActiveConfig;
|
||||||
// Called every frame.
|
// Called every frame.
|
||||||
void UpdateActiveConfig();
|
void UpdateActiveConfig();
|
||||||
|
|
||||||
void ComputeDrawRectangle(int backbuffer_width, int backbuffer_height, bool flip, TargetRectangle *rc);
|
|
||||||
|
|
||||||
#endif // _VIDEO_CONFIG_H_
|
#endif // _VIDEO_CONFIG_H_
|
||||||
|
|
|
@ -181,15 +181,12 @@ XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, un
|
||||||
|
|
||||||
void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc)
|
void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
const float scaleX = Renderer::GetXFBScaleX();
|
|
||||||
const float scaleY = Renderer::GetXFBScaleY();
|
|
||||||
|
|
||||||
TargetRectangle targetSource;
|
TargetRectangle targetSource;
|
||||||
|
|
||||||
targetSource.top = (int)(sourceRc.top *scaleY);
|
targetSource.top = ScaleToVirtualXfbHeight(sourceRc.top, Renderer::GetBackbufferHeight());
|
||||||
targetSource.bottom = (int)(sourceRc.bottom *scaleY);
|
targetSource.bottom = ScaleToVirtualXfbHeight(sourceRc.bottom, Renderer::GetBackbufferHeight());
|
||||||
targetSource.left = (int)(sourceRc.left *scaleX);
|
targetSource.left = ScaleToVirtualXfbWidth(sourceRc.left, Renderer::GetBackbufferWidth());
|
||||||
targetSource.right = (int)(sourceRc.right * scaleX);
|
targetSource.right = ScaleToVirtualXfbWidth(sourceRc.right, Renderer::GetBackbufferWidth());
|
||||||
|
|
||||||
*width = targetSource.right - targetSource.left;
|
*width = targetSource.right - targetSource.left;
|
||||||
*height = targetSource.bottom - targetSource.top;
|
*height = targetSource.bottom - targetSource.top;
|
||||||
|
|
|
@ -349,17 +349,14 @@ Renderer::Renderer()
|
||||||
s_backbuffer_width = D3D::GetBackBufferWidth();
|
s_backbuffer_width = D3D::GetBackBufferWidth();
|
||||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||||
|
|
||||||
s_XFB_width = MAX_XFB_WIDTH;
|
FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH);
|
||||||
s_XFB_height = MAX_XFB_HEIGHT;
|
FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT);
|
||||||
|
|
||||||
TargetRectangle dst_rect;
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
|
||||||
|
|
||||||
CalculateXYScale(dst_rect);
|
|
||||||
|
|
||||||
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
CalculateTargetSize();
|
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);
|
||||||
|
|
||||||
SetupDeviceObjects();
|
SetupDeviceObjects();
|
||||||
|
|
||||||
|
@ -902,7 +899,7 @@ void formatBufferDump(const char *in, char *out, int w, int h, int p)
|
||||||
// This function has the final picture. We adjust the aspect ratio here.
|
// This function has the final picture. We adjust the aspect ratio here.
|
||||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
||||||
{
|
{
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && frame_data)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
AVIDump::AddFrame(frame_data);
|
AVIDump::AddFrame(frame_data);
|
||||||
|
@ -928,13 +925,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
ResetAPIState();
|
ResetAPIState();
|
||||||
|
|
||||||
// Prepare to copy the XFBs to our backbuffer
|
// Prepare to copy the XFBs to our backbuffer
|
||||||
TargetRectangle dst_rect;
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
|
||||||
|
|
||||||
int X = dst_rect.left;
|
int X = GetTargetRectangle().left;
|
||||||
int Y = dst_rect.top;
|
int Y = GetTargetRectangle().top;
|
||||||
int Width = dst_rect.right - dst_rect.left;
|
int Width = GetTargetRectangle().right - GetTargetRectangle().left;
|
||||||
int Height = dst_rect.bottom - dst_rect.top;
|
int Height = GetTargetRectangle().bottom - GetTargetRectangle().top;
|
||||||
|
|
||||||
// TODO: Redundant checks...
|
// TODO: Redundant checks...
|
||||||
if (X < 0) X = 0;
|
if (X < 0) X = 0;
|
||||||
|
@ -978,7 +974,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
MathUtil::Rectangle<float> drawRc;
|
MathUtil::Rectangle<float> drawRc;
|
||||||
|
|
||||||
if (g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if (g_ActiveConfig.bUseRealXFB)
|
||||||
|
{
|
||||||
|
drawRc.top = 1;
|
||||||
|
drawRc.bottom = -1;
|
||||||
|
drawRc.left = -1;
|
||||||
|
drawRc.right = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// use virtual xfb with offset
|
// use virtual xfb with offset
|
||||||
int xfbHeight = xfbSource->srcHeight;
|
int xfbHeight = xfbSource->srcHeight;
|
||||||
|
@ -999,13 +1002,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
//drawRc.left *= hScale;
|
//drawRc.left *= hScale;
|
||||||
//drawRc.right *= hScale;
|
//drawRc.right *= hScale;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
drawRc.top = 1;
|
|
||||||
drawRc.bottom = -1;
|
|
||||||
drawRc.left = -1;
|
|
||||||
drawRc.right = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
xfbSource->Draw(sourceRc, drawRc, 0, 0);
|
xfbSource->Draw(sourceRc, drawRc, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -1022,7 +1018,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
// done with drawing the game stuff, good moment to save a screenshot
|
// done with drawing the game stuff, good moment to save a screenshot
|
||||||
if (s_bScreenshot)
|
if (s_bScreenshot)
|
||||||
{
|
{
|
||||||
SaveScreenshot(s_sScreenshotName, dst_rect);
|
SaveScreenshot(s_sScreenshotName, GetTargetRectangle());
|
||||||
s_bScreenshot = false;
|
s_bScreenshot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1039,8 +1035,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex());
|
D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex());
|
||||||
if (!bLastFrameDumped)
|
if (!bLastFrameDumped)
|
||||||
{
|
{
|
||||||
s_recordWidth = dst_rect.GetWidth();
|
s_recordWidth = GetTargetRectangle().GetWidth();
|
||||||
s_recordHeight = dst_rect.GetHeight();
|
s_recordHeight = GetTargetRectangle().GetHeight();
|
||||||
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
||||||
if (!bAVIDumping)
|
if (!bAVIDumping)
|
||||||
{
|
{
|
||||||
|
@ -1066,7 +1062,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
w = s_recordWidth;
|
w = s_recordWidth;
|
||||||
h = s_recordHeight;
|
h = s_recordHeight;
|
||||||
}
|
}
|
||||||
char* source_ptr = (char*)map.pData + dst_rect.left*4 + dst_rect.top*map.RowPitch;
|
char* source_ptr = (char*)map.pData + GetTargetRectangle().left*4 + GetTargetRectangle().top*map.RowPitch;
|
||||||
formatBufferDump(source_ptr, frame_data, s_recordWidth, s_recordHeight, map.RowPitch);
|
formatBufferDump(source_ptr, frame_data, s_recordWidth, s_recordHeight, map.RowPitch);
|
||||||
AVIDump::AddFrame(frame_data);
|
AVIDump::AddFrame(frame_data);
|
||||||
D3D::context->Unmap(s_screenshot_texture, 0);
|
D3D::context->Unmap(s_screenshot_texture, 0);
|
||||||
|
@ -1142,15 +1138,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
bool xfbchanged = false;
|
bool xfbchanged = false;
|
||||||
|
|
||||||
if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
|
if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight)
|
||||||
{
|
{
|
||||||
xfbchanged = true;
|
xfbchanged = true;
|
||||||
s_XFB_width = fbWidth;
|
unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth;
|
||||||
s_XFB_height = fbHeight;
|
unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight;
|
||||||
if (s_XFB_width < 1) s_XFB_width = MAX_XFB_WIDTH;
|
FramebufferManagerBase::SetLastXfbWidth(w);
|
||||||
if (s_XFB_width > MAX_XFB_WIDTH) s_XFB_width = MAX_XFB_WIDTH;
|
FramebufferManagerBase::SetLastXfbHeight(h);
|
||||||
if (s_XFB_height < 1) s_XFB_height = MAX_XFB_HEIGHT;
|
|
||||||
if (s_XFB_height > MAX_XFB_HEIGHT) s_XFB_height = MAX_XFB_HEIGHT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update FPS counter
|
// update FPS counter
|
||||||
|
@ -1183,12 +1177,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
|
|
||||||
CalculateXYScale(dst_rect);
|
|
||||||
|
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
CalculateTargetSize();
|
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
||||||
|
|
||||||
|
|
|
@ -149,15 +149,12 @@ XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, un
|
||||||
|
|
||||||
void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc)
|
void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
const float scaleX = Renderer::GetXFBScaleX();
|
|
||||||
const float scaleY = Renderer::GetXFBScaleY();
|
|
||||||
|
|
||||||
TargetRectangle targetSource;
|
TargetRectangle targetSource;
|
||||||
|
|
||||||
targetSource.top = (int)(sourceRc.top *scaleY);
|
targetSource.top = ScaleToVirtualXfbHeight(sourceRc.top, Renderer::GetBackbufferHeight());
|
||||||
targetSource.bottom = (int)(sourceRc.bottom *scaleY);
|
targetSource.bottom = ScaleToVirtualXfbHeight(sourceRc.bottom, Renderer::GetBackbufferHeight());
|
||||||
targetSource.left = (int)(sourceRc.left *scaleX);
|
targetSource.left = ScaleToVirtualXfbWidth(sourceRc.left, Renderer::GetBackbufferWidth());
|
||||||
targetSource.right = (int)(sourceRc.right * scaleX);
|
targetSource.right = ScaleToVirtualXfbWidth(sourceRc.right, Renderer::GetBackbufferWidth());
|
||||||
|
|
||||||
*width = targetSource.right - targetSource.left;
|
*width = targetSource.right - targetSource.left;
|
||||||
*height = targetSource.bottom - targetSource.top;
|
*height = targetSource.bottom - targetSource.top;
|
||||||
|
|
|
@ -280,19 +280,16 @@ Renderer::Renderer()
|
||||||
s_backbuffer_width = D3D::GetBackBufferWidth();
|
s_backbuffer_width = D3D::GetBackBufferWidth();
|
||||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||||
|
|
||||||
s_XFB_width = MAX_XFB_WIDTH;
|
FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH);
|
||||||
s_XFB_height = MAX_XFB_HEIGHT;
|
FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT);
|
||||||
|
|
||||||
TargetRectangle dst_rect;
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
|
||||||
|
|
||||||
CalculateXYScale(dst_rect);
|
|
||||||
|
|
||||||
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||||
int SupersampleCoeficient = (s_LastAA % 3) + 1;
|
int SupersampleCoeficient = (s_LastAA % 3) + 1;
|
||||||
|
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
CalculateTargetSize(SupersampleCoeficient);
|
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient);
|
||||||
|
|
||||||
// Make sure to use valid texture sizes
|
// Make sure to use valid texture sizes
|
||||||
D3D::FixTextureSize(s_target_width, s_target_height);
|
D3D::FixTextureSize(s_target_width, s_target_height);
|
||||||
|
@ -837,7 +834,7 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
|
||||||
// This function has the final picture. We adjust the aspect ratio here.
|
// This function has the final picture. We adjust the aspect ratio here.
|
||||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
||||||
{
|
{
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && frame_data)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
AVIDump::AddFrame(frame_data);
|
AVIDump::AddFrame(frame_data);
|
||||||
|
@ -888,8 +885,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
D3D::dev->SetDepthStencilSurface(NULL);
|
D3D::dev->SetDepthStencilSurface(NULL);
|
||||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||||
|
|
||||||
TargetRectangle dst_rect;
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
|
||||||
D3DVIEWPORT9 vp;
|
D3DVIEWPORT9 vp;
|
||||||
|
|
||||||
// Clear full target screen (edges, borders etc)
|
// Clear full target screen (edges, borders etc)
|
||||||
|
@ -909,10 +905,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
|
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int X = dst_rect.left;
|
int X = GetTargetRectangle().left;
|
||||||
int Y = dst_rect.top;
|
int Y = GetTargetRectangle().top;
|
||||||
int Width = dst_rect.right - dst_rect.left;
|
int Width = GetTargetRectangle().right - GetTargetRectangle().left;
|
||||||
int Height = dst_rect.bottom - dst_rect.top;
|
int Height = GetTargetRectangle().bottom - GetTargetRectangle().top;
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (X < 0) X = 0;
|
if (X < 0) X = 0;
|
||||||
|
@ -955,7 +951,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
MathUtil::Rectangle<float> drawRc;
|
MathUtil::Rectangle<float> drawRc;
|
||||||
|
|
||||||
if (!g_ActiveConfig.bUseRealXFB)
|
if (g_ActiveConfig.bUseRealXFB)
|
||||||
|
{
|
||||||
|
drawRc.top = -1;
|
||||||
|
drawRc.bottom = 1;
|
||||||
|
drawRc.left = -1;
|
||||||
|
drawRc.right = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// use virtual xfb with offset
|
// use virtual xfb with offset
|
||||||
int xfbHeight = xfbSource->srcHeight;
|
int xfbHeight = xfbSource->srcHeight;
|
||||||
|
@ -969,20 +972,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
// The following code disables auto stretch. Kept for reference.
|
// The following code disables auto stretch. Kept for reference.
|
||||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||||
//float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
|
//float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight();
|
||||||
//float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
|
//float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth();
|
||||||
//drawRc.top *= vScale;
|
//drawRc.top *= vScale;
|
||||||
//drawRc.bottom *= vScale;
|
//drawRc.bottom *= vScale;
|
||||||
//drawRc.left *= hScale;
|
//drawRc.left *= hScale;
|
||||||
//drawRc.right *= hScale;
|
//drawRc.right *= hScale;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
drawRc.top = -1;
|
|
||||||
drawRc.bottom = 1;
|
|
||||||
drawRc.left = -1;
|
|
||||||
drawRc.right = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
xfbSource->Draw(sourceRc, drawRc, Width, Height);
|
xfbSource->Draw(sourceRc, drawRc, Width, Height);
|
||||||
}
|
}
|
||||||
|
@ -1019,7 +1015,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (s_bScreenshot)
|
if (s_bScreenshot)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||||
SaveScreenshot(s_sScreenshotName, dst_rect);
|
SaveScreenshot(s_sScreenshotName, GetTargetRectangle());
|
||||||
s_bScreenshot = false;
|
s_bScreenshot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,8 +1029,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
||||||
if (!bLastFrameDumped)
|
if (!bLastFrameDumped)
|
||||||
{
|
{
|
||||||
s_recordWidth = dst_rect.GetWidth();
|
s_recordWidth = GetTargetRectangle().GetWidth();
|
||||||
s_recordHeight = dst_rect.GetHeight();
|
s_recordHeight = GetTargetRectangle().GetHeight();
|
||||||
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
||||||
if (!bAVIDumping)
|
if (!bAVIDumping)
|
||||||
{
|
{
|
||||||
|
@ -1051,7 +1047,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (bAVIDumping)
|
if (bAVIDumping)
|
||||||
{
|
{
|
||||||
D3DLOCKED_RECT rect;
|
D3DLOCKED_RECT rect;
|
||||||
if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, dst_rect.AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
|
if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
|
||||||
{
|
{
|
||||||
if (!frame_data || w != s_recordWidth || h != s_recordHeight)
|
if (!frame_data || w != s_recordWidth || h != s_recordHeight)
|
||||||
{
|
{
|
||||||
|
@ -1138,15 +1134,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
bool xfbchanged = false;
|
bool xfbchanged = false;
|
||||||
|
|
||||||
if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
|
if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight)
|
||||||
{
|
{
|
||||||
xfbchanged = true;
|
xfbchanged = true;
|
||||||
s_XFB_width = fbWidth;
|
unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth;
|
||||||
s_XFB_height = fbHeight;
|
unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight;
|
||||||
if (s_XFB_width < 1) s_XFB_width = MAX_XFB_WIDTH;
|
FramebufferManagerBase::SetLastXfbWidth(w);
|
||||||
if (s_XFB_width > MAX_XFB_WIDTH) s_XFB_width = MAX_XFB_WIDTH;
|
FramebufferManagerBase::SetLastXfbHeight(h);
|
||||||
if (s_XFB_height < 1) s_XFB_height = MAX_XFB_HEIGHT;
|
|
||||||
if (s_XFB_height > MAX_XFB_HEIGHT) s_XFB_height = MAX_XFB_HEIGHT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 newAA = g_ActiveConfig.iMultisampleMode;
|
u32 newAA = g_ActiveConfig.iMultisampleMode;
|
||||||
|
@ -1155,14 +1149,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
{
|
{
|
||||||
s_LastAA = newAA;
|
s_LastAA = newAA;
|
||||||
|
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
|
|
||||||
CalculateXYScale(dst_rect);
|
|
||||||
|
|
||||||
int SupersampleCoeficient = (s_LastAA % 3) + 1;
|
int SupersampleCoeficient = (s_LastAA % 3) + 1;
|
||||||
|
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
CalculateTargetSize(SupersampleCoeficient);
|
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient);
|
||||||
|
|
||||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
||||||
|
|
|
@ -363,16 +363,14 @@ Renderer::Renderer()
|
||||||
if (!GLEW_ARB_texture_non_power_of_two)
|
if (!GLEW_ARB_texture_non_power_of_two)
|
||||||
WARN_LOG(VIDEO, "ARB_texture_non_power_of_two not supported.");
|
WARN_LOG(VIDEO, "ARB_texture_non_power_of_two not supported.");
|
||||||
|
|
||||||
s_XFB_width = MAX_XFB_WIDTH;
|
// TODO: Move these somewhere else?
|
||||||
s_XFB_height = MAX_XFB_HEIGHT;
|
FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH);
|
||||||
|
FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT);
|
||||||
|
|
||||||
TargetRectangle dst_rect;
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
|
||||||
|
|
||||||
CalculateXYScale(dst_rect);
|
|
||||||
|
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
CalculateTargetSize();
|
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);
|
||||||
|
|
||||||
// Because of the fixed framebuffer size we need to disable the resolution
|
// Because of the fixed framebuffer size we need to disable the resolution
|
||||||
// options while running
|
// options while running
|
||||||
|
@ -997,7 +995,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
||||||
{
|
{
|
||||||
static int w = 0, h = 0;
|
static int w = 0, h = 0;
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && frame_data)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
{
|
{
|
||||||
|
@ -1017,7 +1015,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
||||||
u32 xfbCount = 0;
|
u32 xfbCount = 0;
|
||||||
const XFBSourceBase* const* xfbSourceList = 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)
|
if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0))
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && frame_data)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
{
|
{
|
||||||
|
@ -1033,8 +1031,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
ResetAPIState();
|
ResetAPIState();
|
||||||
|
|
||||||
TargetRectangle dst_rect;
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &dst_rect);
|
TargetRectangle flipped_trc = GetTargetRectangle();
|
||||||
|
|
||||||
|
// Flip top and bottom for some reason; TODO: Fix the code to suck less?
|
||||||
|
int tmp = flipped_trc.top;
|
||||||
|
flipped_trc.top = flipped_trc.bottom;
|
||||||
|
flipped_trc.bottom = tmp;
|
||||||
|
|
||||||
// Textured triangles are necessary because of post-processing shaders
|
// Textured triangles are necessary because of post-processing shaders
|
||||||
|
|
||||||
|
@ -1043,7 +1046,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
OGL::TextureCache::DisableStage(i);
|
OGL::TextureCache::DisableStage(i);
|
||||||
|
|
||||||
// Update GLViewPort
|
// Update GLViewPort
|
||||||
glViewport(dst_rect.left, dst_rect.bottom, dst_rect.GetWidth(), dst_rect.GetHeight());
|
glViewport(flipped_trc.left, flipped_trc.bottom, flipped_trc.GetWidth(), flipped_trc.GetHeight());
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
@ -1074,7 +1077,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
MathUtil::Rectangle<float> drawRc;
|
MathUtil::Rectangle<float> drawRc;
|
||||||
|
|
||||||
if (!g_ActiveConfig.bUseRealXFB)
|
if (g_ActiveConfig.bUseRealXFB)
|
||||||
|
{
|
||||||
|
drawRc.top = 1;
|
||||||
|
drawRc.bottom = -1;
|
||||||
|
drawRc.left = -1;
|
||||||
|
drawRc.right = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// use virtual xfb with offset
|
// use virtual xfb with offset
|
||||||
int xfbHeight = xfbSource->srcHeight;
|
int xfbHeight = xfbSource->srcHeight;
|
||||||
|
@ -1088,21 +1098,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
// The following code disables auto stretch. Kept for reference.
|
// The following code disables auto stretch. Kept for reference.
|
||||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||||
//float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
|
//float vScale = (float)fbHeight / (float)flipped_trc.GetHeight();
|
||||||
//float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
|
//float hScale = (float)fbWidth / (float)flipped_trc.GetWidth();
|
||||||
//drawRc.top *= vScale;
|
//drawRc.top *= vScale;
|
||||||
//drawRc.bottom *= vScale;
|
//drawRc.bottom *= vScale;
|
||||||
//drawRc.left *= hScale;
|
//drawRc.left *= hScale;
|
||||||
//drawRc.right *= hScale;
|
//drawRc.right *= hScale;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
drawRc.top = 1;
|
|
||||||
drawRc.bottom = -1;
|
|
||||||
drawRc.left = -1;
|
|
||||||
drawRc.right = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tell the OSD Menu about the current internal resolution
|
// Tell the OSD Menu about the current internal resolution
|
||||||
OSDInternalW = xfbSource->sourceRc.GetWidth(); OSDInternalH = xfbSource->sourceRc.GetHeight();
|
OSDInternalW = xfbSource->sourceRc.GetWidth(); OSDInternalH = xfbSource->sourceRc.GetHeight();
|
||||||
|
|
||||||
|
@ -1174,7 +1176,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (s_bScreenshot)
|
if (s_bScreenshot)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||||
SaveScreenshot(s_sScreenshotName, dst_rect);
|
SaveScreenshot(s_sScreenshotName, flipped_trc);
|
||||||
// Reset settings
|
// Reset settings
|
||||||
s_sScreenshotName.clear();
|
s_sScreenshotName.clear();
|
||||||
s_bScreenshot = false;
|
s_bScreenshot = false;
|
||||||
|
@ -1185,16 +1187,16 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (g_ActiveConfig.bDumpFrames)
|
if (g_ActiveConfig.bDumpFrames)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||||
if (!frame_data || w != dst_rect.GetWidth() ||
|
if (!frame_data || w != flipped_trc.GetWidth() ||
|
||||||
h != dst_rect.GetHeight())
|
h != flipped_trc.GetHeight())
|
||||||
{
|
{
|
||||||
if (frame_data) delete[] frame_data;
|
if (frame_data) delete[] frame_data;
|
||||||
w = dst_rect.GetWidth();
|
w = flipped_trc.GetWidth();
|
||||||
h = dst_rect.GetHeight();
|
h = flipped_trc.GetHeight();
|
||||||
frame_data = new char[3 * w * h];
|
frame_data = new char[3 * w * h];
|
||||||
}
|
}
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data);
|
glReadPixels(flipped_trc.left, flipped_trc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data);
|
||||||
if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0)
|
if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0)
|
||||||
{
|
{
|
||||||
if (!bLastFrameDumped)
|
if (!bLastFrameDumped)
|
||||||
|
@ -1249,11 +1251,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||||
std::string movie_file_name;
|
std::string movie_file_name;
|
||||||
w = dst_rect.GetWidth();
|
w = GetTargetRectangle().GetWidth();
|
||||||
h = dst_rect.GetHeight();
|
h = GetTargetRectangle().GetHeight();
|
||||||
frame_data = new char[3 * w * h];
|
frame_data = new char[3 * w * h];
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data);
|
glReadPixels(GetTargetRectangle().left, GetTargetRectangle().bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data);
|
||||||
if (GL_REPORT_ERROR() == GL_NO_ERROR)
|
if (GL_REPORT_ERROR() == GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
if (!bLastFrameDumped)
|
if (!bLastFrameDumped)
|
||||||
|
@ -1296,15 +1298,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
bool xfbchanged = false;
|
bool xfbchanged = false;
|
||||||
|
|
||||||
if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
|
if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight)
|
||||||
{
|
{
|
||||||
xfbchanged = true;
|
xfbchanged = true;
|
||||||
s_XFB_width = fbWidth;
|
unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth;
|
||||||
s_XFB_height = fbHeight;
|
unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight;
|
||||||
if (s_XFB_width < 1) s_XFB_width = MAX_XFB_WIDTH;
|
FramebufferManagerBase::SetLastXfbWidth(w);
|
||||||
if (s_XFB_width > MAX_XFB_WIDTH) s_XFB_width = MAX_XFB_WIDTH;
|
FramebufferManagerBase::SetLastXfbHeight(h);
|
||||||
if (s_XFB_height < 1) s_XFB_height = MAX_XFB_HEIGHT;
|
|
||||||
if (s_XFB_height > MAX_XFB_HEIGHT) s_XFB_height = MAX_XFB_HEIGHT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowResized = false;
|
bool WindowResized = false;
|
||||||
|
@ -1320,11 +1320,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
if (xfbchanged || WindowResized || (s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode))
|
if (xfbchanged || WindowResized || (s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode))
|
||||||
{
|
{
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
|
|
||||||
CalculateXYScale(dst_rect);
|
if (CalculateTargetSize(s_backbuffer_width, s_backbuffer_height) || s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode)
|
||||||
|
|
||||||
if (CalculateTargetSize() || (s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode))
|
|
||||||
{
|
{
|
||||||
s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode;
|
s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode;
|
||||||
s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode);
|
s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode);
|
||||||
|
|
Loading…
Reference in New Issue