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 @@ ...@@ -15,7 +15,7 @@
#define MAJOR_VERSION 4 #define MAJOR_VERSION 4
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 5 #define BUILD_REVISION 6
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -163,28 +163,26 @@ namespace sw ...@@ -163,28 +163,26 @@ namespace sw
swap(sRect.y0, sRect.y1); swap(sRect.y0, sRect.y1);
} }
source->lockInternal((int)sRect.x0, (int)sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC); source->lockInternal(0, 0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC); dest->lockInternal(0, 0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
float w = sRect.width() / dRect.width(); float w = sRect.width() / dRect.width();
float h = sRect.height() / dRect.height(); float h = sRect.height() / dRect.height();
const float xStart = sRect.x0 + 0.5f * w; float xStart = sRect.x0 + (0.5f - dRect.x0) * w;
float y = sRect.y0 + 0.5f * h; float yStart = sRect.y0 + (0.5f - dRect.y0) * h;
for(int j = dRect.y0; j < dRect.y1; j++) 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++) for(int i = dRect.x0; i < dRect.x1; i++)
{ {
float x = xStart + i * w;
// FIXME: Support RGBA mask // FIXME: Support RGBA mask
dest->copyInternal(source, i, j, x, y, options.filter); dest->copyInternal(source, i, j, x, y, options.filter);
x += w;
} }
y += h;
} }
source->unlockInternal(); source->unlockInternal();
...@@ -200,21 +198,21 @@ namespace sw ...@@ -200,21 +198,21 @@ namespace sw
float h = static_cast<float>(source->getHeight()) / static_cast<float>(dest->getHeight()); 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 d = static_cast<float>(source->getDepth()) / static_cast<float>(dest->getDepth());
float z = 0.5f * d;
for(int k = 0; k < dest->getDepth(); k++) 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++) 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++) for(int i = 0; i < dest->getWidth(); i++)
{ {
float x = (i + 0.5f) * w;
dest->copyInternal(source, i, j, k, x, y, z, true); dest->copyInternal(source, i, j, k, x, y, z, true);
x += w;
} }
y += h;
} }
z += d;
} }
source->unlockInternal(); source->unlockInternal();
...@@ -1237,15 +1235,14 @@ namespace sw ...@@ -1237,15 +1235,14 @@ namespace sw
} }
} }
Float y = y0;
For(Int j = y0d, j < y1d, j++) 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; Pointer<Byte> destLine = dest + (dstQuadLayout ? j & Int(~1) : RValue<Int>(j)) * dPitchB;
For(Int i = x0d, i < x1d, i++) 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; Pointer<Byte> d = destLine + (dstQuadLayout ? (((j & Int(1)) << 1) + (i * 2) - (i & Int(1))) : RValue<Int>(i)) * dstBytes;
if(hasConstantColorI) if(hasConstantColorI)
...@@ -1379,11 +1376,7 @@ namespace sw ...@@ -1379,11 +1376,7 @@ namespace sw
d += *Pointer<Int>(blit + OFFSET(BlitData,dSliceB)); d += *Pointer<Int>(blit + OFFSET(BlitData,dSliceB));
} }
} }
if(!state.clearOperation) { x += w; }
} }
if(!state.clearOperation) { y += h; }
} }
} }
...@@ -1456,8 +1449,8 @@ namespace sw ...@@ -1456,8 +1449,8 @@ namespace sw
data.w = sRect.width() / dRect.width(); data.w = sRect.width() / dRect.width();
data.h = sRect.height() / dRect.height(); data.h = sRect.height() / dRect.height();
data.x0 = sRect.x0 + 0.5f * data.w; data.x0 = sRect.x0 + (0.5f - dRect.x0) * data.w;
data.y0 = sRect.y0 + 0.5f * data.h; data.y0 = sRect.y0 + (0.5f - dRect.y0) * data.h;
data.x0d = dRect.x0; data.x0d = dRect.x0;
data.x1d = dRect.x1; 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