VideoCommon: Use integer arithmetic instead of floating point arithmetic when dealing with EFB scales.

Should fix problems caused by EFB scales other than Native (excluding fractional!). Test whether this fixes games which work fine with native EFB resolution but show glitches with higher internal resolutions.

Also fixed numerous warnings.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6549 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
NeoBrainX 2010-12-10 15:54:14 +00:00
parent 1e0b0bf84d
commit 7473a0cf98
12 changed files with 164 additions and 209 deletions

View File

@ -65,10 +65,6 @@ int Renderer::s_Fulltarget_height;
int Renderer::s_backbuffer_width; int Renderer::s_backbuffer_width;
int Renderer::s_backbuffer_height; int Renderer::s_backbuffer_height;
// Internal resolution scale (related to xScale/yScale for "Auto" scaling)
float Renderer::EFBxScale;
float Renderer::EFByScale;
// ratio of backbuffer size and render area size // ratio of backbuffer size and render area size
float Renderer::xScale; float Renderer::xScale;
float Renderer::yScale; float Renderer::yScale;
@ -116,47 +112,43 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
} }
// return true if target size changed // return true if target size changed
bool Renderer::CalculateTargetSize(float multiplier) bool Renderer::CalculateTargetSize(int multiplier)
{ {
int newEFBWidth, newEFBHeight;
switch (s_LastEFBScale) switch (s_LastEFBScale)
{ {
case 0: case 0:
EFBxScale = xScale; newEFBWidth = (int)(EFB_WIDTH * xScale);
EFByScale = yScale; newEFBHeight = (int)(EFB_HEIGHT * yScale);
break; break;
case 1: case 1:
EFBxScale = ceilf(xScale); newEFBWidth = EFB_WIDTH * (int)ceilf(xScale);
EFByScale = ceilf(yScale); newEFBHeight = EFB_HEIGHT * (int)ceilf(yScale);
break; break;
default: default:
EFBxScale = EFByScale = (float)(g_ActiveConfig.iEFBScale - 1); newEFBWidth = EFB_WIDTH * (g_ActiveConfig.iEFBScale - 1);
newEFBHeight = EFB_HEIGHT * (g_ActiveConfig.iEFBScale - 1);
break; break;
}; };
EFBxScale *= multiplier; newEFBWidth *= multiplier;
EFByScale *= multiplier; newEFBHeight *= multiplier;
const int m_newFrameBufferWidth = (int)(EFB_WIDTH * EFBxScale); if (newEFBWidth != s_target_width || newEFBHeight != s_target_height)
const int m_newFrameBufferHeight = (int)(EFB_HEIGHT * EFByScale);
if (m_newFrameBufferWidth != s_target_width ||
m_newFrameBufferHeight != s_target_height)
{ {
s_Fulltarget_width = s_target_width = m_newFrameBufferWidth; s_Fulltarget_width = s_target_width = newEFBWidth;
s_Fulltarget_height = s_target_height = m_newFrameBufferHeight; s_Fulltarget_height = s_target_height = newEFBHeight;
return true; return true;
} }
return false; return false;
} }
void Renderer::SetScreenshot(const char *filename) void Renderer::SetScreenshot(const char *filename)
{ {
s_criticalScreenshot.Enter(); s_criticalScreenshot.Enter();
s_sScreenshotName = filename; s_sScreenshotName = filename;
s_bScreenshot = true; s_bScreenshot = true;
s_criticalScreenshot.Leave(); s_criticalScreenshot.Leave();
} }
// Create On-Screen-Messages // Create On-Screen-Messages

View File

