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_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
float Renderer::xScale;
float Renderer::yScale;
@ -116,47 +112,43 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
}
// return true if target size changed
bool Renderer::CalculateTargetSize(float multiplier)
bool Renderer::CalculateTargetSize(int multiplier)
{
int newEFBWidth, newEFBHeight;
switch (s_LastEFBScale)
{
case 0:
EFBxScale = xScale;
EFByScale = yScale;
newEFBWidth = (int)(EFB_WIDTH * xScale);
newEFBHeight = (int)(EFB_HEIGHT * yScale);
break;
case 1:
EFBxScale = ceilf(xScale);
EFByScale = ceilf(yScale);
newEFBWidth = EFB_WIDTH * (int)ceilf(xScale);
newEFBHeight = EFB_HEIGHT * (int)ceilf(yScale);
break;
default:
EFBxScale = EFByScale = (float)(g_ActiveConfig.iEFBScale - 1);
newEFBWidth = EFB_WIDTH * (g_ActiveConfig.iEFBScale - 1);
newEFBHeight = EFB_HEIGHT * (g_ActiveConfig.iEFBScale - 1);
break;
};
EFBxScale *= multiplier;
EFByScale *= multiplier;
newEFBWidth *= multiplier;
newEFBHeight *= multiplier;
const int m_newFrameBufferWidth = (int)(EFB_WIDTH * EFBxScale);
const int m_newFrameBufferHeight = (int)(EFB_HEIGHT * EFByScale);
if (m_newFrameBufferWidth != s_target_width ||
m_newFrameBufferHeight != s_target_height)
if (newEFBWidth != s_target_width || newEFBHeight != s_target_height)
{
s_Fulltarget_width = s_target_width = m_newFrameBufferWidth;
s_Fulltarget_height = s_target_height = m_newFrameBufferHeight;
s_Fulltarget_width = s_target_width = newEFBWidth;
s_Fulltarget_height = s_target_height = newEFBHeight;
return true;
}
return false;
}
void Renderer::SetScreenshot(const char *filename)
{
s_criticalScreenshot.Enter();
s_sScreenshotName = filename;
s_bScreenshot = true;
s_criticalScreenshot.Leave();
s_criticalScreenshot.Enter();
s_sScreenshotName = filename;
s_bScreenshot = true;
s_criticalScreenshot.Leave();
}
// Create On-Screen-Messages

View File

