CP: Add triangle edge guardband for Tex2D lookup diff
authorKalle Raita <kraita@google.com>
Tue, 18 Jul 2017 21:52:15 +0000 (14:52 -0700)
committerKalle Raita <kraita@google.com>
Wed, 26 Jul 2017 18:26:01 +0000 (11:26 -0700)
Cherry-pick AOSP Change: dcb5991811ed287fc4a72126663136a94eb7dc39

Previously 3D and cube textures allowed pixels along the seam of
triangles to use data from either triangle. This change copies that
allowance to the 2D texture computeTextureLookupDiff. The projection
values chosen for the mipmap.2d.projected group make the data
discontinous over the edge, making it sensitive to tie-breaker
resolution. This change resolves the issue.

Affects: framework

Test: Executed mipmap.2d.projected group with failing result images
Bug: 63335787
Change-Id: Ibaed590fb5e1bc9eb837c9027ddadcea2081f629

framework/opengl/gluTextureTestUtil.cpp

index a010b4d..70f5529 100644 (file)
@@ -1356,6 +1356,8 @@ int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&  result,
 
        const tcu::Vec2                                                         lodBias                         ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
 
+       const float                                                                     posEps                          = 1.0f / float(1<<MIN_SUBPIXEL_BITS);
+
        int                                                                                     numFailed                       = 0;
 
        const tcu::Vec2 lodOffsets[] =
@@ -1387,41 +1389,55 @@ int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&        result,
                                const float             nx              = wx / dstW;
                                const float             ny              = wy / dstH;
 
-                               const int               triNdx  = nx + ny >= 1.0f ? 1 : 0;
-                               const float             triWx   = triNdx ? dstW - wx : wx;
-                               const float             triWy   = triNdx ? dstH - wy : wy;
-                               const float             triNx   = triNdx ? 1.0f - nx : nx;
-                               const float             triNy   = triNdx ? 1.0f - ny : ny;
+                               const bool              tri0    = (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f;
+                               const bool              tri1    = (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f;
 
-                               const tcu::Vec2 coord           (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
-                                                                                        projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
-                               const tcu::Vec2 coordDx         = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
-                                                                                                               triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat();
-                               const tcu::Vec2 coordDy         = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
-                                                                                                               triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat();
+                               bool                    isOk    = false;
 
-                               tcu::Vec2               lodBounds       = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);
+                               DE_ASSERT(tri0 || tri1);
 
-                               // Compute lod bounds across lodOffsets range.
-                               for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
+                               // Pixel can belong to either of the triangles if it lies close enough to the edge.
+                               for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++)
                                {
-                                       const float             wxo             = triWx + lodOffsets[lodOffsNdx].x();
-                                       const float             wyo             = triWy + lodOffsets[lodOffsNdx].y();
-                                       const float             nxo             = wxo/dstW;
-                                       const float             nyo             = wyo/dstH;
+                                       const float             triWx   = triNdx ? dstW - wx : wx;
+                                       const float             triWy   = triNdx ? dstH - wy : wy;
+                                       const float             triNx   = triNdx ? 1.0f - nx : nx;
+                                       const float             triNy   = triNdx ? 1.0f - ny : ny;
 
-                                       const tcu::Vec2 coordDxo        = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
-                                                                                                                       triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat();
-                                       const tcu::Vec2 coordDyo        = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
-                                                                                                                       triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat();
-                                       const tcu::Vec2 lodO            = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec);
+                                       const tcu::Vec2 coord           (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
+                                                                                                projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
+                                       const tcu::Vec2 coordDx         = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
+                                                                                                                       triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat();
+                                       const tcu::Vec2 coordDy         = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
+                                                                                                                       triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat();
 
-                                       lodBounds.x() = de::min(lodBounds.x(), lodO.x());
-                                       lodBounds.y() = de::max(lodBounds.y(), lodO.y());
-                               }
+                                       tcu::Vec2               lodBounds       = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);
 
-                               const tcu::Vec2 clampedLod      = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
-                               const bool              isOk            = tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);
+                                       // Compute lod bounds across lodOffsets range.
+                                       for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
+                                       {
+                                               const float             wxo             = triWx + lodOffsets[lodOffsNdx].x();
+                                               const float             wyo             = triWy + lodOffsets[lodOffsNdx].y();
+                                               const float             nxo             = wxo/dstW;
+                                               const float             nyo             = wyo/dstH;
+
+                                               const tcu::Vec2 coordDxo        = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
+                                                                                                                               triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat();
+                                               const tcu::Vec2 coordDyo        = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
+                                                                                                                               triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat();
+                                               const tcu::Vec2 lodO            = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec);
+
+                                               lodBounds.x() = de::min(lodBounds.x(), lodO.x());
+                                               lodBounds.y() = de::max(lodBounds.y(), lodO.y());
+                                       }
+
+                                       const tcu::Vec2 clampedLod      = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
+                                       if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix))
+                                       {
+                                               isOk = true;
+                                               break;
+                                       }
+                               }
 
                                if (!isOk)
                                {