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/19148 Reviewed-by: Alexis Hétu <sugoi@google.com> Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Common/Version.h b/src/Common/Version.h index ea9a476..9a28e1b 100644 --- a/src/Common/Version.h +++ b/src/Common/Version.h
@@ -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)
diff --git a/src/Renderer/Blitter.cpp b/src/Renderer/Blitter.cpp index c77491c..17c7199 100644 --- a/src/Renderer/Blitter.cpp +++ b/src/Renderer/Blitter.cpp
@@ -163,28 +163,26 @@ 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 @@ 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 @@ } } - 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 @@ d += *Pointer<Int>(blit + OFFSET(BlitData,dSliceB)); } } - - if(!state.clearOperation) { x += w; } } - - if(!state.clearOperation) { y += h; } } } @@ -1456,8 +1449,8 @@ 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;