27 changes: 13 additions & 14 deletions Source/Core/VideoCommon/Src/RenderBase.h
Expand Up @@ -74,20 +74,20 @@ class Renderer
static int GetBackbufferWidth() { return s_backbuffer_width; }
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);

// EFB coordinate conversion functions

// Use this to convert a whole native EFB rect to backbuffer coordinates
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
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); }
Expand Down Expand Up @@ -133,8 +133,7 @@ class Renderer
protected:

static void CalculateTargetScale(int x, int y, int &scaledX, int &scaledY);
static bool CalculateTargetSize(int multiplier = 1);
static void CalculateXYScale(const TargetRectangle& dst_rect);
static bool CalculateTargetSize(unsigned int framebuffer_width, unsigned int framebuffer_height, int multiplier = 1);

static void CheckFifoRecording();
static void RecordVideoMemory();
Expand All @@ -159,12 +158,7 @@ class Renderer
static int s_backbuffer_width;
static int s_backbuffer_height;

// ratio of backbuffer size and render area size - TODO: Remove these!
static float xScale;
static float yScale;

static unsigned int s_XFB_width;
static unsigned int s_XFB_height;
static TargetRectangle target_rc;

// can probably eliminate this static var
static int s_LastEFBScale;
Expand All @@ -176,6 +170,11 @@ class Renderer

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;
Expand Down
122 changes: 0 additions & 122 deletions Source/Core/VideoCommon/Src/VideoConfig.cpp
Expand Up @@ -292,125 +292,3 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* 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);
}
8 changes: 6 additions & 2 deletions Source/Core/VideoCommon/Src/VideoConfig.h
Expand Up @@ -163,6 +163,12 @@ struct VideoConfig
bool bSupportsFormatReinterpretation;
bool bSupportsPixelLighting;
} 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;
Expand All @@ -171,6 +177,4 @@ extern VideoConfig g_ActiveConfig;
// Called every frame.
void UpdateActiveConfig();

void ComputeDrawRectangle(int backbuffer_width, int backbuffer_height, bool flip, TargetRectangle *rc);

#endif // _VIDEO_CONFIG_H_
11 changes: 4 additions & 7 deletions Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp
Expand Up @@ -181,15 +181,12 @@ XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, un

void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc)
{
const float scaleX = Renderer::GetXFBScaleX();
const float scaleY = Renderer::GetXFBScaleY();

TargetRectangle targetSource;

targetSource.top = (int)(sourceRc.top *scaleY);
targetSource.bottom = (int)(sourceRc.bottom *scaleY);
targetSource.left = (int)(sourceRc.left *scaleX);
targetSource.right = (int)(sourceRc.right * scaleX);
targetSource.top = ScaleToVirtualXfbHeight(sourceRc.top, Renderer::GetBackbufferHeight());
targetSource.bottom = ScaleToVirtualXfbHeight(sourceRc.bottom, Renderer::GetBackbufferHeight());
targetSource.left = ScaleToVirtualXfbWidth(sourceRc.left, Renderer::GetBackbufferWidth());
targetSource.right = ScaleToVirtualXfbWidth(sourceRc.right, Renderer::GetBackbufferWidth());

*width = targetSource.right - targetSource.left;
*height = targetSource.bottom - targetSource.top;
Expand Down
66 changes: 29 additions & 37 deletions Source/Plugins/Plugin_VideoDX11/Src/Render.cpp
Expand Up @@ -349,17 +349,14 @@ Renderer::Renderer()
s_backbuffer_width = D3D::GetBackBufferWidth();
s_backbuffer_height = D3D::GetBackBufferHeight();

s_XFB_width = MAX_XFB_WIDTH;
s_XFB_height = MAX_XFB_HEIGHT;
FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH);
FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT);

TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);

CalculateXYScale(dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);

s_LastAA = g_ActiveConfig.iMultisampleMode;
s_LastEFBScale = g_ActiveConfig.iEFBScale;
CalculateTargetSize();
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);

SetupDeviceObjects();

Expand Down Expand Up @@ -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.
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)
AVIDump::AddFrame(frame_data);
Expand All @@ -928,13 +925,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
ResetAPIState();

// Prepare to copy the XFBs to our backbuffer
TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);

int X = dst_rect.left;
int Y = dst_rect.top;
int Width = dst_rect.right - dst_rect.left;
int Height = dst_rect.bottom - dst_rect.top;
int X = GetTargetRectangle().left;
int Y = GetTargetRectangle().top;
int Width = GetTargetRectangle().right - GetTargetRectangle().left;
int Height = GetTargetRectangle().bottom - GetTargetRectangle().top;

// TODO: Redundant checks...
if (X < 0) X = 0;
Expand Down Expand Up @@ -978,7 +974,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons

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
int xfbHeight = xfbSource->srcHeight;
Expand All @@ -999,13 +1002,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
//drawRc.left *= hScale;
//drawRc.right *= hScale;
}
else
{
drawRc.top = 1;
drawRc.bottom = -1;
drawRc.left = -1;
drawRc.right = 1;
}

xfbSource->Draw(sourceRc, drawRc, 0, 0);
}
Expand All @@ -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
if (s_bScreenshot)
{
SaveScreenshot(s_sScreenshotName, dst_rect);
SaveScreenshot(s_sScreenshotName, GetTargetRectangle());
s_bScreenshot = false;
}

Expand All @@ -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());
if (!bLastFrameDumped)
{
s_recordWidth = dst_rect.GetWidth();
s_recordHeight = dst_rect.GetHeight();
s_recordWidth = GetTargetRectangle().GetWidth();
s_recordHeight = GetTargetRectangle().GetHeight();
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
if (!bAVIDumping)
{
Expand All @@ -1066,7 +1062,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
w = s_recordWidth;
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);
AVIDump::AddFrame(frame_data);
D3D::context->Unmap(s_screenshot_texture, 0);
Expand Down Expand Up @@ -1142,15 +1138,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons

bool xfbchanged = false;

if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight)
{
xfbchanged = true;
s_XFB_width = fbWidth;
s_XFB_height = fbHeight;
if (s_XFB_width < 1) s_XFB_width = MAX_XFB_WIDTH;
if (s_XFB_width > MAX_XFB_WIDTH) s_XFB_width = MAX_XFB_WIDTH;
if (s_XFB_height < 1) s_XFB_height = MAX_XFB_HEIGHT;
if (s_XFB_height > MAX_XFB_HEIGHT) s_XFB_height = MAX_XFB_HEIGHT;
unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth;
unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight;
FramebufferManagerBase::SetLastXfbWidth(w);
FramebufferManagerBase::SetLastXfbHeight(h);
}

// update FPS counter
Expand Down Expand Up @@ -1183,12 +1177,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
s_backbuffer_height = D3D::GetBackBufferHeight();
}

ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);

CalculateXYScale(dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);

s_LastEFBScale = g_ActiveConfig.iEFBScale;
CalculateTargetSize();
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);

D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);

Expand Down
11 changes: 4 additions & 7 deletions Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp
Expand Up @@ -149,15 +149,12 @@ XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, un

void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc)
{
const float scaleX = Renderer::GetXFBScaleX();
const float scaleY = Renderer::GetXFBScaleY();

TargetRectangle targetSource;

targetSource.top = (int)(sourceRc.top *scaleY);
targetSource.bottom = (int)(sourceRc.bottom *scaleY);
targetSource.left = (int)(sourceRc.left *scaleX);
targetSource.right = (int)(sourceRc.right * scaleX);
targetSource.top = ScaleToVirtualXfbHeight(sourceRc.top, Renderer::GetBackbufferHeight());
targetSource.bottom = ScaleToVirtualXfbHeight(sourceRc.bottom, Renderer::GetBackbufferHeight());
targetSource.left = ScaleToVirtualXfbWidth(sourceRc.left, Renderer::GetBackbufferWidth());
targetSource.right = ScaleToVirtualXfbWidth(sourceRc.right, Renderer::GetBackbufferWidth());

*width = targetSource.right - targetSource.left;
*height = targetSource.bottom - targetSource.top;
Expand Down
70 changes: 31 additions & 39 deletions Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
Expand Up @@ -280,19 +280,16 @@ Renderer::Renderer()
s_backbuffer_width = D3D::GetBackBufferWidth();
s_backbuffer_height = D3D::GetBackBufferHeight();

s_XFB_width = MAX_XFB_WIDTH;
s_XFB_height = MAX_XFB_HEIGHT;
FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH);
FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT);

TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);

CalculateXYScale(dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);

s_LastAA = g_ActiveConfig.iMultisampleMode;
int SupersampleCoeficient = (s_LastAA % 3) + 1;

s_LastEFBScale = g_ActiveConfig.iEFBScale;
CalculateTargetSize(SupersampleCoeficient);
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient);

// Make sure to use valid texture sizes
D3D::FixTextureSize(s_target_width, s_target_height);
Expand Down Expand Up @@ -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.
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)
AVIDump::AddFrame(frame_data);
Expand Down Expand Up @@ -888,8 +885,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
D3D::dev->SetDepthStencilSurface(NULL);
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());

TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
D3DVIEWPORT9 vp;

// Clear full target screen (edges, borders etc)
Expand All @@ -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);
}

int X = dst_rect.left;
int Y = dst_rect.top;
int Width = dst_rect.right - dst_rect.left;
int Height = dst_rect.bottom - dst_rect.top;
int X = GetTargetRectangle().left;
int Y = GetTargetRectangle().top;
int Width = GetTargetRectangle().right - GetTargetRectangle().left;
int Height = GetTargetRectangle().bottom - GetTargetRectangle().top;

// Sanity check
if (X < 0) X = 0;
Expand Down Expand Up @@ -955,7 +951,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons

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
int xfbHeight = xfbSource->srcHeight;
Expand All @@ -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.
// scale draw area for a 1 to 1 pixel mapping with the draw target
//float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
//float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
//float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight();
//float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth();
//drawRc.top *= vScale;
//drawRc.bottom *= vScale;
//drawRc.left *= hScale;
//drawRc.right *= hScale;
}
else
{
drawRc.top = -1;
drawRc.bottom = 1;
drawRc.left = -1;
drawRc.right = 1;
}

xfbSource->Draw(sourceRc, drawRc, Width, Height);
}
Expand Down Expand Up @@ -1019,7 +1015,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (s_bScreenshot)
{
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
SaveScreenshot(s_sScreenshotName, dst_rect);
SaveScreenshot(s_sScreenshotName, GetTargetRectangle());
s_bScreenshot = false;
}

Expand All @@ -1033,8 +1029,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
if (!bLastFrameDumped)
{
s_recordWidth = dst_rect.GetWidth();
s_recordHeight = dst_rect.GetHeight();
s_recordWidth = GetTargetRectangle().GetWidth();
s_recordHeight = GetTargetRectangle().GetHeight();
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
if (!bAVIDumping)
{
Expand All @@ -1051,7 +1047,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (bAVIDumping)
{
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)
{
Expand Down Expand Up @@ -1138,15 +1134,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons

bool xfbchanged = false;

if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight)
{
xfbchanged = true;
s_XFB_width = fbWidth;
s_XFB_height = fbHeight;
if (s_XFB_width < 1) s_XFB_width = MAX_XFB_WIDTH;
if (s_XFB_width > MAX_XFB_WIDTH) s_XFB_width = MAX_XFB_WIDTH;
if (s_XFB_height < 1) s_XFB_height = MAX_XFB_HEIGHT;
if (s_XFB_height > MAX_XFB_HEIGHT) s_XFB_height = MAX_XFB_HEIGHT;
unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth;
unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight;
FramebufferManagerBase::SetLastXfbWidth(w);
FramebufferManagerBase::SetLastXfbHeight(h);
}

u32 newAA = g_ActiveConfig.iMultisampleMode;
Expand All @@ -1155,14 +1149,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
{
s_LastAA = newAA;

ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);

CalculateXYScale(dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);

int SupersampleCoeficient = (s_LastAA % 3) + 1;

s_LastEFBScale = g_ActiveConfig.iEFBScale;
CalculateTargetSize(SupersampleCoeficient);
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient);

D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
Expand Down
84 changes: 41 additions & 43 deletions Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
Expand Up @@ -363,16 +363,14 @@ Renderer::Renderer()
if (!GLEW_ARB_texture_non_power_of_two)
WARN_LOG(VIDEO, "ARB_texture_non_power_of_two not supported.");

s_XFB_width = MAX_XFB_WIDTH;
s_XFB_height = MAX_XFB_HEIGHT;
// TODO: Move these somewhere else?
FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH);
FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT);

TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);

CalculateXYScale(dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);

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
// options while running
Expand Down Expand Up @@ -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)
{
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)
{
Expand All @@ -1017,7 +1015,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0;
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)
{
Expand All @@ -1033,8 +1031,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons

ResetAPIState();

TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
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

Expand All @@ -1043,7 +1046,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
OGL::TextureCache::DisableStage(i);

// 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();

Expand Down Expand Up @@ -1074,7 +1077,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons

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
int xfbHeight = xfbSource->srcHeight;
Expand All @@ -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.
// scale draw area for a 1 to 1 pixel mapping with the draw target
//float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
//float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
//float vScale = (float)fbHeight / (float)flipped_trc.GetHeight();
//float hScale = (float)fbWidth / (float)flipped_trc.GetWidth();
//drawRc.top *= vScale;
//drawRc.bottom *= vScale;
//drawRc.left *= 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
OSDInternalW = xfbSource->sourceRc.GetWidth(); OSDInternalH = xfbSource->sourceRc.GetHeight();

Expand Down Expand Up @@ -1174,7 +1176,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (s_bScreenshot)
{
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
SaveScreenshot(s_sScreenshotName, dst_rect);
SaveScreenshot(s_sScreenshotName, flipped_trc);
// Reset settings
s_sScreenshotName.clear();
s_bScreenshot = false;
Expand All @@ -1185,16 +1187,16 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (g_ActiveConfig.bDumpFrames)
{
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
if (!frame_data || w != dst_rect.GetWidth() ||
h != dst_rect.GetHeight())
if (!frame_data || w != flipped_trc.GetWidth() ||
h != flipped_trc.GetHeight())
{
if (frame_data) delete[] frame_data;
w = dst_rect.GetWidth();
h = dst_rect.GetHeight();
w = flipped_trc.GetWidth();
h = flipped_trc.GetHeight();
frame_data = new char[3 * w * h];
}
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 (!bLastFrameDumped)
Expand Down Expand Up @@ -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::string movie_file_name;
w = dst_rect.GetWidth();
h = dst_rect.GetHeight();
w = GetTargetRectangle().GetWidth();
h = GetTargetRectangle().GetHeight();
frame_data = new char[3 * w * h];
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 (!bLastFrameDumped)
Expand Down Expand Up @@ -1296,15 +1298,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons

bool xfbchanged = false;

if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight)
{
xfbchanged = true;
s_XFB_width = fbWidth;
s_XFB_height = fbHeight;
if (s_XFB_width < 1) s_XFB_width = MAX_XFB_WIDTH;
if (s_XFB_width > MAX_XFB_WIDTH) s_XFB_width = MAX_XFB_WIDTH;
if (s_XFB_height < 1) s_XFB_height = MAX_XFB_HEIGHT;
if (s_XFB_height > MAX_XFB_HEIGHT) s_XFB_height = MAX_XFB_HEIGHT;
unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth;
unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight;
FramebufferManagerBase::SetLastXfbWidth(w);
FramebufferManagerBase::SetLastXfbHeight(h);
}

bool WindowResized = false;
Expand All @@ -1320,11 +1320,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons

if (xfbchanged || WindowResized || (s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode))
{
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);

CalculateXYScale(dst_rect);
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);

if (CalculateTargetSize() || (s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode))
if (CalculateTargetSize(s_backbuffer_width, s_backbuffer_height) || s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode)
{
s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode;
s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode);
Expand Down