@ -40,7 +40,7 @@
// TODO: Move these out of here. // TODO: Move these out of here.
extern int frameCount; extern int frameCount;
extern int OSDChoice, OSDTime, OSDInternalW, OSDInternalH; extern int OSDChoice, OSDTime;
extern bool s_bLastFrameDumped; extern bool s_bLastFrameDumped;
extern SVideoInitialize g_VideoInitialize; extern SVideoInitialize g_VideoInitialize;
@ -66,25 +66,43 @@ public:
virtual void SetSamplerState(int stage,int texindex) = 0; virtual void SetSamplerState(int stage,int texindex) = 0;
virtual void SetInterlacingMode() = 0; virtual void SetInterlacingMode() = 0;
// Return the rendering target width and height // Real internal resolution:
static int GetTargetWidth() { return s_target_width; } // D3D doesn't support viewports larger than the target size, so we need to resize the target to the viewport size for those.
static int GetTargetHeight() { return s_target_height; } // OpenGL supports this, so GetFullTargetWidth returns the same as GetTargetWidth there.
static int GetFullTargetWidth() { return s_Fulltarget_width; } static int GetFullTargetWidth() { return s_Fulltarget_width; }
static int GetFullTargetHeight() { return s_Fulltarget_height; } static int GetFullTargetHeight() { return s_Fulltarget_height; }
// Multiply any 2D EFB coordinates by these when rendering. // Ideal internal resolution - determined by display resolution (automatic scaling) and/or a multiple of the native EFB resolution
static float GetTargetScaleX() { return EFBxScale; } static int GetTargetWidth() { return s_target_width; }
static float GetTargetScaleY() { return EFByScale; } static int GetTargetHeight() { return s_target_height; }
static float GetXFBScaleX() { return xScale; }
static float GetXFBScaleY() { return yScale; }
// Display resolution
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; }
// EFB coordinate conversion functions
// 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;
// Use this to upscale native EFB coordinates to IDEAL internal resolution
static int EFBToScaledX(int x) { return x * GetTargetWidth() / EFB_WIDTH; }
static int EFBToScaledY(int y) { return y * GetTargetHeight() / EFB_HEIGHT; }
// 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 EFBToScaledYf(float y) { return y * (float)GetTargetHeight() / (float)EFB_HEIGHT; }
// Returns the offset at which the EFB will be drawn onto the backbuffer
// NOTE: Never calculate this manually (e.g. to "increase accuracy"), since you might end up getting off-by-one errors.
// This is a per-frame constant, so it won't cause any issues.
static int TargetStrideX() { return (s_Fulltarget_width - s_target_width) / 2; }
static int TargetStrideY() { return (s_Fulltarget_height - s_target_height) / 2; }
// Random utilities // Random utilities
static void SetScreenshot(const char *filename); static void SetScreenshot(const char *filename);
static void DrawDebugText(); static void DrawDebugText();
@ -112,7 +130,7 @@ protected:
static Common::CriticalSection s_criticalScreenshot; static Common::CriticalSection s_criticalScreenshot;
static std::string s_sScreenshotName; static std::string s_sScreenshotName;
static bool CalculateTargetSize(float multiplier = 1); static bool CalculateTargetSize(int multiplier = 1);
static void CalculateXYScale(const TargetRectangle& dst_rect); static void CalculateXYScale(const TargetRectangle& dst_rect);
static volatile bool s_bScreenshot; static volatile bool s_bScreenshot;
@ -129,11 +147,7 @@ protected:
static int s_backbuffer_width; static int s_backbuffer_width;
static int s_backbuffer_height; static int s_backbuffer_height;
// Internal resolution scale (related to xScale/yScale for "Auto" scaling) // ratio of backbuffer size and render area size - TODO: Remove these!
static float EFBxScale;
static float EFByScale;
// ratio of backbuffer size and render area size
static float xScale; static float xScale;
static float yScale; static float yScale;
@ -157,10 +171,10 @@ void GetScissorRect(MathUtil::Rectangle<R> &rect)
const int xoff = bpmem.scissorOffset.x * 2 - 342; const int xoff = bpmem.scissorOffset.x * 2 - 342;
const int yoff = bpmem.scissorOffset.y * 2 - 342; const int yoff = bpmem.scissorOffset.y * 2 - 342;
rect.left = (R)((float)bpmem.scissorTL.x - xoff - 342); rect.left = (R)(bpmem.scissorTL.x - xoff - 342);
rect.top = (R)((float)bpmem.scissorTL.y - yoff - 342); rect.top = (R)(bpmem.scissorTL.y - yoff - 342);
rect.right = (R)((float)bpmem.scissorBR.x - xoff - 341); rect.right = (R)(bpmem.scissorBR.x - xoff - 341);
rect.bottom = (R)((float)bpmem.scissorBR.y - yoff - 341); rect.bottom = (R)(bpmem.scissorBR.y - yoff - 341);
} }
#endif // _COMMON_RENDERBASE_H_ #endif // _COMMON_RENDERBASE_H_

View File