@ -40,7 +40,7 @@
// TODO: Move these out of here.
extern int frameCount;
extern int OSDChoice, OSDTime, OSDInternalW, OSDInternalH;
extern int OSDChoice, OSDTime;
extern bool s_bLastFrameDumped;
extern SVideoInitialize g_VideoInitialize;
@ -66,25 +66,43 @@ public:
virtual void SetSamplerState(int stage,int texindex) = 0;
virtual void SetInterlacingMode() = 0;
// Return the rendering target width and height
static int GetTargetWidth() { return s_target_width; }
static int GetTargetHeight() { return s_target_height; }
// Real internal resolution:
// D3D doesn't support viewports larger than the target size, so we need to resize the target to the viewport size for those.
// OpenGL supports this, so GetFullTargetWidth returns the same as GetTargetWidth there.
static int GetFullTargetWidth() { return s_Fulltarget_width; }
static int GetFullTargetHeight() { return s_Fulltarget_height; }
// Multiply any 2D EFB coordinates by these when rendering.
static float GetTargetScaleX() { return EFBxScale; }
static float GetTargetScaleY() { return EFByScale; }
static float GetXFBScaleX() { return xScale; }
static float GetXFBScaleY() { return yScale; }
// Ideal internal resolution - determined by display resolution (automatic scaling) and/or a multiple of the native EFB resolution
static int GetTargetWidth() { return s_target_width; }
static int GetTargetHeight() { return s_target_height; }
// Display resolution
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; }
// EFB coordinate conversion functions
// Use this to convert a whole native EFB rect to backbuffer coordinates
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
static void SetScreenshot(const char *filename);
static void DrawDebugText();
@ -112,7 +130,7 @@ protected:
static Common::CriticalSection s_criticalScreenshot;
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 volatile bool s_bScreenshot;
@ -129,11 +147,7 @@ protected:
static int s_backbuffer_width;
static int s_backbuffer_height;
// Internal resolution scale (related to xScale/yScale for "Auto" scaling)
static float EFBxScale;
static float EFByScale;
// ratio of backbuffer size and render area size
// ratio of backbuffer size and render area size - TODO: Remove these!
static float xScale;
static float yScale;
@ -157,10 +171,10 @@ void GetScissorRect(MathUtil::Rectangle<R> &rect)
const int xoff = bpmem.scissorOffset.x * 2 - 342;
const int yoff = bpmem.scissorOffset.y * 2 - 342;
rect.left = (R)((float)bpmem.scissorTL.x - xoff - 342);
rect.top = (R)((float)bpmem.scissorTL.y - yoff - 342);
rect.right = (R)((float)bpmem.scissorBR.x - xoff - 341);
rect.bottom = (R)((float)bpmem.scissorBR.y - yoff - 341);
rect.left = (R)(bpmem.scissorTL.x - xoff - 342);
rect.top = (R)(bpmem.scissorTL.y - yoff - 342);
rect.right = (R)(bpmem.scissorBR.x - xoff - 341);
rect.bottom = (R)(bpmem.scissorBR.y - yoff - 341);
}
#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_h = (abs(source_rect.GetHeight()) >> (int)bScaleByHalf);
const float xScale = Renderer::GetTargetScaleX();
const float yScale = Renderer::GetTargetScaleY();
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;
unsigned int scaled_tex_w = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledX(tex_w) : tex_w;
unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
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)
{
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
TargetRectangle result;
result.left = (int)(rc.left * EFBxScale) + Xstride;
result.top = (int)(rc.top * EFByScale) + Ystride;
result.right = (int)(rc.right * EFBxScale) + Xstride;
result.bottom = (int)(rc.bottom * EFByScale) + Ystride;
result.left = EFBToScaledX(rc.left) + TargetStrideX();
result.top = EFBToScaledY(rc.top) + TargetStrideY();
result.right = EFBToScaledX(rc.right) + TargetStrideX();
result.bottom = EFBToScaledY(rc.bottom) + TargetStrideY();
return result;
}
@ -419,30 +417,20 @@ bool Renderer::SetScissorRect()
TargetRectangle 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.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.bottom < 0) rc.bottom = 0;
if (rc.top > s_target_height) rc.top = s_target_height;
if (rc.bottom > s_target_height) rc.bottom = s_target_height;
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.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
rc.left += Xstride;
rc.top += Ystride;
rc.right += Xstride;
rc.bottom += Ystride;
rc.left = EFBToScaledX(rc.left) + TargetStrideX();
rc.right = EFBToScaledX(rc.right) + TargetStrideX();
rc.top = EFBToScaledY(rc.top) + TargetStrideY();
rc.bottom = EFBToScaledY(rc.bottom) + TargetStrideY();
if (rc.left > rc.right)
{
@ -465,11 +453,11 @@ bool Renderer::SetScissorRect()
else
{
//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());
return false;
}
return false;
}
void Renderer::SetColorMask()
@ -624,21 +612,19 @@ void Renderer::UpdateViewport()
const int old_fulltarget_w = Renderer::GetFullTargetWidth();
const int old_fulltarget_h = Renderer::GetFullTargetHeight();
int scissorXOff = bpmem.scissorOffset.x * 2;
int scissorYOff = bpmem.scissorOffset.y * 2;
int scissorXOff = bpmem.scissorOffset.x << 1;
int scissorYOff = bpmem.scissorOffset.y << 1;
int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2;
int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2;
// Stretch picture with increased internal resolution
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * Renderer::GetTargetScaleX()) + Xstride;
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride;
int Width = (int)ceil((int)(2 * xfregs.rawViewport[0]) * Renderer::GetTargetScaleX());
int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * Renderer::GetTargetScaleY());
// TODO: ceil, floor or just cast to int?
// TODO: Directly use the floats instead of rounding them?
int X = Renderer::EFBToScaledX((int)ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - scissorXOff)) + Renderer::TargetStrideX();
int Y = Renderer::EFBToScaledY((int)ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - scissorYOff)) + Renderer::TargetStrideY();
int Width = Renderer::EFBToScaledX((int)ceil(2.0f * xfregs.rawViewport[0]));
int Height = Renderer::EFBToScaledY((int)ceil(-2.0f * xfregs.rawViewport[1]));
if (Width < 0)
{
X += Width;
Width*=-1;
Width *= -1;
}
if (Height < 0)
{
@ -650,7 +636,7 @@ void Renderer::UpdateViewport()
{
s_Fulltarget_width -= 2 * X;
X = 0;
sizeChanged=true;
sizeChanged = true;
}
if (Y < 0)
{
@ -844,8 +830,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
sourceRc.left = 0;
sourceRc.top = 0;
sourceRc.right = xfbSource->texWidth;
sourceRc.bottom = xfbSource->texHeight;
sourceRc.right = (float)xfbSource->texWidth;
sourceRc.bottom = (float)xfbSource->texHeight;
MathUtil::Rectangle<float> drawRc;

View File

@ -285,7 +285,7 @@ Renderer::Renderer()
CalculateXYScale(dst_rect);
s_LastAA = g_ActiveConfig.iMultisampleMode;
float SupersampleCoeficient = s_LastAA + 1;
int SupersampleCoeficient = s_LastAA + 1;
s_LastEFBScale = g_ActiveConfig.iEFBScale;
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 result;
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
result.left = (int)(rc.left * EFBxScale) + Xstride;
result.top = (int)(rc.top * EFByScale) + Ystride;
result.right = (int)(rc.right * EFBxScale) + Xstride;
result.bottom = (int)(rc.bottom * EFByScale) + Ystride;
result.left = EFBToScaledX(rc.left) + TargetStrideX();
result.top = EFBToScaledY(rc.top) + TargetStrideY();
result.right = EFBToScaledX(rc.right) + TargetStrideX();
result.bottom = EFBToScaledY(rc.bottom) + TargetStrideY();
return result;
}
@ -429,13 +427,11 @@ bool Renderer::SetScissorRect()
if (rc.left < 0) rc.left = 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.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.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
@ -452,13 +448,10 @@ bool Renderer::SetScissorRect()
rc.top = temp;
}
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
rc.left = (int)(rc.left * EFBxScale) + Xstride;
rc.top = (int)(rc.top * EFByScale) + Ystride;
rc.right = (int)(rc.right * EFBxScale) + Xstride;
rc.bottom = (int)(rc.bottom * EFByScale) + Ystride;
rc.left = EFBToScaledX(rc.left) + TargetStrideX();
rc.top = EFBToScaledY(rc.top) + TargetStrideY();
rc.right = EFBToScaledX(rc.right) + TargetStrideX();
rc.bottom = EFBToScaledY(rc.bottom) + TargetStrideY();
// Check that the coordinates are good
if (rc.right != rc.left && rc.bottom != rc.top)
@ -469,10 +462,10 @@ bool Renderer::SetScissorRect()
else
{
//WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
rc.left = Xstride;
rc.top = Ystride;
rc.right = Xstride + s_target_width;
rc.bottom = Ystride + s_target_height;
rc.left = TargetStrideX();
rc.top = TargetStrideY();
rc.right = TargetStrideX() + s_target_width;
rc.bottom = TargetStrideY() + s_target_height;
D3D::dev->SetScissorRect(rc.AsRECT());
}
return false;
@ -696,17 +689,17 @@ void Renderer::UpdateViewport()
const int old_fulltarget_w = Renderer::GetFullTargetWidth();
const int old_fulltarget_h = Renderer::GetFullTargetHeight();
int scissorXOff = bpmem.scissorOffset.x * 2;
int scissorYOff = bpmem.scissorOffset.y * 2;
int scissorXOff = bpmem.scissorOffset.x << 1;
int scissorYOff = bpmem.scissorOffset.y << 1;
int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2;
int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2;
// Stretch picture with increased internal resolution
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * Renderer::GetTargetScaleX()) + Xstride;
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride;
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX());
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY());
// TODO: ceil, floor or just cast to int?
int X = EFBToScaledX((int)ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - scissorXOff)) + TargetStrideX();
int Y = EFBToScaledY((int)ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - scissorYOff)) + TargetStrideY();
int Width = EFBToScaledX((int)ceil(2.0f * xfregs.rawViewport[0]));
int Height = EFBToScaledY((int)ceil(-2.0f * xfregs.rawViewport[1]));
if (Width < 0)
{
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
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);
D3DVIEWPORT9 vp;
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);
VertexShaderManager::ResetView();
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;
}
else
@ -891,7 +884,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
VertexShaderManager::ResetView();
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;
}
}
@ -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 Height = dst_rect.bottom - dst_rect.top;
// Sanity check
// Sanity check
if (X < 0) X = 0;
if (Y < 0) Y = 0;
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.top = 0;
sourceRc.right = xfbSource->texWidth;
sourceRc.bottom = xfbSource->texHeight;
sourceRc.right = (float)xfbSource->texWidth;
sourceRc.bottom = (float)xfbSource->texHeight;
MathUtil::Rectangle<float> drawRc;
@ -1130,7 +1123,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
CalculateXYScale(dst_rect);
float SupersampleCoeficient = s_LastAA + 1;
int SupersampleCoeficient = s_LastAA + 1;
s_LastEFBScale = g_ActiveConfig.iEFBScale;
CalculateTargetSize(SupersampleCoeficient);

