Commit ae3d8752 by Nicolas Capens Committed by Nicolas Capens

Prevent floating-point error accumulation during blitting.

The numeric imprecision can accumulate quickly and cause visible sampling errors. Bug chromium:848238 Change-Id: Ie41c10a0462e5b5e5c3ed5f7329ece00dab3f7f9 Reviewed-on: https://swiftshader-review.googlesource.com/19148Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 419e8a7a
......@@ -15,7 +15,7 @@
#define MAJOR_VERSION 4
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 5
#define BUILD_REVISION 6
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -163,28 +163,26 @@ namespace sw
swap(sRect.y0, sRect.y1);
}
source->lockInternal((int)sRect.x0, (int)sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
source->lockInternal(0, 0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
dest->lockInternal(0, 0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
float w = sRect.width() / dRect.width();
float h = sRect.height() / dRect.height();
const float xStart = sRect.x0 + 0.5f * w;
float y = sRect.y0 + 0.5f * h;
float xStart = sRect.x0 + (0.5f - dRect.x0) * w;
float yStart = sRect.y0 + (0.5f - dRect.y0) * h;
for(int j = dRect.y0; j < dRect.y1; j++)
{
float x = xStart;
float y = yStart + j * h;
for(int i = dRect.x0; i < dRect.x1; i++)
{
float x = xStart + i * w;
// FIXME: Support RGBA mask
dest->copyInternal(source, i, j, x, y, options.filter);
x += w;
}
y += h;
}
source->unlockInternal();
......@@ -200,21 +198,21 @@ namespace sw
float h = static_cast<float>(source->getHeight()) / static_cast<float>(dest->getHeight());
float d = static_cast<float>(source->getDepth()) / static_cast<float>(dest->getDepth());
float z = 0.5f * d;
for(int k = 0; k < dest->getDepth(); k++)
{
float y = 0.5f * h;
float z = (k + 0.5f) * d;
for(int j = 0; j < dest->getHeight(); j++)
{
float x = 0.5f * w;
float y = (j + 0.5f) * h;
for(int i = 0; i < dest->getWidth(); i++)
{
float x = (i + 0.5f) * w;
dest->copyInternal(source, i, j, k, x, y, z, true);
x += w;
}
y += h;
}
z += d;
}
source->unlockInternal();
......@@ -1237,15 +1235,14 @@ namespace sw
}
}
Float y = y0;
For(Int j = y0d, j < y1d, j++)
{
Float x = x0;
Float y = state.clearOperation ? y0 : y0 + Float(j) * h;
Pointer<Byte> destLine = dest + (dstQuadLayout ? j & Int(~1) : RValue<Int>(j)) * dPitchB;
For(Int i = x0d, i < x1d, i++)
{
Float x = state.clearOperation ? x0 : x0 + Float(i) * w;
Pointer<Byte> d = destLine + (dstQuadLayout ? (((j & Int(1)) << 1) + (i * 2) - (i & Int(1))) : RValue<Int>(i)) * dstBytes;
if(hasConstantColorI)
......@@ -1379,11 +1376,7 @@ namespace sw
d += *Pointer<Int>(blit + OFFSET(BlitData,dSliceB));
}
}
if(!state.clearOperation) { x += w; }
}
if(!state.clearOperation) { y += h; }
}
}
......@@ -1456,8 +1449,8 @@ namespace sw
data.w = sRect.width() / dRect.width();
data.h = sRect.height() / dRect.height();
data.x0 = sRect.x0 + 0.5f * data.w;
data.y0 = sRect.y0 + 0.5f * data.h;
data.x0 = sRect.x0 + (0.5f - dRect.x0) * data.w;
data.y0 = sRect.y0 + (0.5f - dRect.y0) * data.h;
data.x0d = dRect.x0;
data.x1d = dRect.x1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment