Merge vk-gl-cts/vulkan-cts-1.1.5 into vk-gl-cts/vulkan-cts-1.1.6
[platform/upstream/VK-GL-CTS.git] / framework / common / tcuRasterizationVerifier.cpp
index b391532..bac16e3 100644 (file)
@@ -915,9 +915,20 @@ bool verifyMultisampleLineGroupRasterization (const tcu::Surface& surface, const
        const float                     halfLineWidth   = scene.lineWidth * 0.5f;
        TriangleSceneSpec       triangleScene;
 
+       deUint32                        stippleCounter  = 0;
+       float                           leftoverPhase   = 0.0f;
+
        triangleScene.triangles.resize(2 * scene.lines.size());
        for (int lineNdx = 0; lineNdx < (int)scene.lines.size(); ++lineNdx)
        {
+
+               if (!scene.isStrip)
+               {
+                       // reset stipple at the start of each line segment
+                       stippleCounter = 0;
+                       leftoverPhase = 0;
+               }
+
                // Transform to screen space, add pixel offsets, convert back to normalized device space, and test as triangles
                tcu::Vec2 lineNormalizedDeviceSpace[2] =
                {
@@ -939,31 +950,117 @@ bool verifyMultisampleLineGroupRasterization (const tcu::Surface& surface, const
                const tcu::Vec2 lineDir                 = tcu::normalize(lineScreenSpace[1] - lineScreenSpace[0]);
                const tcu::Vec2 lineNormalDir   = tcu::Vec2(lineDir.y(), -lineDir.x());
 
-               const tcu::Vec2 lineQuadScreenSpace[4] =
+               if (scene.stippleEnable)
                {
-                       lineScreenSpace[0] + lineNormalDir * halfLineWidth,
-                       lineScreenSpace[0] - lineNormalDir * halfLineWidth,
-                       lineScreenSpace[1] - lineNormalDir * halfLineWidth,
-                       lineScreenSpace[1] + lineNormalDir * halfLineWidth,
-               };
-               const tcu::Vec2 lineQuadNormalizedDeviceSpace[4] =
-               {
-                       lineQuadScreenSpace[0] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
-                       lineQuadScreenSpace[1] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
-                       lineQuadScreenSpace[2] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
-                       lineQuadScreenSpace[3] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
-               };
+                       float lineLength                        = tcu::distance(lineScreenSpace[0], lineScreenSpace[1]);
+                       float lineOffset                        = 0.0f;
 
-               triangleScene.triangles[lineNdx*2 + 0].positions[0] = tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x(), lineQuadNormalizedDeviceSpace[0].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 0].sharedEdge[0] = false;
-               triangleScene.triangles[lineNdx*2 + 0].positions[1] = tcu::Vec4(lineQuadNormalizedDeviceSpace[1].x(), lineQuadNormalizedDeviceSpace[1].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 0].sharedEdge[1] = false;
-               triangleScene.triangles[lineNdx*2 + 0].positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x(), lineQuadNormalizedDeviceSpace[2].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 0].sharedEdge[2] = true;
+                       while (lineOffset < lineLength)
+                       {
+                               float d0 = (float)lineOffset;
+                               float d1 = d0 + 1.0f;
 
-               triangleScene.triangles[lineNdx*2 + 1].positions[0] = tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x(), lineQuadNormalizedDeviceSpace[0].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 1].sharedEdge[0] = true;
-               triangleScene.triangles[lineNdx*2 + 1].positions[1] = tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x(), lineQuadNormalizedDeviceSpace[2].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 1].sharedEdge[1] = false;
-               triangleScene.triangles[lineNdx*2 + 1].positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[3].x(), lineQuadNormalizedDeviceSpace[3].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 1].sharedEdge[2] = false;
+                               // "leftoverPhase" carries over a fractional stipple phase that was "unused"
+                               // by the last line segment in the strip, if it wasn't an integer length.
+                               if (leftoverPhase > lineLength)
+                               {
+                                       DE_ASSERT(d0 == 0.0f);
+                                       d1 = lineLength;
+                                       leftoverPhase -= lineLength;
+                               }
+                               else if (leftoverPhase != 0.0f)
+                               {
+                                       DE_ASSERT(d0 == 0.0f);
+                                       d1 = leftoverPhase;
+                                       leftoverPhase = 0.0f;
+                               }
+                               else
+                               {
+                                       if (d0 + 1.0f > lineLength)
+                                       {
+                                               d1 = lineLength;
+                                               leftoverPhase = d0 + 1.0f - lineLength;
+                                       }
+                                       else
+                                               d1 = d0 + 1.0f;
+                               }
+
+                               // set offset for next iteration
+                               lineOffset = d1;
+
+                               int stippleBit = (stippleCounter / scene.stippleFactor) % 16;
+                               bool stipplePass = (scene.stipplePattern & (1 << stippleBit)) != 0;
+
+                               if (leftoverPhase == 0)
+                                       stippleCounter++;
+
+                               if (!stipplePass)
+                                       continue;
+
+                               d0 /= lineLength;
+                               d1 /= lineLength;
+
+                               tcu::Vec2 l0 = mix(lineScreenSpace[0], lineScreenSpace[1], d0);
+                               tcu::Vec2 l1 = mix(lineScreenSpace[0], lineScreenSpace[1], d1);
+
+                               const tcu::Vec2 lineQuadScreenSpace[4] =
+                               {
+                                       l0 + lineNormalDir * halfLineWidth,
+                                       l0 - lineNormalDir * halfLineWidth,
+                                       l1 - lineNormalDir * halfLineWidth,
+                                       l1 + lineNormalDir * halfLineWidth,
+                               };
+                               const tcu::Vec2 lineQuadNormalizedDeviceSpace[4] =
+                               {
+                                       lineQuadScreenSpace[0] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
+                                       lineQuadScreenSpace[1] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
+                                       lineQuadScreenSpace[2] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
+                                       lineQuadScreenSpace[3] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
+                               };
+
+                               TriangleSceneSpec::SceneTriangle tri;
+
+                               tri.positions[0] = tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x(), lineQuadNormalizedDeviceSpace[0].y(), 0.0f, 1.0f);   tri.sharedEdge[0] = (d0 != 0.0f);
+                               tri.positions[1] = tcu::Vec4(lineQuadNormalizedDeviceSpace[1].x(), lineQuadNormalizedDeviceSpace[1].y(), 0.0f, 1.0f);   tri.sharedEdge[1] = false;
+                               tri.positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x(), lineQuadNormalizedDeviceSpace[2].y(), 0.0f, 1.0f);   tri.sharedEdge[2] = true;
+
+                               triangleScene.triangles.push_back(tri);
+
+                               tri.positions[0] = tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x(), lineQuadNormalizedDeviceSpace[0].y(), 0.0f, 1.0f);   tri.sharedEdge[0] = true;
+                               tri.positions[1] = tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x(), lineQuadNormalizedDeviceSpace[2].y(), 0.0f, 1.0f);   tri.sharedEdge[1] = (d1 != 1.0f);
+                               tri.positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[3].x(), lineQuadNormalizedDeviceSpace[3].y(), 0.0f, 1.0f);   tri.sharedEdge[2] = false;
+
+                               triangleScene.triangles.push_back(tri);
+                       }
+               }
+               else
+               {
+                       const tcu::Vec2 lineQuadScreenSpace[4] =
+                       {
+                               lineScreenSpace[0] + lineNormalDir * halfLineWidth,
+                               lineScreenSpace[0] - lineNormalDir * halfLineWidth,
+                               lineScreenSpace[1] - lineNormalDir * halfLineWidth,
+                               lineScreenSpace[1] + lineNormalDir * halfLineWidth,
+                       };
+                       const tcu::Vec2 lineQuadNormalizedDeviceSpace[4] =
+                       {
+                               lineQuadScreenSpace[0] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
+                               lineQuadScreenSpace[1] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
+                               lineQuadScreenSpace[2] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
+                               lineQuadScreenSpace[3] / viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
+                       };
+
+                       triangleScene.triangles[lineNdx*2 + 0].positions[0] = tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x(), lineQuadNormalizedDeviceSpace[0].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 0].sharedEdge[0] = false;
+                       triangleScene.triangles[lineNdx*2 + 0].positions[1] = tcu::Vec4(lineQuadNormalizedDeviceSpace[1].x(), lineQuadNormalizedDeviceSpace[1].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 0].sharedEdge[1] = false;
+                       triangleScene.triangles[lineNdx*2 + 0].positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x(), lineQuadNormalizedDeviceSpace[2].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 0].sharedEdge[2] = true;
+
+                       triangleScene.triangles[lineNdx*2 + 1].positions[0] = tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x(), lineQuadNormalizedDeviceSpace[0].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 1].sharedEdge[0] = true;
+                       triangleScene.triangles[lineNdx*2 + 1].positions[1] = tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x(), lineQuadNormalizedDeviceSpace[2].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 1].sharedEdge[1] = false;
+                       triangleScene.triangles[lineNdx*2 + 1].positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[3].x(), lineQuadNormalizedDeviceSpace[3].y(), 0.0f, 1.0f);        triangleScene.triangles[lineNdx*2 + 1].sharedEdge[2] = false;
+               }
        }
 
