From 418deed8c554853ce15617b02ecf845a173fa4cd Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Tue, 28 Apr 2020 03:32:10 +0000 Subject: [PATCH] Bug 1633617 - round quantized coordinates in SWGL bilinear filtering. r=jimb Differential Revision: https://phabricator.services.mozilla.com/D72782 --- gfx/wr/swgl/src/gl.cc | 6 +++--- gfx/wr/swgl/src/glsl.h | 36 ++++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/gfx/wr/swgl/src/gl.cc b/gfx/wr/swgl/src/gl.cc index 7522314887b0..ae6eff53fdb0 100644 --- a/gfx/wr/swgl/src/gl.cc +++ b/gfx/wr/swgl/src/gl.cc @@ -3543,11 +3543,11 @@ static void linear_blit(Texture& srctex, const IntRect& srcReq, int srcZ, vec2_scalar srcUV(srcReq.x0, srcReq.y0); vec2_scalar srcDUV(float(srcReq.width()) / dstReq.width(), float(srcReq.height()) / dstReq.height()); - // Scale source UVs by linear-interpolation precision - srcUV *= 128.0f; - srcDUV *= 128.0f; // Skip to clamped source start srcUV += srcDUV * vec2_scalar(dstBounds.x0, dstBounds.y0); + // Scale source UVs by linear-interpolation precision + srcUV = linearQuantize(srcUV, 128); + srcDUV *= 128.0f; // Calculate dest pointer from clamped offsets int bpp = dsttex.bpp(); int destStride = dsttex.stride(bpp); diff --git a/gfx/wr/swgl/src/glsl.h b/gfx/wr/swgl/src/glsl.h index 2b1710c6c853..a880a2f48781 100644 --- a/gfx/wr/swgl/src/glsl.h +++ b/gfx/wr/swgl/src/glsl.h @@ -2443,15 +2443,27 @@ SI T mix(T x, T y, vec4_scalar a) { mix(x.w, y.w, a.w)}; } +// Scale texture coords for quantization, subtract offset for filtering, +// and round to nearest 1/scale increment +template +SI T linearQuantize(T P, float scale) { + return P * scale + (0.5f - 0.5f * scale); +} + +// Helper version that also scales normalized texture coords for sampler +template +SI T linearQuantize(T P, float scale, S sampler) { + P.x *= sampler->width; + P.y *= sampler->height; + return linearQuantize(P, scale); +} + template vec4 textureLinearRGBA8(S sampler, vec2 P, I32 zoffset = 0) { assert(sampler->format == TextureFormat::RGBA8); #if USE_SSE2 - P.x *= sampler->width * 256.0f; - P.y *= sampler->height * 256.0f; - P -= 0.5f * 256.0f; - ivec2 i(P); + ivec2 i(linearQuantize(P, 256, sampler)); ivec2 frac = i & (I32)0xFF; i >>= 8; @@ -2515,10 +2527,7 @@ vec4 textureLinearRGBA8(S sampler, vec2 P, I32 zoffset = 0) { _MM_TRANSPOSE4_PS(r0, r1, r2, r3); return vec4(r2, r1, r0, r3) * (1.0f / 0xFF00); #else - P.x *= sampler->width * 128.0f; - P.y *= sampler->height * 128.0f; - P -= 0.5f * 128.0f; - ivec2 i(P); + ivec2 i(linearQuantize(P, 128, sampler)); ivec2 frac = i & (I32)0x7F; i >>= 7; @@ -2615,10 +2624,7 @@ vec4 textureLinearR8(S sampler, vec2 P, I32 zoffset = 0) { assert(sampler->format == TextureFormat::R8); #if USE_SSE2 - P.x *= sampler->width * 256.0f; - P.y *= sampler->height * 256.0f; - P -= 0.5f * 256.0f; - ivec2 i(P); + ivec2 i(linearQuantize(P, 256, sampler)); ivec2 frac = i & (I32)0xFF; i >>= 8; @@ -2671,10 +2677,8 @@ vec4 textureLinearR8(S sampler, vec2 P, I32 zoffset = 0) { __m128 r = _mm_cvtepi32_ps(_mm_madd_epi16(cc, fracx)); return vec4((Float)r * (1.0f / 0xFF00), 0.0f, 0.0f, 1.0f); #else - P.x *= sampler->width * 128.0f; - P.y *= sampler->height * 128.0f; - P -= 0.5f * 128.0f; - Float r = CONVERT(textureLinearPackedR8(sampler, ivec2(P), zoffset), Float); + ivec2 i(linearQuantize(P, 128, sampler)); + Float r = CONVERT(textureLinearPackedR8(sampler, i, zoffset), Float); return vec4(r * (1.0f / 255.0f), 0.0f, 0.0f, 1.0f); #endif }