gsdx hack: reduce complexity of alpha* function

It will help the compiler to make a couple of optimizations (and it will help
a futur porting to GSVector)
This commit is contained in:
Gregory Hainaut 2015-04-12 17:10:45 +02:00
parent 1d0deb5ffe
commit 399ddbd74a
2 changed files with 20 additions and 22 deletions

View File

@ -207,26 +207,16 @@ int GSRendererHW::Interpolate_UV(float alpha, int t0, int t1)
return (int)t & ~0xF; // cheap rounding return (int)t & ~0xF; // cheap rounding
} }
float GSRendererHW::alpha0(int offset, int x0, int x1) float GSRendererHW::alpha0(int L, int X0, int X1)
{ {
int X0 = x0 - offset; float x = (X0 + 15) & ~0xF; // Round up
if (X0 & 0xF) { return (x - X0) / (float)L;
float L = (x1 - x0);
float x = (X0 + 15) & ~0xF; // Round up
return (x - X0) / L;
} else {
// X0 is aligned on the pixel. Above calcul can be shortcuted
return 0.0f;
}
} }
float GSRendererHW::alpha1(int offset, int x0, int x1) float GSRendererHW::alpha1(int L, int X0, int X1)
{ {
int X1 = x1 - offset;
int X0 = x0 - offset;
float x = (X1 - 1) & ~0xF; // Round down. Note -1 because right pixel isn't included in primitive so 0x100 must return 0. float x = (X1 - 1) & ~0xF; // Round down. Note -1 because right pixel isn't included in primitive so 0x100 must return 0.
float L = (x1 - x0); return (x - X0) / (float)L;
return (x - X0) / L;
} }
template <bool linear> template <bool linear>
@ -240,11 +230,15 @@ void GSRendererHW::RoundSpriteOffset()
GSVertex* v = &m_vertex.buff[0]; GSVertex* v = &m_vertex.buff[0];
for(size_t i = 0; i < count; i += 2) { for(size_t i = 0; i < count; i += 2) {
// Performance note: if it had any impact on perf, someone would port it to SSE // Performance note: if it had any impact on perf, someone would port it to SSE (AKA GSVector)
// Compute the coordinate of first and last texels (in native with a linear filtering) // Compute the coordinate of first and last texels (in native with a linear filtering)
float ax0 = alpha0(m_context->XYOFFSET.OFX, v[i].XYZ.X, v[i+1].XYZ.X); int ox = m_context->XYOFFSET.OFX;
float ax1 = alpha1(m_context->XYOFFSET.OFX, v[i].XYZ.X, v[i+1].XYZ.X); int X0 = v[i].XYZ.X - ox;
int X1 = v[i+1].XYZ.X - ox;
int Lx = (v[i+1].XYZ.X - v[i].XYZ.X);
float ax0 = alpha0(Lx, X0, X1);
float ax1 = alpha1(Lx, X0, X1);
int tx0 = Interpolate_UV(ax0, v[i].U, v[i+1].U); int tx0 = Interpolate_UV(ax0, v[i].U, v[i+1].U);
int tx1 = Interpolate_UV(ax1, v[i].U, v[i+1].U); int tx1 = Interpolate_UV(ax1, v[i].U, v[i+1].U);
#ifdef DEBUG_U #ifdef DEBUG_U
@ -255,8 +249,12 @@ void GSRendererHW::RoundSpriteOffset()
} }
#endif #endif
float ay0 = alpha0(m_context->XYOFFSET.OFY, v[i].XYZ.Y, v[i+1].XYZ.Y); int oy = m_context->XYOFFSET.OFY;
float ay1 = alpha1(m_context->XYOFFSET.OFY, v[i].XYZ.Y, v[i+1].XYZ.Y); int Y0 = v[i].XYZ.Y - oy;
int Y1 = v[i+1].XYZ.Y - oy;
int Ly = (v[i+1].XYZ.Y - v[i].XYZ.Y);
float ay0 = alpha0(Ly, Y0, Y1);
float ay1 = alpha1(Ly, Y0, Y1);
int ty0 = Interpolate_UV(ay0, v[i].V, v[i+1].V); int ty0 = Interpolate_UV(ay0, v[i].V, v[i+1].V);
int ty1 = Interpolate_UV(ay1, v[i].V, v[i+1].V); int ty1 = Interpolate_UV(ay1, v[i].V, v[i+1].V);
#ifdef DEBUG_V #ifdef DEBUG_V

View File

@ -133,8 +133,8 @@ private:
#pragma endregion #pragma endregion
int Interpolate_UV(float alpha, int t0, int t1); int Interpolate_UV(float alpha, int t0, int t1);
float alpha0(int offset, int x0, int x1); float alpha0(int L, int X0, int X1);
float alpha1(int offset, int x0, int x1); float alpha1(int L, int X0, int X1);
template <bool linear> void RoundSpriteOffset(); template <bool linear> void RoundSpriteOffset();