View File

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

View File

@ -344,21 +344,15 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
s32 expandedWidth = (width + blkW) & (~blkW);
s32 expandedHeight = (height + blkH) & (~blkH);
float MValueX = Renderer::GetTargetScaleX();
float MValueY = Renderer::GetTargetScaleY();
float Xstride = (float)((Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2);
float Ystride = (float)((Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2);
float sampleStride = bScaleByHalf?2.0f:1.0f;
float sampleStride = bScaleByHalf ? 2.f : 1.f;
// TODO: sampleStride scaling might be slightly off
TextureConversionShader::SetShaderParameters(
(float)expandedWidth,
expandedHeight * MValueY,
source.left * MValueX + Xstride ,
source.top * MValueY + Ystride,
sampleStride * MValueX,
sampleStride * MValueY,
(float)expandedWidth,
(float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this?
(float)(Renderer::EFBToScaledX(source.left) + Renderer::TargetStrideX()),
(float)(Renderer::EFBToScaledY(source.top) + Renderer::TargetStrideY()),
Renderer::EFBToScaledXf(sampleStride),
Renderer::EFBToScaledYf(sampleStride),
(float)Renderer::GetFullTargetWidth(),
(float)Renderer::GetFullTargetHeight());
@ -379,7 +373,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
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;
@ -415,15 +409,15 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou
s32 expandedWidth = (width + blkW) & (~blkW);
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(
(float)expandedWidth,
expandedHeight * MValueY,
source.left * MValueX + Xstride ,
source.top * MValueY + Ystride,
sampleStride * MValueX,
sampleStride * MValueY,
(float)expandedWidth,
(float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this?
(float)(Renderer::EFBToScaledX(source.left) + Renderer::TargetStrideX()),
(float)(Renderer::EFBToScaledY(source.top) + Renderer::TargetStrideY()),
Renderer::EFBToScaledXf(sampleStride),
Renderer::EFBToScaledYf(sampleStride),
(float)SourceW,
(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);
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 result;
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
result.left = (int)(rc.left * EFBxScale) + Xstride;
result.top = (int)((EFB_HEIGHT - rc.top) * EFByScale) + Ystride;
result.right = (int)(rc.right * EFBxScale) - (Xstride * 2);
result.bottom = (int)((EFB_HEIGHT - rc.bottom) * EFByScale) - (Ystride * 2);
result.left = EFBToScaledX(rc.left) + TargetStrideX();
result.top = EFBToScaledY(EFB_HEIGHT - rc.top) + TargetStrideY();
result.right = EFBToScaledX(rc.right) - (TargetStrideX() * 2);
result.bottom = EFBToScaledY(EFB_HEIGHT - rc.bottom) - (TargetStrideY() * 2);
return result;
}
@ -618,11 +616,8 @@ bool Renderer::SetScissorRect()
GetScissorRect(rc);
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.right > EFB_WIDTH) rc.right = EFB_WIDTH;
if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
if (rc.left > rc.right)
@ -642,11 +637,10 @@ bool Renderer::SetScissorRect()
if (rc.right != rc.left && rc.bottom != rc.top)
{
glScissor(
(int)(rc.left * EFBxScale), // x = 0 for example
(int)((EFB_HEIGHT - rc.bottom) * EFByScale), // y = 0 for example
(int)((rc.right - rc.left)* EFBxScale), // width = 640 for example
(int)((rc.bottom - rc.top) * EFByScale) // height = 480 for example
);
EFBToScaledX(rc.left), // x = 0 for example
EFBToScaledY(EFB_HEIGHT - rc.bottom), // y = 0 for example
EFBToScaledX(rc.right - rc.left), // width = 640 for example
EFBToScaledY(rc.bottom - rc.top)); // height = 480 for example
return true;
}
else
@ -784,23 +778,23 @@ void Renderer::UpdateViewport()
// [4] = yorig + height/2 + 342
// [5] = 16777215 * farz
int scissorXOff = bpmem.scissorOffset.x * 2;
int scissorYOff = bpmem.scissorOffset.y * 2;
int scissorXOff = bpmem.scissorOffset.x << 1;
int scissorYOff = bpmem.scissorOffset.y << 1;
// int Xstride = (s_Fulltarget_width - s_target_width) / 2;
// int Ystride = (s_Fulltarget_height - s_target_height) / 2;
// Stretch picture with increased internal resolution
int X = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - float(scissorXOff)) * Renderer::GetTargetScaleX());
int Y = (int)ceil((float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + float(scissorYOff)) * Renderer::GetTargetScaleY());
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX());
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY());
// TODO: ceil, floor or just cast to int?
int X = EFBToScaledX((int)ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (float)scissorXOff));
int Y = EFBToScaledY((int)ceil((float)EFB_HEIGHT - xfregs.rawViewport[4] + xfregs.rawViewport[1] + (float)scissorYOff));
int Width = EFBToScaledX((int)ceil(2.0f * xfregs.rawViewport[0]));
int Height = EFBToScaledY((int)ceil(-2.0f * xfregs.rawViewport[1]));
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
double GLFar = xfregs.rawViewport[5] / 16777216.0f;
if (Width < 0)
{
X += Width;
Width*=-1;
Width *= -1;
}
if (Height < 0)
{

View File

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

View File

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

View File

@ -37,7 +37,7 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
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);
}