-       return verifyTriangleGroupRasterization(surface, triangleScene, args, log, VERIFICATIONMODE_STRICT, logStash);
+       return verifyTriangleGroupRasterization(surface, triangleScene, args, log, scene.verificationMode, logStash);
 }
 
 bool verifyMultisampleLineGroupInterpolation (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
@@ -1100,7 +1197,6 @@ bool verifySinglesampleLineGroupRasterization (const tcu::Surface& surface, cons
        int                                             referenceFragments      = 0;
        int                                             resultFragments         = 0;
        int                                             lineWidth                       = deFloorFloatToInt32(scene.lineWidth + 0.5f);
-       bool                                    imageShown                      = false;
        std::vector<bool>               lineIsXMajor            (scene.lines.size());
        std::vector<tcu::Vec4>  screenspaceLines(scene.lines.size());
 
@@ -1110,9 +1206,9 @@ bool verifySinglesampleLineGroupRasterization (const tcu::Surface& surface, cons
 
        genScreenSpaceLines(screenspaceLines, scene.lines, tcu::IVec2(surface.getWidth(), surface.getHeight()));
 
+       rr::SingleSampleLineRasterizer rasterizer(tcu::IVec4(0, 0, surface.getWidth(), surface.getHeight()), args.subpixelBits);
        for (int lineNdx = 0; lineNdx < (int)scene.lines.size(); ++lineNdx)
        {
-               rr::SingleSampleLineRasterizer rasterizer(tcu::IVec4(0, 0, surface.getWidth(), surface.getHeight()), args.subpixelBits);
                rasterizer.init(tcu::Vec4(screenspaceLines[lineNdx][0],
                                                                  screenspaceLines[lineNdx][1],
                                                                  0.0f,
@@ -1121,7 +1217,12 @@ bool verifySinglesampleLineGroupRasterization (const tcu::Surface& surface, cons
                                                                  screenspaceLines[lineNdx][3],
                                                                  0.0f,
                                                                  1.0f),
-                                               scene.lineWidth);
+                                               scene.lineWidth,
+                                               scene.stippleFactor,
+                                               scene.stipplePattern);
+
+               if (!scene.isStrip)
+                       rasterizer.resetStipple();
 
                // calculate majority of later use
                lineIsXMajor[lineNdx] = isPackedSSLineXMajor(screenspaceLines[lineNdx]);
@@ -1209,13 +1310,6 @@ bool verifySinglesampleLineGroupRasterization (const tcu::Surface& surface, cons
 
                if (missingFragments)
                {
-                       log << tcu::TestLog::Message << "Invalid deviation(s) found." << tcu::TestLog::EndMessage;
-                       log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
-                               << tcu::TestLog::Image("Result", "Result",                      surface)
-                               << tcu::TestLog::Image("ErrorMask", "ErrorMask",        errorMask)
-                               << tcu::TestLog::EndImageSet;
-
-                       imageShown = true;
                        allOK = false;
                }
                else
@@ -1256,7 +1350,6 @@ bool verifySinglesampleLineGroupRasterization (const tcu::Surface& surface, cons
                                        << tcu::TestLog::EndImageSet;
 
                                allOK = false;
-                               imageShown = true;
                        }
                        else
                        {
@@ -1303,7 +1396,6 @@ bool verifySinglesampleLineGroupRasterization (const tcu::Surface& surface, cons
                                                {
                                                        if (lineID && lineID != nearbyID)
                                                                multipleNearbyLines = true;
-                                                       lineID = nearbyID;
                                                }
                                        }
 
@@ -1461,10 +1553,20 @@ bool verifySinglesampleLineGroupRasterization (const tcu::Surface& surface, cons
        //duplicate fragments, nor may any fragments be omitted so as to interrupt
        //continuity of the connected segments.
 
-       if (!imageShown)
        {
+               tcu::Surface reference(surface.getWidth(), surface.getHeight());
+
+               // show a helpful reference image
+               tcu::clear(reference.getAccess(), tcu::IVec4(0, 0, 0, 255));
+               for (int y = 0; y < surface.getHeight(); ++y)
+               for (int x = 0; x < surface.getWidth(); ++x)
+                       if (referenceLineMap.getAccess().getPixelInt(x, y).x())
+                               reference.setPixel(x, y, tcu::RGBA::white());
+
+               log << tcu::TestLog::Message << "Invalid fragment count in result image." << tcu::TestLog::EndMessage;
                log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
-                       << tcu::TestLog::Image("Result", "Result", surface)
+                       << tcu::TestLog::Image("Reference", "Reference",        reference)
+                       << tcu::TestLog::Image("Result", "Result",                      surface)
                        << tcu::TestLog::EndImageSet;
        }
 
@@ -1495,7 +1597,8 @@ void setMaskMapCoverageBitForLine (int bitNdx, const tcu::Vec2& screenSpaceP0, c
 
        rasterizer.init(tcu::Vec4(screenSpaceP0.x(), screenSpaceP0.y(), 0.0f, 1.0f),
                                        tcu::Vec4(screenSpaceP1.x(), screenSpaceP1.y(), 0.0f, 1.0f),
-                                       lineWidth);
+                                       lineWidth,
+                                       1, 0xFFFF);
 
        while (numRasterized == MAX_PACKETS)
        {
@@ -2282,6 +2385,7 @@ bool verifyTriangleGroupRasterization (const tcu::Surface& surface, const Triang
        const tcu::RGBA         partialPixelColor                       = tcu::RGBA(255, 255, 0, 255);
        const tcu::RGBA         primitivePixelColor                     = tcu::RGBA(30, 30, 30, 255);
        const int                       weakVerificationThreshold       = 10;
+       const int                       weakerVerificationThreshold     = 25;
        const bool                      multisampled                            = (args.numSamples != 0);
        const tcu::IVec2        viewportSize                            = tcu::IVec2(surface.getWidth(), surface.getHeight());
        int                                     missingPixels                           = 0;
@@ -2407,7 +2511,9 @@ bool verifyTriangleGroupRasterization (const tcu::Surface& surface, const Triang
        }
 
        if (((mode == VERIFICATIONMODE_STRICT) && (missingPixels + unexpectedPixels > 0)) ||
-               ((mode == VERIFICATIONMODE_WEAK)   && (missingPixels + unexpectedPixels > weakVerificationThreshold)))
+               ((mode == VERIFICATIONMODE_WEAK)   && (missingPixels + unexpectedPixels > weakVerificationThreshold)) ||
+               ((mode == VERIFICATIONMODE_WEAKER) && (missingPixels + unexpectedPixels > weakerVerificationThreshold)) ||
+               ((mode == VERIFICATIONMODE_SMOOTH) && (missingPixels > weakVerificationThreshold)))
        {
                result = false;
        }