@ -617,11 +617,8 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
const unsigned int tex_w = (abs(source_rect.GetWidth()) >> (int)bScaleByHalf); const unsigned int tex_w = (abs(source_rect.GetWidth()) >> (int)bScaleByHalf);
const unsigned int tex_h = (abs(source_rect.GetHeight()) >> (int)bScaleByHalf); const unsigned int tex_h = (abs(source_rect.GetHeight()) >> (int)bScaleByHalf);
const float xScale = Renderer::GetTargetScaleX(); unsigned int scaled_tex_w = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledX(tex_w) : tex_w;
const float yScale = Renderer::GetTargetScaleY(); unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
unsigned int scaled_tex_w = g_ActiveConfig.bCopyEFBScaled ? (int)(tex_w * xScale) : tex_w;
unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? (int)(tex_h * yScale) : tex_h;
bool texture_is_dynamic = false; bool texture_is_dynamic = false;

View File

@ -371,13 +371,11 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color)
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
{ {
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
TargetRectangle result; TargetRectangle result;
result.left = (int)(rc.left * EFBxScale) + Xstride; result.left = EFBToScaledX(rc.left) + TargetStrideX();
result.top = (int)(rc.top * EFByScale) + Ystride; result.top = EFBToScaledY(rc.top) + TargetStrideY();
result.right = (int)(rc.right * EFBxScale) + Xstride; result.right = EFBToScaledX(rc.right) + TargetStrideX();
result.bottom = (int)(rc.bottom * EFByScale) + Ystride; result.bottom = EFBToScaledY(rc.bottom) + TargetStrideY();
return result; return result;
} }
@ -419,30 +417,20 @@ bool Renderer::SetScissorRect()
TargetRectangle rc; TargetRectangle rc;
GetScissorRect(rc); GetScissorRect(rc);
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
rc.left = (int)(rc.left * EFBxScale);
rc.top = (int)(rc.top * EFByScale);
rc.right = (int)(rc.right * EFBxScale);
rc.bottom = (int)(rc.bottom * EFByScale);
if (rc.left < 0) rc.left = 0; if (rc.left < 0) rc.left = 0;
if (rc.right < 0) rc.right = 0; if (rc.right < 0) rc.right = 0;
if (rc.left > s_target_width) rc.left = s_target_width;
if (rc.right > s_target_width) rc.right = s_target_width;
if (rc.top < 0) rc.top = 0; if (rc.top < 0) rc.top = 0;
if (rc.bottom < 0) rc.bottom = 0; if (rc.bottom < 0) rc.bottom = 0;
if (rc.top > s_target_height) rc.top = s_target_height; if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH;
if (rc.bottom > s_target_height) rc.bottom = s_target_height; if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT;
if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
rc.left += Xstride; rc.left = EFBToScaledX(rc.left) + TargetStrideX();
rc.top += Ystride; rc.right = EFBToScaledX(rc.right) + TargetStrideX();
rc.right += Xstride; rc.top = EFBToScaledY(rc.top) + TargetStrideY();
rc.bottom += Ystride; rc.bottom = EFBToScaledY(rc.bottom) + TargetStrideY();
if (rc.left > rc.right) if (rc.left > rc.right)
{ {
@ -465,11 +453,11 @@ bool Renderer::SetScissorRect()
else else
{ {
//WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom); //WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
*rc.AsRECT() = CD3D11_RECT(Xstride, Ystride, Xstride + s_target_width, Ystride + s_target_height); *rc.AsRECT() = CD3D11_RECT(TargetStrideX(), TargetStrideY(),
TargetStrideX() + s_target_width, TargetStrideY() + s_target_height);
D3D::context->RSSetScissorRects(1, rc.AsRECT()); D3D::context->RSSetScissorRects(1, rc.AsRECT());
return false; return false;
} }
return false;
} }
void Renderer::SetColorMask() void Renderer::SetColorMask()
@ -624,21 +612,19 @@ void Renderer::UpdateViewport()
const int old_fulltarget_w = Renderer::GetFullTargetWidth(); const int old_fulltarget_w = Renderer::GetFullTargetWidth();
const int old_fulltarget_h = Renderer::GetFullTargetHeight(); const int old_fulltarget_h = Renderer::GetFullTargetHeight();
int scissorXOff = bpmem.scissorOffset.x * 2; int scissorXOff = bpmem.scissorOffset.x << 1;
int scissorYOff = bpmem.scissorOffset.y * 2; int scissorYOff = bpmem.scissorOffset.y << 1;
int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2; // TODO: ceil, floor or just cast to int?
int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2; // TODO: Directly use the floats instead of rounding them?
int X = Renderer::EFBToScaledX((int)ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - scissorXOff)) + Renderer::TargetStrideX();
// Stretch picture with increased internal resolution int Y = Renderer::EFBToScaledY((int)ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - scissorYOff)) + Renderer::TargetStrideY();
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * Renderer::GetTargetScaleX()) + Xstride; int Width = Renderer::EFBToScaledX((int)ceil(2.0f * xfregs.rawViewport[0]));
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride; int Height = Renderer::EFBToScaledY((int)ceil(-2.0f * xfregs.rawViewport[1]));
int Width = (int)ceil((int)(2 * xfregs.rawViewport[0]) * Renderer::GetTargetScaleX());
int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * Renderer::GetTargetScaleY());
if (Width < 0) if (Width < 0)
{ {
X += Width; X += Width;
Width*=-1; Width *= -1;
} }
if (Height < 0) if (Height < 0)
{ {
@ -650,7 +636,7 @@ void Renderer::UpdateViewport()
{ {
s_Fulltarget_width -= 2 * X; s_Fulltarget_width -= 2 * X;
X = 0; X = 0;
sizeChanged=true; sizeChanged = true;
} }
if (Y < 0) if (Y < 0)
{ {
@ -844,8 +830,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
sourceRc.left = 0; sourceRc.left = 0;
sourceRc.top = 0; sourceRc.top = 0;
sourceRc.right = xfbSource->texWidth; sourceRc.right = (float)xfbSource->texWidth;
sourceRc.bottom = xfbSource->texHeight; sourceRc.bottom = (float)xfbSource->texHeight;
MathUtil::Rectangle<float> drawRc; MathUtil::Rectangle<float> drawRc;

View File

@ -285,7 +285,7 @@ Renderer::Renderer()
CalculateXYScale(dst_rect); CalculateXYScale(dst_rect);
s_LastAA = g_ActiveConfig.iMultisampleMode; s_LastAA = g_ActiveConfig.iMultisampleMode;
float SupersampleCoeficient = s_LastAA + 1; int SupersampleCoeficient = s_LastAA + 1;
s_LastEFBScale = g_ActiveConfig.iEFBScale; s_LastEFBScale = g_ActiveConfig.iEFBScale;
CalculateTargetSize(SupersampleCoeficient); CalculateTargetSize(SupersampleCoeficient);
@ -350,12 +350,10 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color)
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
{ {
TargetRectangle result; TargetRectangle result;
int Xstride = (s_Fulltarget_width - s_target_width) / 2; result.left = EFBToScaledX(rc.left) + TargetStrideX();
int Ystride = (s_Fulltarget_height - s_target_height) / 2; result.top = EFBToScaledY(rc.top) + TargetStrideY();
result.left = (int)(rc.left * EFBxScale) + Xstride; result.right = EFBToScaledX(rc.right) + TargetStrideX();
result.top = (int)(rc.top * EFByScale) + Ystride; result.bottom = EFBToScaledY(rc.bottom) + TargetStrideY();
result.right = (int)(rc.right * EFBxScale) + Xstride;
result.bottom = (int)(rc.bottom * EFByScale) + Ystride;
return result; return result;
} }
@ -429,13 +427,11 @@ bool Renderer::SetScissorRect()
if (rc.left < 0) rc.left = 0; if (rc.left < 0) rc.left = 0;
if (rc.right < 0) rc.right = 0; if (rc.right < 0) rc.right = 0;
if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH;
if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
if (rc.top < 0) rc.top = 0; if (rc.top < 0) rc.top = 0;
if (rc.bottom < 0) rc.bottom = 0; if (rc.bottom < 0) rc.bottom = 0;
if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH;
if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT; if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT;
if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT; if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
@ -452,13 +448,10 @@ bool Renderer::SetScissorRect()
rc.top = temp; rc.top = temp;
} }
int Xstride = (s_Fulltarget_width - s_target_width) / 2; rc.left = EFBToScaledX(rc.left) + TargetStrideX();
int Ystride = (s_Fulltarget_height - s_target_height) / 2; rc.top = EFBToScaledY(rc.top) + TargetStrideY();
rc.right = EFBToScaledX(rc.right) + TargetStrideX();
rc.left = (int)(rc.left * EFBxScale) + Xstride; rc.bottom = EFBToScaledY(rc.bottom) + TargetStrideY();
rc.top = (int)(rc.top * EFByScale) + Ystride;
rc.right = (int)(rc.right * EFBxScale) + Xstride;
rc.bottom = (int)(rc.bottom * EFByScale) + Ystride;
// Check that the coordinates are good // Check that the coordinates are good
if (rc.right != rc.left && rc.bottom != rc.top) if (rc.right != rc.left && rc.bottom != rc.top)
@ -469,10 +462,10 @@ bool Renderer::SetScissorRect()
else else
{ {
//WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom); //WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
rc.left = Xstride; rc.left = TargetStrideX();
rc.top = Ystride; rc.top = TargetStrideY();
rc.right = Xstride + s_target_width; rc.right = TargetStrideX() + s_target_width;
rc.bottom = Ystride + s_target_height; rc.bottom = TargetStrideY() + s_target_height;
D3D::dev->SetScissorRect(rc.AsRECT()); D3D::dev->SetScissorRect(rc.AsRECT());
} }
return false; return false;
@ -696,17 +689,17 @@ void Renderer::UpdateViewport()
const int old_fulltarget_w = Renderer::GetFullTargetWidth(); const int old_fulltarget_w = Renderer::GetFullTargetWidth();
const int old_fulltarget_h = Renderer::GetFullTargetHeight(); const int old_fulltarget_h = Renderer::GetFullTargetHeight();
int scissorXOff = bpmem.scissorOffset.x * 2; int scissorXOff = bpmem.scissorOffset.x << 1;
int scissorYOff = bpmem.scissorOffset.y * 2; int scissorYOff = bpmem.scissorOffset.y << 1;
int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2; int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2;
int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2; int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2;
// Stretch picture with increased internal resolution // TODO: ceil, floor or just cast to int?
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * Renderer::GetTargetScaleX()) + Xstride; int X = EFBToScaledX((int)ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - scissorXOff)) + TargetStrideX();
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride; int Y = EFBToScaledY((int)ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - scissorYOff)) + TargetStrideY();
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX()); int Width = EFBToScaledX((int)ceil(2.0f * xfregs.rawViewport[0]));
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY()); int Height = EFBToScaledY((int)ceil(-2.0f * xfregs.rawViewport[1]));
if (Width < 0) if (Width < 0)
{ {
X += Width; X += Width;
@ -796,7 +789,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
if (zEnable) // other depth functions don't make sense here if (zEnable) // other depth functions don't make sense here
D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
// Update the view port for clearing the whole EFB texture // Update the viewport for clearing the target EFB rect
TargetRectangle targetRc = ConvertEFBRectangle(rc); TargetRectangle targetRc = ConvertEFBRectangle(rc);
D3DVIEWPORT9 vp; D3DVIEWPORT9 vp;
vp.X = targetRc.left; vp.X = targetRc.left;
@ -883,7 +876,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN); D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN);
VertexShaderManager::ResetView(); VertexShaderManager::ResetView();
VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iAnaglyphStereoSeparation,0.0f);
VertexShaderManager::RotateView(-0.0001 *g_ActiveConfig.iAnaglyphFocalAngle,0.0f); VertexShaderManager::RotateView(-0.0001f *g_ActiveConfig.iAnaglyphFocalAngle,0.0f);
RightFrame = false; RightFrame = false;
} }
else else
@ -891,7 +884,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED); D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
VertexShaderManager::ResetView(); VertexShaderManager::ResetView();
VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iAnaglyphStereoSeparation,0.0f);
VertexShaderManager::RotateView(0.0001 * g_ActiveConfig.iAnaglyphFocalAngle,0.0f); VertexShaderManager::RotateView(0.0001f * g_ActiveConfig.iAnaglyphFocalAngle,0.0f);
RightFrame = true; RightFrame = true;
} }
} }
@ -926,7 +919,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
int Width = dst_rect.right - dst_rect.left; int Width = dst_rect.right - dst_rect.left;
int Height = dst_rect.bottom - dst_rect.top; int Height = dst_rect.bottom - dst_rect.top;
// Sanity check // Sanity check
if (X < 0) X = 0; if (X < 0) X = 0;
if (Y < 0) Y = 0; if (Y < 0) Y = 0;
if (X > s_backbuffer_width) X = s_backbuffer_width; if (X > s_backbuffer_width) X = s_backbuffer_width;
@ -962,8 +955,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
sourceRc.left = 0; sourceRc.left = 0;
sourceRc.top = 0; sourceRc.top = 0;
sourceRc.right = xfbSource->texWidth; sourceRc.right = (float)xfbSource->texWidth;
sourceRc.bottom = xfbSource->texHeight; sourceRc.bottom = (float)xfbSource->texHeight;
MathUtil::Rectangle<float> drawRc; MathUtil::Rectangle<float> drawRc;
@ -1130,7 +1123,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
CalculateXYScale(dst_rect); CalculateXYScale(dst_rect);
float SupersampleCoeficient = s_LastAA + 1; int SupersampleCoeficient = s_LastAA + 1;
s_LastEFBScale = g_ActiveConfig.iEFBScale; s_LastEFBScale = g_ActiveConfig.iEFBScale;
CalculateTargetSize(SupersampleCoeficient); CalculateTargetSize(SupersampleCoeficient);

View File

@ -149,10 +149,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
read_texture, read_texture,
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetWidth(),
Renderer::GetFullTargetHeight(), Renderer::GetFullTargetHeight(),
Renderer::GetTargetScaleX(),
Renderer::GetTargetScaleY(),
(float)((Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2),
(float)((Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2) ,
bFromZBuffer, bFromZBuffer,
bIsIntensityFmt, bIsIntensityFmt,
copyfmt, copyfmt,

View File

@ -344,21 +344,15 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
s32 expandedWidth = (width + blkW) & (~blkW); s32 expandedWidth = (width + blkW) & (~blkW);
s32 expandedHeight = (height + blkH) & (~blkH); s32 expandedHeight = (height + blkH) & (~blkH);
float MValueX = Renderer::GetTargetScaleX(); float sampleStride = bScaleByHalf ? 2.f : 1.f;
float MValueY = Renderer::GetTargetScaleY(); // TODO: sampleStride scaling might be slightly off
float Xstride = (float)((Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2);
float Ystride = (float)((Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2);
float sampleStride = bScaleByHalf?2.0f:1.0f;
TextureConversionShader::SetShaderParameters( TextureConversionShader::SetShaderParameters(
(float)expandedWidth, (float)expandedWidth,
expandedHeight * MValueY, (float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this?
source.left * MValueX + Xstride , (float)(Renderer::EFBToScaledX(source.left) + Renderer::TargetStrideX()),
source.top * MValueY + Ystride, (float)(Renderer::EFBToScaledY(source.top) + Renderer::TargetStrideY()),
sampleStride * MValueX, Renderer::EFBToScaledXf(sampleStride),
sampleStride * MValueY, Renderer::EFBToScaledYf(sampleStride),
(float)Renderer::GetFullTargetWidth(), (float)Renderer::GetFullTargetWidth(),
(float)Renderer::GetFullTargetHeight()); (float)Renderer::GetFullTargetHeight());
@ -379,7 +373,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
g_renderer->RestoreAPIState(); g_renderer->RestoreAPIState();
} }
u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 SourceW, u32 SourceH,float MValueX,float MValueY,float Xstride, float Ystride , bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
{ {
u32 format = copyfmt; u32 format = copyfmt;
@ -415,15 +409,15 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou
s32 expandedWidth = (width + blkW) & (~blkW); s32 expandedWidth = (width + blkW) & (~blkW);
s32 expandedHeight = (height + blkH) & (~blkH); s32 expandedHeight = (height + blkH) & (~blkH);
float sampleStride = bScaleByHalf?2.0f:1.0f; float sampleStride = bScaleByHalf ? 2.f : 1.f;
// TODO: sampleStride scaling might be slightly off
TextureConversionShader::SetShaderParameters( TextureConversionShader::SetShaderParameters(
(float)expandedWidth, (float)expandedWidth,
expandedHeight * MValueY, (float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this?
source.left * MValueX + Xstride , (float)(Renderer::EFBToScaledX(source.left) + Renderer::TargetStrideX()),
source.top * MValueY + Ystride, (float)(Renderer::EFBToScaledY(source.top) + Renderer::TargetStrideY()),
sampleStride * MValueX, Renderer::EFBToScaledXf(sampleStride),
sampleStride * MValueY, Renderer::EFBToScaledYf(sampleStride),
(float)SourceW, (float)SourceW,
(float)SourceH); (float)SourceH);

View File

@ -40,7 +40,7 @@ void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourc
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture); void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture);
u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 SourceW, u32 SourceH,float MValueX,float MValueY,float Xstride, float Ystride , bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source); u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
} }

View File

@ -593,12 +593,10 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color)
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
{ {
TargetRectangle result; TargetRectangle result;
int Xstride = (s_Fulltarget_width - s_target_width) / 2; result.left = EFBToScaledX(rc.left) + TargetStrideX();
int Ystride = (s_Fulltarget_height - s_target_height) / 2; result.top = EFBToScaledY(EFB_HEIGHT - rc.top) + TargetStrideY();
result.left = (int)(rc.left * EFBxScale) + Xstride; result.right = EFBToScaledX(rc.right) - (TargetStrideX() * 2);
result.top = (int)((EFB_HEIGHT - rc.top) * EFByScale) + Ystride; result.bottom = EFBToScaledY(EFB_HEIGHT - rc.bottom) - (TargetStrideY() * 2);
result.right = (int)(rc.right * EFBxScale) - (Xstride * 2);
result.bottom = (int)((EFB_HEIGHT - rc.bottom) * EFByScale) - (Ystride * 2);
return result; return result;
} }
@ -618,11 +616,8 @@ bool Renderer::SetScissorRect()
GetScissorRect(rc); GetScissorRect(rc);
if (rc.left < 0) rc.left = 0; if (rc.left < 0) rc.left = 0;
if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
if (rc.top < 0) rc.top = 0; if (rc.top < 0) rc.top = 0;
if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT; if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
if (rc.left > rc.right) if (rc.left > rc.right)
@ -642,11 +637,10 @@ bool Renderer::SetScissorRect()
if (rc.right != rc.left && rc.bottom != rc.top) if (rc.right != rc.left && rc.bottom != rc.top)
{ {
glScissor( glScissor(
(int)(rc.left * EFBxScale), // x = 0 for example EFBToScaledX(rc.left), // x = 0 for example
(int)((EFB_HEIGHT - rc.bottom) * EFByScale), // y = 0 for example EFBToScaledY(EFB_HEIGHT - rc.bottom), // y = 0 for example
(int)((rc.right - rc.left)* EFBxScale), // width = 640 for example EFBToScaledX(rc.right - rc.left), // width = 640 for example
(int)((rc.bottom - rc.top) * EFByScale) // height = 480 for example EFBToScaledY(rc.bottom - rc.top)); // height = 480 for example
);
return true; return true;
} }
else else
@ -784,23 +778,23 @@ void Renderer::UpdateViewport()
// [4] = yorig + height/2 + 342 // [4] = yorig + height/2 + 342
// [5] = 16777215 * farz // [5] = 16777215 * farz
int scissorXOff = bpmem.scissorOffset.x * 2; int scissorXOff = bpmem.scissorOffset.x << 1;
int scissorYOff = bpmem.scissorOffset.y * 2; int scissorYOff = bpmem.scissorOffset.y << 1;
// int Xstride = (s_Fulltarget_width - s_target_width) / 2; // int Xstride = (s_Fulltarget_width - s_target_width) / 2;
// int Ystride = (s_Fulltarget_height - s_target_height) / 2; // int Ystride = (s_Fulltarget_height - s_target_height) / 2;
// Stretch picture with increased internal resolution // TODO: ceil, floor or just cast to int?
int X = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - float(scissorXOff)) * Renderer::GetTargetScaleX()); int X = EFBToScaledX((int)ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (float)scissorXOff));
int Y = (int)ceil((float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + float(scissorYOff)) * Renderer::GetTargetScaleY()); int Y = EFBToScaledY((int)ceil((float)EFB_HEIGHT - xfregs.rawViewport[4] + xfregs.rawViewport[1] + (float)scissorYOff));
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX()); int Width = EFBToScaledX((int)ceil(2.0f * xfregs.rawViewport[0]));
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY()); int Height = EFBToScaledY((int)ceil(-2.0f * xfregs.rawViewport[1]));
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f; double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
double GLFar = xfregs.rawViewport[5] / 16777216.0f; double GLFar = xfregs.rawViewport[5] / 16777216.0f;
if (Width < 0) if (Width < 0)
{ {
X += Width; X += Width;
Width*=-1; Width *= -1;
} }
if (Height < 0) if (Height < 0)
{ {

View File

@ -276,10 +276,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
FramebufferManager::ResolveAndGetDepthTarget(source_rect) : FramebufferManager::ResolveAndGetDepthTarget(source_rect) :
FramebufferManager::ResolveAndGetRenderTarget(source_rect); FramebufferManager::ResolveAndGetRenderTarget(source_rect);
// TODO: move
const float xScale = Renderer::GetTargetScaleX();
const float yScale = Renderer::GetTargetScaleY();
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
if (false == isDynamic || g_ActiveConfig.bCopyEFBToTexture) if (false == isDynamic || g_ActiveConfig.bCopyEFBToTexture)
@ -325,8 +321,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
hash = TextureConverter::EncodeToRamFromTexture( hash = TextureConverter::EncodeToRamFromTexture(
addr, addr,
read_texture, read_texture,
xScale,
yScale,
bFromZBuffer, bFromZBuffer,
bIsIntensityFmt, bIsIntensityFmt,
copyfmt, copyfmt,

View File

@ -284,19 +284,14 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
s32 expandedWidth = (width + blkW) & (~blkW); s32 expandedWidth = (width + blkW) & (~blkW);
s32 expandedHeight = (height + blkH) & (~blkH); s32 expandedHeight = (height + blkH) & (~blkH);
float MValueX = Renderer::GetTargetScaleX(); float sampleStride = bScaleByHalf ? 2.f : 1.f;
float MValueY = Renderer::GetTargetScaleY(); // TODO: sampleStride scaling might be slightly off
TextureConversionShader::SetShaderParameters((float)expandedWidth,
float top = (EFB_HEIGHT - source.top - expandedHeight) * MValueY ; (float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this?
(float)Renderer::EFBToScaledX(source.left),
float sampleStride = bScaleByHalf?2.0f:1.0f; (float)Renderer::EFBToScaledY(EFB_HEIGHT - source.top - expandedHeight),
Renderer::EFBToScaledXf(sampleStride),
TextureConversionShader::SetShaderParameters((float)expandedWidth, Renderer::EFBToScaledYf(sampleStride));
expandedHeight * MValueY,
source.left * MValueX,
top,
sampleStride * MValueX,
sampleStride * MValueY);
TargetRectangle scaledSource; TargetRectangle scaledSource;
scaledSource.top = 0; scaledSource.top = 0;
@ -318,7 +313,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
} }
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) u64 EncodeToRamFromTexture(u32 address,GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
{ {
u32 format = copyfmt; u32 format = copyfmt;
@ -354,14 +349,14 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float
s32 expandedWidth = (width + blkW) & (~blkW); s32 expandedWidth = (width + blkW) & (~blkW);
s32 expandedHeight = (height + blkH) & (~blkH); s32 expandedHeight = (height + blkH) & (~blkH);
float sampleStride = bScaleByHalf?2.0f:1.0f; float sampleStride = bScaleByHalf ? 2.f : 1.f;
float top = (EFB_HEIGHT - source.top - expandedHeight) * MValueY ; // TODO: sampleStride scaling might be slightly off
TextureConversionShader::SetShaderParameters((float)expandedWidth, TextureConversionShader::SetShaderParameters((float)expandedWidth,
expandedHeight * MValueY, (float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this?
source.left * MValueX, (float)Renderer::EFBToScaledX(source.left),
top, (float)Renderer::EFBToScaledY(EFB_HEIGHT - source.top - expandedHeight),
sampleStride * MValueX, Renderer::EFBToScaledXf(sampleStride),
sampleStride * MValueY); Renderer::EFBToScaledYf(sampleStride));
TargetRectangle scaledSource; TargetRectangle scaledSource;
scaledSource.top = 0; scaledSource.top = 0;
@ -447,8 +442,8 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2f(srcFmtWidth, (float)srcHeight); glVertex2f(1,-1); glTexCoord2f((float)srcFmtWidth, (float)srcHeight); glVertex2f(1,-1);
glTexCoord2f(srcFmtWidth, 0); glVertex2f(1,1); glTexCoord2f((float)srcFmtWidth, 0); glVertex2f(1,1);
glTexCoord2f(0, 0); glVertex2f(-1,1); glTexCoord2f(0, 0); glVertex2f(-1,1);
glTexCoord2f(0, (float)srcHeight); glVertex2f(-1,-1); glTexCoord2f(0, (float)srcHeight); glVertex2f(-1,-1);
glEnd(); glEnd();

View File

@ -37,7 +37,7 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture); void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture);
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source); u64 EncodeToRamFromTexture(u32 address, GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
} }