/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Rasterization verifier utils.
 *//*--------------------------------------------------------------------*/

#include "tcuRasterizationVerifier.hpp"
#include "tcuVector.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuFloat.hpp"

#include "deMath.h"
#include "deStringUtil.hpp"

#include "rrRasterizer.hpp"

#include <limits>

namespace tcu
{
namespace
{

bool verifyLineGroupInterpolationWithProjectedWeights (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log);

bool lineLineIntersect (const tcu::Vector<deInt64, 2>& line0Beg, const tcu::Vector<deInt64, 2>& line0End, const tcu::Vector<deInt64, 2>& line1Beg, const tcu::Vector<deInt64, 2>& line1End)
{
	typedef tcu::Vector<deInt64, 2> I64Vec2;

	// Lines do not intersect if the other line's endpoints are on the same side
	// otherwise, the do intersect

	// Test line 0
	{
		const I64Vec2 line			= line0End - line0Beg;
		const I64Vec2 v0			= line1Beg - line0Beg;
		const I64Vec2 v1			= line1End - line0Beg;
		const deInt64 crossProduct0	= (line.x() * v0.y() - line.y() * v0.x());
		const deInt64 crossProduct1	= (line.x() * v1.y() - line.y() * v1.x());

		// check signs
		if ((crossProduct0 < 0 && crossProduct1 < 0) ||
			(crossProduct0 > 0 && crossProduct1 > 0))
			return false;
	}

	// Test line 1
	{
		const I64Vec2 line			= line1End - line1Beg;
		const I64Vec2 v0			= line0Beg - line1Beg;
		const I64Vec2 v1			= line0End - line1Beg;
		const deInt64 crossProduct0	= (line.x() * v0.y() - line.y() * v0.x());
		const deInt64 crossProduct1	= (line.x() * v1.y() - line.y() * v1.x());

		// check signs
		if ((crossProduct0 < 0 && crossProduct1 < 0) ||
			(crossProduct0 > 0 && crossProduct1 > 0))
			return false;
	}

	return true;
}

bool isTriangleClockwise (const tcu::Vec4& p0, const tcu::Vec4& p1, const tcu::Vec4& p2)
{
	const tcu::Vec2	u				(p1.x() / p1.w() - p0.x() / p0.w(), p1.y() / p1.w() - p0.y() / p0.w());
	const tcu::Vec2	v				(p2.x() / p2.w() - p0.x() / p0.w(), p2.y() / p2.w() - p0.y() / p0.w());
	const float		crossProduct	= (u.x() * v.y() - u.y() * v.x());

	return crossProduct > 0.0f;
}

bool compareColors (const tcu::RGBA& colorA, const tcu::RGBA& colorB, int redBits, int greenBits, int blueBits)
{
	const int thresholdRed		= 1 << (8 - redBits);
	const int thresholdGreen	= 1 << (8 - greenBits);
	const int thresholdBlue		= 1 << (8 - blueBits);

	return	deAbs32(colorA.getRed()   - colorB.getRed())   <= thresholdRed   &&
			deAbs32(colorA.getGreen() - colorB.getGreen()) <= thresholdGreen &&
			deAbs32(colorA.getBlue()  - colorB.getBlue())  <= thresholdBlue;
}

bool pixelNearLineSegment (const tcu::IVec2& pixel, const tcu::Vec2& p0, const tcu::Vec2& p1)
{
	const tcu::Vec2 pixelCenterPosition = tcu::Vec2((float)pixel.x() + 0.5f, (float)pixel.y() + 0.5f);

	// "Near" = Distance from the line to the pixel is less than 2 * pixel_max_radius. (pixel_max_radius = sqrt(2) / 2)
	const float maxPixelDistance		= 1.414f;
	const float maxPixelDistanceSquared	= 2.0f;

	// Near the line
	{
		const tcu::Vec2	line			= p1                  - p0;
		const tcu::Vec2	v				= pixelCenterPosition - p0;
		const float		crossProduct	= (line.x() * v.y() - line.y() * v.x());

		// distance to line: (line x v) / |line|
		//     |(line x v) / |line|| > maxPixelDistance
		// ==> (line x v)^2 / |line|^2 > maxPixelDistance^2
		// ==> (line x v)^2 > maxPixelDistance^2 * |line|^2

		if (crossProduct * crossProduct > maxPixelDistanceSquared * tcu::lengthSquared(line))
			return false;
	}

	// Between the endpoints
	{
		// distance from line endpoint 1 to pixel is less than line length + maxPixelDistance
		const float maxDistance = tcu::length(p1 - p0) + maxPixelDistance;

		if (tcu::length(pixelCenterPosition - p0) > maxDistance)
			return false;
		if (tcu::length(pixelCenterPosition - p1) > maxDistance)
			return false;
	}

	return true;
}

bool pixelOnlyOnASharedEdge (const tcu::IVec2& pixel, const TriangleSceneSpec::SceneTriangle& triangle, const tcu::IVec2& viewportSize)
{
	if (triangle.sharedEdge[0] || triangle.sharedEdge[1] || triangle.sharedEdge[2])
	{
		const tcu::Vec2 triangleNormalizedDeviceSpace[3] =
		{
			tcu::Vec2(triangle.positions[0].x() / triangle.positions[0].w(), triangle.positions[0].y() / triangle.positions[0].w()),
			tcu::Vec2(triangle.positions[1].x() / triangle.positions[1].w(), triangle.positions[1].y() / triangle.positions[1].w()),
			tcu::Vec2(triangle.positions[2].x() / triangle.positions[2].w(), triangle.positions[2].y() / triangle.positions[2].w()),
		};
		const tcu::Vec2 triangleScreenSpace[3] =
		{
			(triangleNormalizedDeviceSpace[0] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
			(triangleNormalizedDeviceSpace[1] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
			(triangleNormalizedDeviceSpace[2] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
		};

		const bool pixelOnEdge0 = pixelNearLineSegment(pixel, triangleScreenSpace[0], triangleScreenSpace[1]);
		const bool pixelOnEdge1 = pixelNearLineSegment(pixel, triangleScreenSpace[1], triangleScreenSpace[2]);
		const bool pixelOnEdge2 = pixelNearLineSegment(pixel, triangleScreenSpace[2], triangleScreenSpace[0]);

		// If the pixel is on a multiple edges return false

		if (pixelOnEdge0 && !pixelOnEdge1 && !pixelOnEdge2)
			return triangle.sharedEdge[0];
		if (!pixelOnEdge0 && pixelOnEdge1 && !pixelOnEdge2)
			return triangle.sharedEdge[1];
		if (!pixelOnEdge0 && !pixelOnEdge1 && pixelOnEdge2)
			return triangle.sharedEdge[2];
	}

	return false;
}

float triangleArea (const tcu::Vec2& s0, const tcu::Vec2& s1, const tcu::Vec2& s2)
{
	const tcu::Vec2	u				(s1.x() - s0.x(), s1.y() - s0.y());
	const tcu::Vec2	v				(s2.x() - s0.x(), s2.y() - s0.y());
	const float		crossProduct	= (u.x() * v.y() - u.y() * v.x());

	return crossProduct / 2.0f;
}

tcu::IVec4 getTriangleAABB (const TriangleSceneSpec::SceneTriangle& triangle, const tcu::IVec2& viewportSize)
{
	const tcu::Vec2 normalizedDeviceSpace[3] =
	{
		tcu::Vec2(triangle.positions[0].x() / triangle.positions[0].w(), triangle.positions[0].y() / triangle.positions[0].w()),
		tcu::Vec2(triangle.positions[1].x() / triangle.positions[1].w(), triangle.positions[1].y() / triangle.positions[1].w()),
		tcu::Vec2(triangle.positions[2].x() / triangle.positions[2].w(), triangle.positions[2].y() / triangle.positions[2].w()),
	};
	const tcu::Vec2 screenSpace[3] =
	{
		(normalizedDeviceSpace[0] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
		(normalizedDeviceSpace[1] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
		(normalizedDeviceSpace[2] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
	};

	tcu::IVec4 aabb;

	aabb.x() = (int)deFloatFloor(de::min(de::min(screenSpace[0].x(), screenSpace[1].x()), screenSpace[2].x()));
	aabb.y() = (int)deFloatFloor(de::min(de::min(screenSpace[0].y(), screenSpace[1].y()), screenSpace[2].y()));
	aabb.z() = (int)deFloatCeil (de::max(de::max(screenSpace[0].x(), screenSpace[1].x()), screenSpace[2].x()));
	aabb.w() = (int)deFloatCeil (de::max(de::max(screenSpace[0].y(), screenSpace[1].y()), screenSpace[2].y()));

	return aabb;
}

float getExponentEpsilonFromULP (int valueExponent, deUint32 ulp)
{
	DE_ASSERT(ulp < (1u<<10));

	// assume mediump precision, using ulp as ulps in a 10 bit mantissa
	return tcu::Float32::construct(+1, valueExponent, (1u<<23) + (ulp << (23 - 10))).asFloat() - tcu::Float32::construct(+1, valueExponent, (1u<<23)).asFloat();
}

float getValueEpsilonFromULP (float value, deUint32 ulp)
{
	DE_ASSERT(value != std::numeric_limits<float>::infinity() && value != -std::numeric_limits<float>::infinity());

	const int exponent = tcu::Float32(value).exponent();
	return getExponentEpsilonFromULP(exponent, ulp);
}

float getMaxValueWithinError (float value, deUint32 ulp)
{
	if (value == std::numeric_limits<float>::infinity() || value == -std::numeric_limits<float>::infinity())
		return value;

	return value + getValueEpsilonFromULP(value, ulp);
}

float getMinValueWithinError (float value, deUint32 ulp)
{
	if (value == std::numeric_limits<float>::infinity() || value == -std::numeric_limits<float>::infinity())
		return value;

	return value - getValueEpsilonFromULP(value, ulp);
}

float getMinFlushToZero (float value)
{
	// flush to zero if that decreases the value
	// assume mediump precision
	if (value > 0.0f && value < tcu::Float32::construct(+1, -14, 1u<<23).asFloat())
		return 0.0f;
	return value;
}

float getMaxFlushToZero (float value)
{
	// flush to zero if that increases the value
	// assume mediump precision
	if (value < 0.0f && value > tcu::Float32::construct(-1, -14, 1u<<23).asFloat())
		return 0.0f;
	return value;
}

tcu::IVec3 convertRGB8ToNativeFormat (const tcu::RGBA& color, const RasterizationArguments& args)
{
	tcu::IVec3 pixelNativeColor;

	for (int channelNdx = 0; channelNdx < 3; ++channelNdx)
	{
		const int channelBitCount	= (channelNdx == 0) ? (args.redBits) : (channelNdx == 1) ? (args.greenBits) : (args.blueBits);
		const int channelPixelValue	= (channelNdx == 0) ? (color.getRed()) : (channelNdx == 1) ? (color.getGreen()) : (color.getBlue());

		if (channelBitCount <= 8)
			pixelNativeColor[channelNdx] = channelPixelValue >> (8 - channelBitCount);
		else if (channelBitCount == 8)
			pixelNativeColor[channelNdx] = channelPixelValue;
		else
		{
			// just in case someone comes up with 8+ bits framebuffers pixel formats. But as
			// we can only read in rgba8, we have to guess the trailing bits. Guessing 0.
			pixelNativeColor[channelNdx] = channelPixelValue << (channelBitCount - 8);
		}
	}

	return pixelNativeColor;
}

/*--------------------------------------------------------------------*//*!
 * Returns the maximum value of x / y, where x c [minDividend, maxDividend]
 * and y c [minDivisor, maxDivisor]
 *//*--------------------------------------------------------------------*/
float maximalRangeDivision (float minDividend, float maxDividend, float minDivisor, float maxDivisor)
{
	DE_ASSERT(minDividend <= maxDividend);
	DE_ASSERT(minDivisor <= maxDivisor);

	// special cases
	if (minDividend == 0.0f && maxDividend == 0.0f)
		return 0.0f;
	if (minDivisor <= 0.0f && maxDivisor >= 0.0f)
		return std::numeric_limits<float>::infinity();

	return de::max(de::max(minDividend / minDivisor, minDividend / maxDivisor), de::max(maxDividend / minDivisor, maxDividend / maxDivisor));
}

/*--------------------------------------------------------------------*//*!
 * Returns the minimum value of x / y, where x c [minDividend, maxDividend]
 * and y c [minDivisor, maxDivisor]
 *//*--------------------------------------------------------------------*/
float minimalRangeDivision (float minDividend, float maxDividend, float minDivisor, float maxDivisor)
{
	DE_ASSERT(minDividend <= maxDividend);
	DE_ASSERT(minDivisor <= maxDivisor);

	// special cases
	if (minDividend == 0.0f && maxDividend == 0.0f)
		return 0.0f;
	if (minDivisor <= 0.0f && maxDivisor >= 0.0f)
		return -std::numeric_limits<float>::infinity();

	return de::min(de::min(minDividend / minDivisor, minDividend / maxDivisor), de::min(maxDividend / minDivisor, maxDividend / maxDivisor));
}

static bool isLineXMajor (const tcu::Vec2& lineScreenSpaceP0, const tcu::Vec2& lineScreenSpaceP1)
{
	return de::abs(lineScreenSpaceP1.x() - lineScreenSpaceP0.x()) >= de::abs(lineScreenSpaceP1.y() - lineScreenSpaceP0.y());
}

static bool isPackedSSLineXMajor (const tcu::Vec4& packedLine)
{
	const tcu::Vec2 lineScreenSpaceP0 = packedLine.swizzle(0, 1);
	const tcu::Vec2 lineScreenSpaceP1 = packedLine.swizzle(2, 3);

	return isLineXMajor(lineScreenSpaceP0, lineScreenSpaceP1);
}

struct InterpolationRange
{
	tcu::Vec3 max;
	tcu::Vec3 min;
};

struct LineInterpolationRange
{
	tcu::Vec2 max;
	tcu::Vec2 min;
};

InterpolationRange calcTriangleInterpolationWeights (const tcu::Vec4& p0, const tcu::Vec4& p1, const tcu::Vec4& p2, const tcu::Vec2& ndpixel)
{
	const int roundError		= 1;
	const int barycentricError	= 3;
	const int divError			= 8;

	const tcu::Vec2 nd0 = p0.swizzle(0, 1) / p0.w();
	const tcu::Vec2 nd1 = p1.swizzle(0, 1) / p1.w();
	const tcu::Vec2 nd2 = p2.swizzle(0, 1) / p2.w();

	const float ka = triangleArea(ndpixel, nd1, nd2);
	const float kb = triangleArea(ndpixel, nd2, nd0);
	const float kc = triangleArea(ndpixel, nd0, nd1);

	const float kaMax = getMaxFlushToZero(getMaxValueWithinError(ka, barycentricError));
	const float kbMax = getMaxFlushToZero(getMaxValueWithinError(kb, barycentricError));
	const float kcMax = getMaxFlushToZero(getMaxValueWithinError(kc, barycentricError));
	const float kaMin = getMinFlushToZero(getMinValueWithinError(ka, barycentricError));
	const float kbMin = getMinFlushToZero(getMinValueWithinError(kb, barycentricError));
	const float kcMin = getMinFlushToZero(getMinValueWithinError(kc, barycentricError));
	DE_ASSERT(kaMin <= kaMax);
	DE_ASSERT(kbMin <= kbMax);
	DE_ASSERT(kcMin <= kcMax);

	// calculate weights: vec3(ka / p0.w, kb / p1.w, kc / p2.w) / (ka / p0.w + kb / p1.w + kc / p2.w)
	const float maxPreDivisionValues[3] =
	{
		getMaxFlushToZero(getMaxValueWithinError(getMaxFlushToZero(kaMax / p0.w()), divError)),
		getMaxFlushToZero(getMaxValueWithinError(getMaxFlushToZero(kbMax / p1.w()), divError)),
		getMaxFlushToZero(getMaxValueWithinError(getMaxFlushToZero(kcMax / p2.w()), divError)),
	};
	const float minPreDivisionValues[3] =
	{
		getMinFlushToZero(getMinValueWithinError(getMinFlushToZero(kaMin / p0.w()), divError)),
		getMinFlushToZero(getMinValueWithinError(getMinFlushToZero(kbMin / p1.w()), divError)),
		getMinFlushToZero(getMinValueWithinError(getMinFlushToZero(kcMin / p2.w()), divError)),
	};
	DE_ASSERT(minPreDivisionValues[0] <= maxPreDivisionValues[0]);
	DE_ASSERT(minPreDivisionValues[1] <= maxPreDivisionValues[1]);
	DE_ASSERT(minPreDivisionValues[2] <= maxPreDivisionValues[2]);

	const float maxDivisor = getMaxFlushToZero(getMaxValueWithinError(maxPreDivisionValues[0] + maxPreDivisionValues[1] + maxPreDivisionValues[2], 2*roundError));
	const float minDivisor = getMinFlushToZero(getMinValueWithinError(minPreDivisionValues[0] + minPreDivisionValues[1] + minPreDivisionValues[2], 2*roundError));
	DE_ASSERT(minDivisor <= maxDivisor);

	InterpolationRange returnValue;

	returnValue.max.x() = getMaxFlushToZero(getMaxValueWithinError(getMaxFlushToZero(maximalRangeDivision(minPreDivisionValues[0], maxPreDivisionValues[0], minDivisor, maxDivisor)), divError));
	returnValue.max.y() = getMaxFlushToZero(getMaxValueWithinError(getMaxFlushToZero(maximalRangeDivision(minPreDivisionValues[1], maxPreDivisionValues[1], minDivisor, maxDivisor)), divError));
	returnValue.max.z() = getMaxFlushToZero(getMaxValueWithinError(getMaxFlushToZero(maximalRangeDivision(minPreDivisionValues[2], maxPreDivisionValues[2], minDivisor, maxDivisor)), divError));
	returnValue.min.x() = getMinFlushToZero(getMinValueWithinError(getMinFlushToZero(minimalRangeDivision(minPreDivisionValues[0], maxPreDivisionValues[0], minDivisor, maxDivisor)), divError));
	returnValue.min.y() = getMinFlushToZero(getMinValueWithinError(getMinFlushToZero(minimalRangeDivision(minPreDivisionValues[1], maxPreDivisionValues[1], minDivisor, maxDivisor)), divError));
	returnValue.min.z() = getMinFlushToZero(getMinValueWithinError(getMinFlushToZero(minimalRangeDivision(minPreDivisionValues[2], maxPreDivisionValues[2], minDivisor, maxDivisor)), divError));

	DE_ASSERT(returnValue.min.x() <= returnValue.max.x());
	DE_ASSERT(returnValue.min.y() <= returnValue.max.y());
	DE_ASSERT(returnValue.min.z() <= returnValue.max.z());

	return returnValue;
}

LineInterpolationRange calcLineInterpolationWeights (const tcu::Vec2& pa, float wa, const tcu::Vec2& pb, float wb, const tcu::Vec2& pr)
{
	const int roundError	= 1;
	const int divError		= 3;

	// calc weights:
	//			(1-t) / wa					t / wb
	//		-------------------	,	-------------------
	//		(1-t) / wa + t / wb		(1-t) / wa + t / wb

	// Allow 1 ULP
	const float		dividend	= tcu::dot(pr - pa, pb - pa);
	const float		dividendMax	= getMaxValueWithinError(dividend, 1);
	const float		dividendMin	= getMinValueWithinError(dividend, 1);
	DE_ASSERT(dividendMin <= dividendMax);

	// Assuming lengthSquared will not be implemented as sqrt(x)^2, allow 1 ULP
	const float		divisor		= tcu::lengthSquared(pb - pa);
	const float		divisorMax	= getMaxValueWithinError(divisor, 1);
	const float		divisorMin	= getMinValueWithinError(divisor, 1);
	DE_ASSERT(divisorMin <= divisorMax);

	// Allow 3 ULP precision for division
	const float		tMax		= getMaxValueWithinError(maximalRangeDivision(dividendMin, dividendMax, divisorMin, divisorMax), divError);
	const float		tMin		= getMinValueWithinError(minimalRangeDivision(dividendMin, dividendMax, divisorMin, divisorMax), divError);
	DE_ASSERT(tMin <= tMax);

	const float		perspectiveTMax			= getMaxValueWithinError(maximalRangeDivision(tMin, tMax, wb, wb), divError);
	const float		perspectiveTMin			= getMinValueWithinError(minimalRangeDivision(tMin, tMax, wb, wb), divError);
	DE_ASSERT(perspectiveTMin <= perspectiveTMax);

	const float		perspectiveInvTMax		= getMaxValueWithinError(maximalRangeDivision((1.0f - tMax), (1.0f - tMin), wa, wa), divError);
	const float		perspectiveInvTMin		= getMinValueWithinError(minimalRangeDivision((1.0f - tMax), (1.0f - tMin), wa, wa), divError);
	DE_ASSERT(perspectiveInvTMin <= perspectiveInvTMax);

	const float		perspectiveDivisorMax	= getMaxValueWithinError(perspectiveTMax + perspectiveInvTMax, roundError);
	const float		perspectiveDivisorMin	= getMinValueWithinError(perspectiveTMin + perspectiveInvTMin, roundError);
	DE_ASSERT(perspectiveDivisorMin <= perspectiveDivisorMax);

	LineInterpolationRange returnValue;
	returnValue.max.x() = getMaxValueWithinError(maximalRangeDivision(perspectiveInvTMin,	perspectiveInvTMax,	perspectiveDivisorMin, perspectiveDivisorMax), divError);
	returnValue.max.y() = getMaxValueWithinError(maximalRangeDivision(perspectiveTMin,		perspectiveTMax,	perspectiveDivisorMin, perspectiveDivisorMax), divError);
	returnValue.min.x() = getMinValueWithinError(minimalRangeDivision(perspectiveInvTMin,	perspectiveInvTMax,	perspectiveDivisorMin, perspectiveDivisorMax), divError);
	returnValue.min.y() = getMinValueWithinError(minimalRangeDivision(perspectiveTMin,		perspectiveTMax,	perspectiveDivisorMin, perspectiveDivisorMax), divError);

	DE_ASSERT(returnValue.min.x() <= returnValue.max.x());
	DE_ASSERT(returnValue.min.y() <= returnValue.max.y());

	return returnValue;
}

LineInterpolationRange calcLineInterpolationWeightsAxisProjected (const tcu::Vec2& pa, float wa, const tcu::Vec2& pb, float wb, const tcu::Vec2& pr)
{
	const int	roundError		= 1;
	const int	divError		= 3;
	const bool	isXMajor		= isLineXMajor(pa, pb);
	const int	majorAxisNdx	= (isXMajor) ? (0) : (1);

	// calc weights:
	//			(1-t) / wa					t / wb
	//		-------------------	,	-------------------
	//		(1-t) / wa + t / wb		(1-t) / wa + t / wb

	// Use axis projected (inaccurate) method, i.e. for X-major lines:
	//     (xd - xa) * (xb - xa)      xd - xa
	// t = ---------------------  ==  -------
	//       ( xb - xa ) ^ 2          xb - xa

	// Allow 1 ULP
	const float		dividend	= (pr[majorAxisNdx] - pa[majorAxisNdx]);
	const float		dividendMax	= getMaxValueWithinError(dividend, 1);
	const float		dividendMin	= getMinValueWithinError(dividend, 1);
	DE_ASSERT(dividendMin <= dividendMax);

	// Allow 1 ULP
	const float		divisor		= (pb[majorAxisNdx] - pa[majorAxisNdx]);
	const float		divisorMax	= getMaxValueWithinError(divisor, 1);
	const float		divisorMin	= getMinValueWithinError(divisor, 1);
	DE_ASSERT(divisorMin <= divisorMax);

	// Allow 3 ULP precision for division
	const float		tMax		= getMaxValueWithinError(maximalRangeDivision(dividendMin, dividendMax, divisorMin, divisorMax), divError);
	const float		tMin		= getMinValueWithinError(minimalRangeDivision(dividendMin, dividendMax, divisorMin, divisorMax), divError);
	DE_ASSERT(tMin <= tMax);

	const float		perspectiveTMax			= getMaxValueWithinError(maximalRangeDivision(tMin, tMax, wb, wb), divError);
	const float		perspectiveTMin			= getMinValueWithinError(minimalRangeDivision(tMin, tMax, wb, wb), divError);
	DE_ASSERT(perspectiveTMin <= perspectiveTMax);

	const float		perspectiveInvTMax		= getMaxValueWithinError(maximalRangeDivision((1.0f - tMax), (1.0f - tMin), wa, wa), divError);
	const float		perspectiveInvTMin		= getMinValueWithinError(minimalRangeDivision((1.0f - tMax), (1.0f - tMin), wa, wa), divError);
	DE_ASSERT(perspectiveInvTMin <= perspectiveInvTMax);

	const float		perspectiveDivisorMax	= getMaxValueWithinError(perspectiveTMax + perspectiveInvTMax, roundError);
	const float		perspectiveDivisorMin	= getMinValueWithinError(perspectiveTMin + perspectiveInvTMin, roundError);
	DE_ASSERT(perspectiveDivisorMin <= perspectiveDivisorMax);

	LineInterpolationRange returnValue;
	returnValue.max.x() = getMaxValueWithinError(maximalRangeDivision(perspectiveInvTMin,	perspectiveInvTMax,	perspectiveDivisorMin, perspectiveDivisorMax), divError);
	returnValue.max.y() = getMaxValueWithinError(maximalRangeDivision(perspectiveTMin,		perspectiveTMax,	perspectiveDivisorMin, perspectiveDivisorMax), divError);
	returnValue.min.x() = getMinValueWithinError(minimalRangeDivision(perspectiveInvTMin,	perspectiveInvTMax,	perspectiveDivisorMin, perspectiveDivisorMax), divError);
	returnValue.min.y() = getMinValueWithinError(minimalRangeDivision(perspectiveTMin,		perspectiveTMax,	perspectiveDivisorMin, perspectiveDivisorMax), divError);

	DE_ASSERT(returnValue.min.x() <= returnValue.max.x());
	DE_ASSERT(returnValue.min.y() <= returnValue.max.y());

	return returnValue;
}

template <typename WeightEquation>
LineInterpolationRange calcSingleSampleLineInterpolationRangeWithWeightEquation (const tcu::Vec2&	pa,
																				 float				wa,
																				 const tcu::Vec2&	pb,
																				 float				wb,
																				 const tcu::IVec2&	pixel,
																				 int				subpixelBits,
																				 WeightEquation		weightEquation)
{
	// allow interpolation weights anywhere in the central subpixels
	const float testSquareSize = (2.0f / (float)(1UL << subpixelBits));
	const float testSquarePos  = (0.5f - testSquareSize / 2);

	const tcu::Vec2 corners[4] =
	{
		tcu::Vec2((float)pixel.x() + testSquarePos + 0.0f,				(float)pixel.y() + testSquarePos + 0.0f),
		tcu::Vec2((float)pixel.x() + testSquarePos + 0.0f,				(float)pixel.y() + testSquarePos + testSquareSize),
		tcu::Vec2((float)pixel.x() + testSquarePos + testSquareSize,	(float)pixel.y() + testSquarePos + testSquareSize),
		tcu::Vec2((float)pixel.x() + testSquarePos + testSquareSize,	(float)pixel.y() + testSquarePos + 0.0f),
	};

	// calculate interpolation as a line
	const LineInterpolationRange weights[4] =
	{
		weightEquation(pa, wa, pb, wb, corners[0]),
		weightEquation(pa, wa, pb, wb, corners[1]),
		weightEquation(pa, wa, pb, wb, corners[2]),
		weightEquation(pa, wa, pb, wb, corners[3]),
	};

	const tcu::Vec2 minWeights = tcu::min(tcu::min(weights[0].min, weights[1].min), tcu::min(weights[2].min, weights[3].min));
	const tcu::Vec2 maxWeights = tcu::max(tcu::max(weights[0].max, weights[1].max), tcu::max(weights[2].max, weights[3].max));

	LineInterpolationRange result;
	result.min = minWeights;
	result.max = maxWeights;
	return result;
}

LineInterpolationRange calcSingleSampleLineInterpolationRange (const tcu::Vec2& pa, float wa, const tcu::Vec2& pb, float wb, const tcu::IVec2& pixel, int subpixelBits)
{
	return calcSingleSampleLineInterpolationRangeWithWeightEquation(pa, wa, pb, wb, pixel, subpixelBits, calcLineInterpolationWeights);
}

LineInterpolationRange calcSingleSampleLineInterpolationRangeAxisProjected (const tcu::Vec2& pa, float wa, const tcu::Vec2& pb, float wb, const tcu::IVec2& pixel, int subpixelBits)
{
	return calcSingleSampleLineInterpolationRangeWithWeightEquation(pa, wa, pb, wb, pixel, subpixelBits, calcLineInterpolationWeightsAxisProjected);
}

struct TriangleInterpolator
{
	const TriangleSceneSpec& scene;

	TriangleInterpolator (const TriangleSceneSpec& scene_)
		: scene(scene_)
	{
	}

	InterpolationRange interpolate (int primitiveNdx, const tcu::IVec2 pixel, const tcu::IVec2 viewportSize, bool multisample, int subpixelBits) const
	{
		// allow anywhere in the pixel area in multisample
		// allow only in the center subpixels (4 subpixels) in singlesample
		const float testSquareSize = (multisample) ? (1.0f) : (2.0f / (float)(1UL << subpixelBits));
		const float testSquarePos  = (multisample) ? (0.0f) : (0.5f - testSquareSize / 2);
		const tcu::Vec2 corners[4] =
		{
			tcu::Vec2(((float)pixel.x() + testSquarePos + 0.0f)           / (float)viewportSize.x() * 2.0f - 1.0f, ((float)pixel.y() + testSquarePos + 0.0f          ) / (float)viewportSize.y() * 2.0f - 1.0f),
			tcu::Vec2(((float)pixel.x() + testSquarePos + 0.0f)           / (float)viewportSize.x() * 2.0f - 1.0f, ((float)pixel.y() + testSquarePos + testSquareSize) / (float)viewportSize.y() * 2.0f - 1.0f),
			tcu::Vec2(((float)pixel.x() + testSquarePos + testSquareSize) / (float)viewportSize.x() * 2.0f - 1.0f, ((float)pixel.y() + testSquarePos + testSquareSize) / (float)viewportSize.y() * 2.0f - 1.0f),
			tcu::Vec2(((float)pixel.x() + testSquarePos + testSquareSize) / (float)viewportSize.x() * 2.0f - 1.0f, ((float)pixel.y() + testSquarePos + 0.0f          ) / (float)viewportSize.y() * 2.0f - 1.0f),
		};
		const InterpolationRange weights[4] =
		{
			calcTriangleInterpolationWeights(scene.triangles[primitiveNdx].positions[0], scene.triangles[primitiveNdx].positions[1], scene.triangles[primitiveNdx].positions[2], corners[0]),
			calcTriangleInterpolationWeights(scene.triangles[primitiveNdx].positions[0], scene.triangles[primitiveNdx].positions[1], scene.triangles[primitiveNdx].positions[2], corners[1]),
			calcTriangleInterpolationWeights(scene.triangles[primitiveNdx].positions[0], scene.triangles[primitiveNdx].positions[1], scene.triangles[primitiveNdx].positions[2], corners[2]),
			calcTriangleInterpolationWeights(scene.triangles[primitiveNdx].positions[0], scene.triangles[primitiveNdx].positions[1], scene.triangles[primitiveNdx].positions[2], corners[3]),
		};

		InterpolationRange result;
		result.min = tcu::min(tcu::min(weights[0].min, weights[1].min), tcu::min(weights[2].min, weights[3].min));
		result.max = tcu::max(tcu::max(weights[0].max, weights[1].max), tcu::max(weights[2].max, weights[3].max));
		return result;
	}
};

/*--------------------------------------------------------------------*//*!
 * Used only by verifyMultisampleLineGroupInterpolation to calculate
 * correct line interpolations for the triangulated lines.
 *//*--------------------------------------------------------------------*/
struct MultisampleLineInterpolator
{
	const LineSceneSpec& scene;

	MultisampleLineInterpolator (const LineSceneSpec& scene_)
		: scene(scene_)
	{
	}

	InterpolationRange interpolate (int primitiveNdx, const tcu::IVec2 pixel, const tcu::IVec2 viewportSize, bool multisample, int subpixelBits) const
	{
		DE_UNREF(multisample);
		DE_UNREF(subpixelBits);

		// in triangulation, one line emits two triangles
		const int		lineNdx		= primitiveNdx / 2;

		// allow interpolation weights anywhere in the pixel
		const tcu::Vec2 corners[4] =
		{
			tcu::Vec2((float)pixel.x() + 0.0f, (float)pixel.y() + 0.0f),
			tcu::Vec2((float)pixel.x() + 0.0f, (float)pixel.y() + 1.0f),
			tcu::Vec2((float)pixel.x() + 1.0f, (float)pixel.y() + 1.0f),
			tcu::Vec2((float)pixel.x() + 1.0f, (float)pixel.y() + 0.0f),
		};

		const float		wa = scene.lines[lineNdx].positions[0].w();
		const float		wb = scene.lines[lineNdx].positions[1].w();
		const tcu::Vec2	pa = tcu::Vec2((scene.lines[lineNdx].positions[0].x() / wa + 1.0f) * 0.5f * (float)viewportSize.x(),
									   (scene.lines[lineNdx].positions[0].y() / wa + 1.0f) * 0.5f * (float)viewportSize.y());
		const tcu::Vec2	pb = tcu::Vec2((scene.lines[lineNdx].positions[1].x() / wb + 1.0f) * 0.5f * (float)viewportSize.x(),
									   (scene.lines[lineNdx].positions[1].y() / wb + 1.0f) * 0.5f * (float)viewportSize.y());

		// calculate interpolation as a line
		const LineInterpolationRange weights[4] =
		{
			calcLineInterpolationWeights(pa, wa, pb, wb, corners[0]),
			calcLineInterpolationWeights(pa, wa, pb, wb, corners[1]),
			calcLineInterpolationWeights(pa, wa, pb, wb, corners[2]),
			calcLineInterpolationWeights(pa, wa, pb, wb, corners[3]),
		};

		const tcu::Vec2 minWeights = tcu::min(tcu::min(weights[0].min, weights[1].min), tcu::min(weights[2].min, weights[3].min));
		const tcu::Vec2 maxWeights = tcu::max(tcu::max(weights[0].max, weights[1].max), tcu::max(weights[2].max, weights[3].max));

		// convert to three-component form. For all triangles, the vertex 0 is always emitted by the line starting point, and vertex 2 by the ending point
		InterpolationRange result;
		result.min = tcu::Vec3(minWeights.x(), 0.0f, minWeights.y());
		result.max = tcu::Vec3(maxWeights.x(), 0.0f, maxWeights.y());
		return result;
	}
};

template <typename Interpolator>
bool verifyTriangleGroupInterpolationWithInterpolator (const tcu::Surface&							surface,
													   const TriangleSceneSpec&						scene,
													   const RasterizationArguments&				args,
													   VerifyTriangleGroupInterpolationLogStash&	logStash,
													   const Interpolator&							interpolator)
{
	const tcu::RGBA		invalidPixelColor	= tcu::RGBA(255, 0, 0, 255);
	const bool			multisampled		= (args.numSamples != 0);
	const tcu::IVec2	viewportSize		= tcu::IVec2(surface.getWidth(), surface.getHeight());
	const int			errorFloodThreshold	= 4;
	int					errorCount			= 0;
	int					invalidPixels		= 0;
	int					subPixelBits		= args.subpixelBits;
	tcu::Surface		errorMask			(surface.getWidth(), surface.getHeight());

	tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	// log format

	logStash.messages.push_back(std::string("Verifying rasterization result. Native format is RGB" + de::toString(args.redBits) + de::toString(args.greenBits) + de::toString(args.blueBits)));
	if (args.redBits > 8 || args.greenBits > 8 || args.blueBits > 8)
		logStash.messages.push_back(std::string("Warning! More than 8 bits in a color channel, this may produce false negatives."));

	// subpixel bits in a valid range?

	if (subPixelBits < 0)
	{
		logStash.messages.push_back(std::string("Invalid subpixel count (" + de::toString(subPixelBits) + "), assuming 0"));
		subPixelBits = 0;
	}
	else if (subPixelBits > 16)
	{
		// At high subpixel bit counts we might overflow. Checking at lower bit count is ok, but is less strict
		logStash.messages.push_back(std::string("Subpixel count is greater than 16 (" + de::toString(subPixelBits) + ")."
												" Checking results using less strict 16 bit requirements. This may produce false positives."));
		subPixelBits = 16;
	}

	// check pixels

	for (int y = 0; y < surface.getHeight(); ++y)
	for (int x = 0; x < surface.getWidth();  ++x)
	{
		const tcu::RGBA		color				= surface.getPixel(x, y);
		bool				stackBottomFound	= false;
		int					stackSize			= 0;
		tcu::Vec4			colorStackMin;
		tcu::Vec4			colorStackMax;

		// Iterate triangle coverage front to back, find the stack of pontentially contributing fragments
		for (int triNdx = (int)scene.triangles.size() - 1; triNdx >= 0; --triNdx)
		{
			const CoverageType coverage = calculateTriangleCoverage(scene.triangles[triNdx].positions[0],
																	scene.triangles[triNdx].positions[1],
																	scene.triangles[triNdx].positions[2],
																	tcu::IVec2(x, y),
																	viewportSize,
																	subPixelBits,
																	multisampled);

			if (coverage == COVERAGE_FULL || coverage == COVERAGE_PARTIAL)
			{
				// potentially contributes to the result fragment's value
				const InterpolationRange weights = interpolator.interpolate(triNdx, tcu::IVec2(x, y), viewportSize, multisampled, subPixelBits);

				const tcu::Vec4 fragmentColorMax =	de::clamp(weights.max.x(), 0.0f, 1.0f) * scene.triangles[triNdx].colors[0] +
													de::clamp(weights.max.y(), 0.0f, 1.0f) * scene.triangles[triNdx].colors[1] +
													de::clamp(weights.max.z(), 0.0f, 1.0f) * scene.triangles[triNdx].colors[2];
				const tcu::Vec4 fragmentColorMin =	de::clamp(weights.min.x(), 0.0f, 1.0f) * scene.triangles[triNdx].colors[0] +
													de::clamp(weights.min.y(), 0.0f, 1.0f) * scene.triangles[triNdx].colors[1] +
													de::clamp(weights.min.z(), 0.0f, 1.0f) * scene.triangles[triNdx].colors[2];

				if (stackSize++ == 0)
				{
					// first triangle, set the values properly
					colorStackMin = fragmentColorMin;
					colorStackMax = fragmentColorMax;
				}
				else
				{
					// contributing triangle
					colorStackMin = tcu::min(colorStackMin, fragmentColorMin);
					colorStackMax = tcu::max(colorStackMax, fragmentColorMax);
				}

				if (coverage == COVERAGE_FULL)
				{
					// loop terminates, this is the bottommost fragment
					stackBottomFound = true;
					break;
				}
			}
		}

		// Partial coverage == background may be visible
		if (stackSize != 0 && !stackBottomFound)
		{
			stackSize++;
			colorStackMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
		}

		// Is the result image color in the valid range.
		if (stackSize == 0)
		{
			// No coverage, allow only background (black, value=0)
			const tcu::IVec3	pixelNativeColor	= convertRGB8ToNativeFormat(color, args);
			const int			threshold			= 1;

			if (pixelNativeColor.x() > threshold ||
				pixelNativeColor.y() > threshold ||
				pixelNativeColor.z() > threshold)
			{
				++errorCount;

				// don't fill the logs with too much data
				if (errorCount < errorFloodThreshold)
				{
					std::ostringstream str;

					str << "Found an invalid pixel at (" << x << "," << y << ")\n"
						<< "\tPixel color:\t\t" << color << "\n"
						<< "\tExpected background color.\n";

					logStash.messages.push_back(str.str());
				}

				++invalidPixels;
				errorMask.setPixel(x, y, invalidPixelColor);
			}
		}
		else
		{
			DE_ASSERT(stackSize);

			// Each additional step in the stack may cause conversion error of 1 bit due to undefined rounding direction
			const int			thresholdRed	= stackSize - 1;
			const int			thresholdGreen	= stackSize - 1;
			const int			thresholdBlue	= stackSize - 1;

			const tcu::Vec3		valueRangeMin	= tcu::Vec3(colorStackMin.xyz());
			const tcu::Vec3		valueRangeMax	= tcu::Vec3(colorStackMax.xyz());

			const tcu::IVec3	formatLimit		((1 << args.redBits) - 1, (1 << args.greenBits) - 1, (1 << args.blueBits) - 1);
			const tcu::Vec3		colorMinF		(de::clamp(valueRangeMin.x() * (float)formatLimit.x(), 0.0f, (float)formatLimit.x()),
												 de::clamp(valueRangeMin.y() * (float)formatLimit.y(), 0.0f, (float)formatLimit.y()),
												 de::clamp(valueRangeMin.z() * (float)formatLimit.z(), 0.0f, (float)formatLimit.z()));
			const tcu::Vec3		colorMaxF		(de::clamp(valueRangeMax.x() * (float)formatLimit.x(), 0.0f, (float)formatLimit.x()),
												 de::clamp(valueRangeMax.y() * (float)formatLimit.y(), 0.0f, (float)formatLimit.y()),
												 de::clamp(valueRangeMax.z() * (float)formatLimit.z(), 0.0f, (float)formatLimit.z()));
			const tcu::IVec3	colorMin		((int)deFloatFloor(colorMinF.x()),
												 (int)deFloatFloor(colorMinF.y()),
												 (int)deFloatFloor(colorMinF.z()));
			const tcu::IVec3	colorMax		((int)deFloatCeil (colorMaxF.x()),
												 (int)deFloatCeil (colorMaxF.y()),
												 (int)deFloatCeil (colorMaxF.z()));

			// Convert pixel color from rgba8 to the real pixel format. Usually rgba8 or 565
			const tcu::IVec3 pixelNativeColor = convertRGB8ToNativeFormat(color, args);

			// Validity check
			if (pixelNativeColor.x() < colorMin.x() - thresholdRed   ||
				pixelNativeColor.y() < colorMin.y() - thresholdGreen ||
				pixelNativeColor.z() < colorMin.z() - thresholdBlue  ||
				pixelNativeColor.x() > colorMax.x() + thresholdRed   ||
				pixelNativeColor.y() > colorMax.y() + thresholdGreen ||
				pixelNativeColor.z() > colorMax.z() + thresholdBlue)
			{
				++errorCount;

				// don't fill the logs with too much data
				if (errorCount <= errorFloodThreshold)
				{
					std::ostringstream str;

					str << "Found an invalid pixel at (" << x << "," << y << ")\n"
						<< "\tPixel color:\t\t" << color << "\n"
						<< "\tNative color:\t\t" << pixelNativeColor << "\n"
						<< "\tAllowed error:\t\t" << tcu::IVec3(thresholdRed, thresholdGreen, thresholdBlue) << "\n"
						<< "\tReference native color min: " << tcu::clamp(colorMin - tcu::IVec3(thresholdRed, thresholdGreen, thresholdBlue), tcu::IVec3(0,0,0), formatLimit) << "\n"
						<< "\tReference native color max: " << tcu::clamp(colorMax + tcu::IVec3(thresholdRed, thresholdGreen, thresholdBlue), tcu::IVec3(0,0,0), formatLimit) << "\n"
						<< "\tReference native float min: " << tcu::clamp(colorMinF - tcu::IVec3(thresholdRed, thresholdGreen, thresholdBlue).cast<float>(), tcu::Vec3(0.0f, 0.0f, 0.0f), formatLimit.cast<float>()) << "\n"
						<< "\tReference native float max: " << tcu::clamp(colorMaxF + tcu::IVec3(thresholdRed, thresholdGreen, thresholdBlue).cast<float>(), tcu::Vec3(0.0f, 0.0f, 0.0f), formatLimit.cast<float>()) << "\n"
						<< "\tFmin:\t" << tcu::clamp(valueRangeMin, tcu::Vec3(0.0f, 0.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 1.0f)) << "\n"
						<< "\tFmax:\t" << tcu::clamp(valueRangeMax, tcu::Vec3(0.0f, 0.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 1.0f)) << "\n";
					logStash.messages.push_back(str.str());
				}

				++invalidPixels;
				errorMask.setPixel(x, y, invalidPixelColor);
			}
		}
	}

	// don't just hide failures
	if (errorCount > errorFloodThreshold)
		logStash.messages.push_back(std::string("Omitted " + de::toString(errorCount - errorFloodThreshold) + " pixel error description(s)."));

	logStash.success		= (invalidPixels == 0);
	logStash.invalidPixels	= invalidPixels;

	// report result
	if (!logStash.success)
		logStash.errorMask = errorMask;

	return logStash.success;
}


float calculateIntersectionParameter (const tcu::Vec2 line[2], float w, int componentNdx)
{
	DE_ASSERT(componentNdx < 2);
	if (line[1][componentNdx] == line[0][componentNdx])
		return -1.0f;

	return (w - line[0][componentNdx]) / (line[1][componentNdx] - line[0][componentNdx]);
}

// Clips the given line with a ((-w, -w), (-w, w), (w, w), (w, -w)) rectangle
void applyClippingBox (tcu::Vec2 line[2], float w)
{
	for (int side = 0; side < 4; ++side)
	{
		const int	sign		= ((side / 2) * -2) + 1;
		const int	component	= side % 2;
		const float	t			= calculateIntersectionParameter(line, w * (float)sign, component);

		if ((t > 0) && (t < 1))
		{
			const float newCoord	= t * line[1][1 - component] + (1 - t) * line[0][1 - component];

			if (line[1][component] > (w * (float)sign))
			{
				line[1 - side / 2][component] = w * (float)sign;
				line[1 - side / 2][1 - component] = newCoord;
			}
			else
			{
				line[side / 2][component] = w * (float)sign;
				line[side / 2][1 - component] = newCoord;
			}
		}
	}
}

enum ClipMode
{
	CLIPMODE_NO_CLIPPING = 0,
	CLIPMODE_USE_CLIPPING_BOX,

	CLIPMODE_LAST
};

bool verifyMultisampleLineGroupRasterization (const tcu::Surface&						surface,
											  const LineSceneSpec&						scene,
											  const RasterizationArguments&				args,
											  tcu::TestLog&								log,
											  ClipMode									clipMode,
											  VerifyTriangleGroupRasterizationLogStash*	logStash,
											  const bool								vulkanLinesTest,
											  const bool								strictMode,
											  const bool								carryRemainder)
{
	// Multisampled line == 2 triangles

	const tcu::Vec2		viewportSize	= tcu::Vec2((float)surface.getWidth(), (float)surface.getHeight());
	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] =
		{
			tcu::Vec2(scene.lines[lineNdx].positions[0].x() / scene.lines[lineNdx].positions[0].w(), scene.lines[lineNdx].positions[0].y() / scene.lines[lineNdx].positions[0].w()),
			tcu::Vec2(scene.lines[lineNdx].positions[1].x() / scene.lines[lineNdx].positions[1].w(), scene.lines[lineNdx].positions[1].y() / scene.lines[lineNdx].positions[1].w()),
		};

		if (clipMode == CLIPMODE_USE_CLIPPING_BOX)
		{
			applyClippingBox(lineNormalizedDeviceSpace, 1.0f);
		}

		const tcu::Vec2 lineScreenSpace[2] =
		{
			(lineNormalizedDeviceSpace[0] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * viewportSize,
			(lineNormalizedDeviceSpace[1] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * viewportSize,
		};

		const tcu::Vec2 lineDir			= tcu::normalize(lineScreenSpace[1] - lineScreenSpace[0]);
		const tcu::Vec2 lineNormalDir	= (strictMode || scene.isRectangular) ? tcu::Vec2(lineDir.y(), -lineDir.x())
										: isLineXMajor(lineScreenSpace[0], lineScreenSpace[1]) ? tcu::Vec2(0.0f, 1.0f)
										: tcu::Vec2(1.0f, 0.0f);

		if (scene.stippleEnable)
		{
			float lineLength			= tcu::distance(lineScreenSpace[0], lineScreenSpace[1]);
			float lineOffset			= 0.0f;

			while (lineOffset < lineLength)
			{
				float d0 = (float)lineOffset;
				float d1 = d0 + 1.0f;

				if (carryRemainder)
				{
					// "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;
					}
				}
				else
				{
					if (d1 > lineLength)
						d1 = lineLength;
				}

				// 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;
		}
	}

	if (logStash != DE_NULL)
	{
		logStash->messages.push_back("Rasterization clipping mode: " + std::string(clipMode == CLIPMODE_USE_CLIPPING_BOX ? "CLIPMODE_USE_CLIPPING_BOX" : "CLIPMODE_NO_CLIPPING") + ".");
		logStash->messages.push_back("Rasterization line draw strictness mode: " + std::string(strictMode ? "strict" : "non-strict") + ".");
	}

	return verifyTriangleGroupRasterization(surface, triangleScene, args, log, scene.verificationMode, logStash, vulkanLinesTest);
}

bool verifyMultisampleLineGroupRasterization (const tcu::Surface&						surface,
											  const LineSceneSpec&						scene,
											  const RasterizationArguments&				args,
											  tcu::TestLog&								log,
											  ClipMode									clipMode,
											  VerifyTriangleGroupRasterizationLogStash*	logStash,
											  const bool								vulkanLinesTest,
											  const bool								strictMode)
{
	if (scene.stippleEnable)
		return verifyMultisampleLineGroupRasterization(surface, scene, args, log, clipMode, logStash, vulkanLinesTest, strictMode, true) ||
		       verifyMultisampleLineGroupRasterization(surface, scene, args, log, clipMode, logStash, vulkanLinesTest, strictMode, false);
	else
		return verifyMultisampleLineGroupRasterization(surface, scene, args, log, clipMode, logStash, vulkanLinesTest, strictMode, true);
}

static bool verifyMultisampleLineGroupInterpolationInternal (const tcu::Surface&						surface,
													  const LineSceneSpec&						scene,
													  const RasterizationArguments&				args,
													  VerifyTriangleGroupInterpolationLogStash&	logStash,
													  const bool								strictMode)
{
	// Multisampled line == 2 triangles

	const tcu::Vec2		viewportSize	= tcu::Vec2((float)surface.getWidth(), (float)surface.getHeight());
	const float			halfLineWidth	= scene.lineWidth * 0.5f;
	TriangleSceneSpec	triangleScene;

	triangleScene.triangles.resize(2 * scene.lines.size());
	for (int lineNdx = 0; lineNdx < (int)scene.lines.size(); ++lineNdx)
	{
		// Need the w-coordinates a couple of times
		const float		wa = scene.lines[lineNdx].positions[0].w();
		const float		wb = scene.lines[lineNdx].positions[1].w();

		// Transform to screen space, add pixel offsets, convert back to normalized device space, and test as triangles
		const tcu::Vec2 lineNormalizedDeviceSpace[2] =
		{
			tcu::Vec2(scene.lines[lineNdx].positions[0].x() / wa, scene.lines[lineNdx].positions[0].y() / wa),
			tcu::Vec2(scene.lines[lineNdx].positions[1].x() / wb, scene.lines[lineNdx].positions[1].y() / wb),
		};
		const tcu::Vec2 lineScreenSpace[2] =
		{
			(lineNormalizedDeviceSpace[0] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * viewportSize,
			(lineNormalizedDeviceSpace[1] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * viewportSize,
		};

		const tcu::Vec2 lineDir			= tcu::normalize(lineScreenSpace[1] - lineScreenSpace[0]);
		const tcu::Vec2 lineNormalDir	= (strictMode || scene.isRectangular) ? tcu::Vec2(lineDir.y(), -lineDir.x())
										: isLineXMajor(lineScreenSpace[0], lineScreenSpace[1]) ? tcu::Vec2(0.0f, 1.0f)
										: tcu::Vec2(1.0f, 0.0f);

		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),
		};

		// Re-construct un-projected geometry using the quantised positions
		const tcu::Vec4 lineQuadUnprojected[4] =
		{
			tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x() * wa, lineQuadNormalizedDeviceSpace[0].y() * wa, 0.0f, wa),
			tcu::Vec4(lineQuadNormalizedDeviceSpace[1].x() * wa, lineQuadNormalizedDeviceSpace[1].y() * wa, 0.0f, wa),
			tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x() * wb, lineQuadNormalizedDeviceSpace[2].y() * wb, 0.0f, wb),
			tcu::Vec4(lineQuadNormalizedDeviceSpace[3].x() * wb, lineQuadNormalizedDeviceSpace[3].y() * wb, 0.0f, wb),
		};

		triangleScene.triangles[lineNdx*2 + 0].positions[0] = lineQuadUnprojected[0];
		triangleScene.triangles[lineNdx*2 + 0].positions[1] = lineQuadUnprojected[1];
		triangleScene.triangles[lineNdx*2 + 0].positions[2] = lineQuadUnprojected[2];

		triangleScene.triangles[lineNdx*2 + 0].sharedEdge[0] = false;
		triangleScene.triangles[lineNdx*2 + 0].sharedEdge[1] = false;
		triangleScene.triangles[lineNdx*2 + 0].sharedEdge[2] = true;

		triangleScene.triangles[lineNdx*2 + 0].colors[0] = scene.lines[lineNdx].colors[0];
		triangleScene.triangles[lineNdx*2 + 0].colors[1] = scene.lines[lineNdx].colors[0];
		triangleScene.triangles[lineNdx*2 + 0].colors[2] = scene.lines[lineNdx].colors[1];

		triangleScene.triangles[lineNdx*2 + 1].positions[0] = lineQuadUnprojected[0];
		triangleScene.triangles[lineNdx*2 + 1].positions[1] = lineQuadUnprojected[2];
		triangleScene.triangles[lineNdx*2 + 1].positions[2] = lineQuadUnprojected[3];

		triangleScene.triangles[lineNdx*2 + 1].sharedEdge[0] = true;
		triangleScene.triangles[lineNdx*2 + 1].sharedEdge[1] = false;
		triangleScene.triangles[lineNdx*2 + 1].sharedEdge[2] = false;

		triangleScene.triangles[lineNdx*2 + 1].colors[0] = scene.lines[lineNdx].colors[0];
		triangleScene.triangles[lineNdx*2 + 1].colors[1] = scene.lines[lineNdx].colors[1];
		triangleScene.triangles[lineNdx*2 + 1].colors[2] = scene.lines[lineNdx].colors[1];
	}

	if (strictMode)
	{
		// Strict mode interpolation should be purely in the direction of the line-segment
		logStash.messages.push_back("Verify using line interpolator");
		return verifyTriangleGroupInterpolationWithInterpolator(surface, triangleScene, args, logStash, MultisampleLineInterpolator(scene));
	}
	else
	{
		// For non-strict lines some allowance needs to be inplace for a few different styles of implementation.
		//
		// Some implementations duplicate the attributes at the endpoints to the corners of the triangle
		// deconstruted parallelogram. Gradients along the line will be seen to travel in the major axis,
		// with values effectively duplicated in the minor axis direction. In other cases, implementations
		// will use the original parameters of the line to calculate attribute interpolation so it will
		// follow the direction of the line-segment.
		logStash.messages.push_back("Verify using triangle interpolator");
		if (!verifyTriangleGroupInterpolationWithInterpolator(surface, triangleScene, args, logStash, TriangleInterpolator(triangleScene)))
		{
			logStash.messages.push_back("Verify using line interpolator");
			return verifyTriangleGroupInterpolationWithInterpolator(surface, triangleScene, args, logStash, MultisampleLineInterpolator(scene));
		}
		return true;
	}
}

static void logTriangleGroupnterpolationStash (const tcu::Surface& surface, tcu::TestLog& log, VerifyTriangleGroupInterpolationLogStash& logStash)
{
	// Output results
	log << tcu::TestLog::Message << "Verifying rasterization result." << tcu::TestLog::EndMessage;

	for (size_t msgNdx = 0; msgNdx < logStash.messages.size(); ++msgNdx)
		log << tcu::TestLog::Message << logStash.messages[msgNdx] << tcu::TestLog::EndMessage;

	// report result
	if (!logStash.success)
	{
		log << tcu::TestLog::Message << logStash.invalidPixels << " invalid pixel(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",	logStash.errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", surface)
			<< tcu::TestLog::EndImageSet;
	}
}

static bool verifyMultisampleLineGroupInterpolation (const tcu::Surface&			surface,
													 const LineSceneSpec&			scene,
													 const RasterizationArguments&	args,
													 tcu::TestLog&					log,
													 const bool						strictMode = true,
													 const bool						allowBresenhamForNonStrictLines = false)
{
	bool										result					= false;
	VerifyTriangleGroupInterpolationLogStash	nonStrictModeLogStash;
	VerifyTriangleGroupInterpolationLogStash	strictModeLogStash;

	nonStrictModeLogStash.messages.push_back("Non-strict line draw mode.");
	strictModeLogStash.messages.push_back("Strict mode line draw mode.");

	if (strictMode)
	{
		result = verifyMultisampleLineGroupInterpolationInternal(surface,scene, args, strictModeLogStash, strictMode);

		logTriangleGroupnterpolationStash(surface, log, strictModeLogStash);
	}
	else
	{
		if (verifyMultisampleLineGroupInterpolationInternal(surface,scene, args, nonStrictModeLogStash, false))
		{
			logTriangleGroupnterpolationStash(surface, log, nonStrictModeLogStash);

			result	= true;
		}
		else if (verifyMultisampleLineGroupInterpolationInternal(surface,scene, args, strictModeLogStash, true))
		{
			logTriangleGroupnterpolationStash(surface, log, strictModeLogStash);

			result	= true;
		}
		else
		{
			logTriangleGroupnterpolationStash(surface, log, nonStrictModeLogStash);
			logTriangleGroupnterpolationStash(surface, log, strictModeLogStash);
		}

		// In the non-strict line case, bresenham is also permissable, though not specified. This is due
		// to a change in how lines are specified in Vulkan versus GLES; in GLES bresenham lines using the
		// diamond-exit rule were the preferred way to draw single pixel non-antialiased lines, and not all
		// GLES implementations are able to disable this behaviour.
		if (result == false)
		{
			log << tcu::TestLog::Message << "Checking line rasterisation using verifySinglesampleNarrowLineGroupInterpolation for nonStrict lines" << tcu::TestLog::EndMessage;
			if (args.numSamples <= 1 &&
				allowBresenhamForNonStrictLines &&
				verifyLineGroupInterpolationWithProjectedWeights(surface, scene, args, log))
			{
				log << tcu::TestLog::Message << "verifySinglesampleNarrowLineGroupInterpolation for nonStrict lines Passed" << tcu::TestLog::EndMessage;

				result	= true;
			}
		}

	}

	return result;
}

bool verifyMultisamplePointGroupRasterization (const tcu::Surface& surface, const PointSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	// Multisampled point == 2 triangles

	const tcu::Vec2		viewportSize	= tcu::Vec2((float)surface.getWidth(), (float)surface.getHeight());
	TriangleSceneSpec	triangleScene;

	triangleScene.triangles.resize(2 * scene.points.size());
	for (int pointNdx = 0; pointNdx < (int)scene.points.size(); ++pointNdx)
	{
		// Transform to screen space, add pixel offsets, convert back to normalized device space, and test as triangles
		const tcu::Vec2	pointNormalizedDeviceSpace			= tcu::Vec2(scene.points[pointNdx].position.x() / scene.points[pointNdx].position.w(), scene.points[pointNdx].position.y() / scene.points[pointNdx].position.w());
		const tcu::Vec2	pointScreenSpace					= (pointNormalizedDeviceSpace + tcu::Vec2(1.0f, 1.0f)) * 0.5f * viewportSize;
		const float		offset								= scene.points[pointNdx].pointSize * 0.5f;
		const tcu::Vec2	lineQuadNormalizedDeviceSpace[4]	=
		{
			(pointScreenSpace + tcu::Vec2(-offset, -offset))/ viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
			(pointScreenSpace + tcu::Vec2(-offset,  offset))/ viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
			(pointScreenSpace + tcu::Vec2( offset,  offset))/ viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
			(pointScreenSpace + tcu::Vec2( offset, -offset))/ viewportSize * 2.0f - tcu::Vec2(1.0f, 1.0f),
		};

		triangleScene.triangles[pointNdx*2 + 0].positions[0] = tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x(), lineQuadNormalizedDeviceSpace[0].y(), 0.0f, 1.0f);	triangleScene.triangles[pointNdx*2 + 0].sharedEdge[0] = false;
		triangleScene.triangles[pointNdx*2 + 0].positions[1] = tcu::Vec4(lineQuadNormalizedDeviceSpace[1].x(), lineQuadNormalizedDeviceSpace[1].y(), 0.0f, 1.0f);	triangleScene.triangles[pointNdx*2 + 0].sharedEdge[1] = false;
		triangleScene.triangles[pointNdx*2 + 0].positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x(), lineQuadNormalizedDeviceSpace[2].y(), 0.0f, 1.0f);	triangleScene.triangles[pointNdx*2 + 0].sharedEdge[2] = true;

		triangleScene.triangles[pointNdx*2 + 1].positions[0] = tcu::Vec4(lineQuadNormalizedDeviceSpace[0].x(), lineQuadNormalizedDeviceSpace[0].y(), 0.0f, 1.0f);	triangleScene.triangles[pointNdx*2 + 1].sharedEdge[0] = true;
		triangleScene.triangles[pointNdx*2 + 1].positions[1] = tcu::Vec4(lineQuadNormalizedDeviceSpace[2].x(), lineQuadNormalizedDeviceSpace[2].y(), 0.0f, 1.0f);	triangleScene.triangles[pointNdx*2 + 1].sharedEdge[1] = false;
		triangleScene.triangles[pointNdx*2 + 1].positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[3].x(), lineQuadNormalizedDeviceSpace[3].y(), 0.0f, 1.0f);	triangleScene.triangles[pointNdx*2 + 1].sharedEdge[2] = false;
	}

	return verifyTriangleGroupRasterization(surface, triangleScene, args, log);
}

void genScreenSpaceLines (std::vector<tcu::Vec4>& screenspaceLines, const std::vector<LineSceneSpec::SceneLine>& lines, const tcu::IVec2& viewportSize)
{
	DE_ASSERT(screenspaceLines.size() == lines.size());

	for (int lineNdx = 0; lineNdx < (int)lines.size(); ++lineNdx)
	{
		const tcu::Vec2 lineNormalizedDeviceSpace[2] =
		{
			tcu::Vec2(lines[lineNdx].positions[0].x() / lines[lineNdx].positions[0].w(), lines[lineNdx].positions[0].y() / lines[lineNdx].positions[0].w()),
			tcu::Vec2(lines[lineNdx].positions[1].x() / lines[lineNdx].positions[1].w(), lines[lineNdx].positions[1].y() / lines[lineNdx].positions[1].w()),
		};
		const tcu::Vec4 lineScreenSpace[2] =
		{
			tcu::Vec4((lineNormalizedDeviceSpace[0].x() + 1.0f) * 0.5f * (float)viewportSize.x(), (lineNormalizedDeviceSpace[0].y() + 1.0f) * 0.5f * (float)viewportSize.y(), 0.0f, 1.0f),
			tcu::Vec4((lineNormalizedDeviceSpace[1].x() + 1.0f) * 0.5f * (float)viewportSize.x(), (lineNormalizedDeviceSpace[1].y() + 1.0f) * 0.5f * (float)viewportSize.y(), 0.0f, 1.0f),
		};

		screenspaceLines[lineNdx] = tcu::Vec4(lineScreenSpace[0].x(), lineScreenSpace[0].y(), lineScreenSpace[1].x(), lineScreenSpace[1].y());
	}
}

bool verifySinglesampleLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	DE_ASSERT(deFloatFrac(scene.lineWidth) != 0.5f); // rounding direction is not defined, disallow undefined cases
	DE_ASSERT(scene.lines.size() < 255); // indices are stored as unsigned 8-bit ints

	bool					allOK				= true;
	bool					overdrawInReference	= false;
	int						referenceFragments	= 0;
	int						resultFragments		= 0;
	int						lineWidth			= deFloorFloatToInt32(scene.lineWidth + 0.5f);
	std::vector<bool>		lineIsXMajor		(scene.lines.size());
	std::vector<tcu::Vec4>	screenspaceLines(scene.lines.size());

	// Reference renderer produces correct fragments using the diamond-rule. Make 2D int array, each cell contains the highest index (first index = 1) of the overlapping lines or 0 if no line intersects the pixel
	tcu::TextureLevel referenceLineMap(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT8), surface.getWidth(), surface.getHeight());
	tcu::clear(referenceLineMap.getAccess(), tcu::IVec4(0, 0, 0, 0));

	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)
	{
		rasterizer.init(tcu::Vec4(screenspaceLines[lineNdx][0],
								  screenspaceLines[lineNdx][1],
								  0.0f,
								  1.0f),
						tcu::Vec4(screenspaceLines[lineNdx][2],
								  screenspaceLines[lineNdx][3],
								  0.0f,
								  1.0f),
						scene.lineWidth,
						scene.stippleFactor,
						scene.stipplePattern);

		if (!scene.isStrip)
			rasterizer.resetStipple();

		// calculate majority of later use
		lineIsXMajor[lineNdx] = isPackedSSLineXMajor(screenspaceLines[lineNdx]);

		for (;;)
		{
			const int			maxPackets			= 32;
			int					numRasterized		= 0;
			rr::FragmentPacket	packets[maxPackets];

			rasterizer.rasterize(packets, DE_NULL, maxPackets, numRasterized);

			for (int packetNdx = 0; packetNdx < numRasterized; ++packetNdx)
			{
				for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
				{
					if ((deUint32)packets[packetNdx].coverage & (1 << fragNdx))
					{
						const tcu::IVec2 fragPos = packets[packetNdx].position + tcu::IVec2(fragNdx%2, fragNdx/2);

						// Check for overdraw
						if (!overdrawInReference)
							overdrawInReference = referenceLineMap.getAccess().getPixelInt(fragPos.x(), fragPos.y()).x() != 0;

						// Output pixel
						referenceLineMap.getAccess().setPixel(tcu::IVec4(lineNdx + 1, 0, 0, 0), fragPos.x(), fragPos.y());
					}
				}
			}

			if (numRasterized != maxPackets)
				break;
		}
	}

	// Requirement 1: The coordinates of a fragment produced by the algorithm may not deviate by more than one unit
	{
		tcu::Surface	errorMask			(surface.getWidth(), surface.getHeight());
		bool			missingFragments	= false;

		tcu::clear(errorMask.getAccess(), tcu::IVec4(0, 255, 0, 255));

		log << tcu::TestLog::Message << "Searching for deviating fragments." << tcu::TestLog::EndMessage;

		for (int y = 0; y < referenceLineMap.getHeight(); ++y)
		for (int x = 0; x < referenceLineMap.getWidth(); ++x)
		{
			const bool reference	= referenceLineMap.getAccess().getPixelInt(x, y).x() != 0;
			const bool result		= compareColors(surface.getPixel(x, y), tcu::RGBA::white(), args.redBits, args.greenBits, args.blueBits);

			if (reference)
				++referenceFragments;
			if (result)
				++resultFragments;

			if (reference == result)
				continue;

			// Reference fragment here, matching result fragment must be nearby
			if (reference && !result)
			{
				bool foundFragment = false;

				if (x == 0 || y == 0 || x == referenceLineMap.getWidth() - 1 || y == referenceLineMap.getHeight() -1)
				{
					// image boundary, missing fragment could be over the image edge
					foundFragment = true;
				}

				// find nearby fragment
				for (int dy = -1; dy < 2 && !foundFragment; ++dy)
				for (int dx = -1; dx < 2 && !foundFragment; ++dx)
				{
					if (compareColors(surface.getPixel(x+dx, y+dy), tcu::RGBA::white(), args.redBits, args.greenBits, args.blueBits))
						foundFragment = true;
				}

				if (!foundFragment)
				{
					missingFragments = true;
					errorMask.setPixel(x, y, tcu::RGBA::red());
				}
			}
		}

		if (missingFragments)
		{

			allOK = false;
		}
		else
		{
			log << tcu::TestLog::Message << "No invalid deviations found." << tcu::TestLog::EndMessage;
		}
	}

	// Requirement 2: The total number of fragments produced by the algorithm may differ from
	//                that produced by the diamond-exit rule by no more than one.
	{
		// Check is not valid if the primitives intersect or otherwise share same fragments
		if (!overdrawInReference)
		{
			int allowedDeviation = (int)scene.lines.size() * lineWidth; // one pixel per primitive in the major direction

			log << tcu::TestLog::Message << "Verifying fragment counts:\n"
				<< "\tDiamond-exit rule: " << referenceFragments << " fragments.\n"
				<< "\tResult image: " << resultFragments << " fragments.\n"
				<< "\tAllowing deviation of " << allowedDeviation << " fragments.\n"
				<< tcu::TestLog::EndMessage;

			if (deAbs32(referenceFragments - resultFragments) > allowedDeviation)
			{
				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("Reference", "Reference",	reference)
					<< tcu::TestLog::Image("Result", "Result",			surface)
					<< tcu::TestLog::EndImageSet;

				allOK = false;
			}
			else
			{
				log << tcu::TestLog::Message << "Fragment count is valid." << tcu::TestLog::EndMessage;
			}
		}
		else
		{
			log << tcu::TestLog::Message << "Overdraw in scene. Fragment count cannot be verified. Skipping fragment count checks." << tcu::TestLog::EndMessage;
		}
	}

	// Requirement 3: Line width must be constant
	{
		bool invalidWidthFound = false;

		log << tcu::TestLog::Message << "Verifying line widths of the x-major lines." << tcu::TestLog::EndMessage;
		for (int y = 1; y < referenceLineMap.getHeight() - 1; ++y)
		{
			bool	fullyVisibleLine		= false;
			bool	previousPixelUndefined	= false;
			int		currentLine				= 0;
			int		currentWidth			= 1;

			for (int x = 1; x < referenceLineMap.getWidth() - 1; ++x)
			{
				const bool	result	= compareColors(surface.getPixel(x, y), tcu::RGBA::white(), args.redBits, args.greenBits, args.blueBits);
				int			lineID	= 0;

				// Which line does this fragment belong to?

				if (result)
				{
					bool multipleNearbyLines = false;
					bool renderAtSurfaceEdge = false;

					renderAtSurfaceEdge = (x == 1) || (x == referenceLineMap.getWidth() - 2);

					for (int dy = -1; dy < 2; ++dy)
					for (int dx = -1; dx < 2; ++dx)
					{
						const int nearbyID = referenceLineMap.getAccess().getPixelInt(x+dx, y+dy).x();
						if (nearbyID)
						{
							if (lineID && lineID != nearbyID)
								multipleNearbyLines = true;
						}
					}

					if (multipleNearbyLines || renderAtSurfaceEdge)
					{
						// Another line is too close, don't try to calculate width here
						// Or the render result is outside of surface range
						previousPixelUndefined = true;
						continue;
					}
				}

				// Only line with id of lineID is nearby

				if (previousPixelUndefined)
				{
					// The line might have been overdrawn or not
					currentLine = lineID;
					currentWidth = 1;
					fullyVisibleLine = false;
					previousPixelUndefined = false;
				}
				else if (lineID == currentLine)
				{
					// Current line continues
					++currentWidth;
				}
				else if (lineID > currentLine)
				{
					// Another line was drawn over or the line ends
					currentLine = lineID;
					currentWidth = 1;
					fullyVisibleLine = true;
				}
				else
				{
					// The line ends
					if (fullyVisibleLine && !lineIsXMajor[currentLine-1])
					{
						// check width
						if (currentWidth != lineWidth)
						{
							log << tcu::TestLog::Message << "\tInvalid line width at (" << x - currentWidth << ", " << y << ") - (" << x - 1 << ", " << y << "). Detected width of " << currentWidth << ", expected " << lineWidth << tcu::TestLog::EndMessage;
							invalidWidthFound = true;
						}
					}

					currentLine = lineID;
					currentWidth = 1;
					fullyVisibleLine = false;
				}
			}
		}

		log << tcu::TestLog::Message << "Verifying line widths of the y-major lines." << tcu::TestLog::EndMessage;
		for (int x = 1; x < referenceLineMap.getWidth() - 1; ++x)
		{
			bool	fullyVisibleLine		= false;
			bool	previousPixelUndefined	= false;
			int		currentLine				= 0;
			int		currentWidth			= 1;

			for (int y = 1; y < referenceLineMap.getHeight() - 1; ++y)
			{
				const bool	result	= compareColors(surface.getPixel(x, y), tcu::RGBA::white(), args.redBits, args.greenBits, args.blueBits);
				int			lineID	= 0;

				// Which line does this fragment belong to?

				if (result)
				{
					bool multipleNearbyLines = false;
					bool renderAtSurfaceEdge = false;

					renderAtSurfaceEdge = (y == 1) || (y == referenceLineMap.getWidth() - 2);

					for (int dy = -1; dy < 2; ++dy)
					for (int dx = -1; dx < 2; ++dx)
					{
						const int nearbyID = referenceLineMap.getAccess().getPixelInt(x+dx, y+dy).x();
						if (nearbyID)
						{
							if (lineID && lineID != nearbyID)
								multipleNearbyLines = true;
							lineID = nearbyID;
						}
					}

					if (multipleNearbyLines || renderAtSurfaceEdge)
					{
						// Another line is too close, don't try to calculate width here
						// Or the render result is outside of surface range
						previousPixelUndefined = true;
						continue;
					}
				}

				// Only line with id of lineID is nearby

				if (previousPixelUndefined)
				{
					// The line might have been overdrawn or not
					currentLine = lineID;
					currentWidth = 1;
					fullyVisibleLine = false;
					previousPixelUndefined = false;
				}
				else if (lineID == currentLine)
				{
					// Current line continues
					++currentWidth;
				}
				else if (lineID > currentLine)
				{
					// Another line was drawn over or the line ends
					currentLine = lineID;
					currentWidth = 1;
					fullyVisibleLine = true;
				}
				else
				{
					// The line ends
					if (fullyVisibleLine && lineIsXMajor[currentLine-1])
					{
						// check width
						if (currentWidth != lineWidth)
						{
							log << tcu::TestLog::Message << "\tInvalid line width at (" << x << ", " << y - currentWidth << ") - (" << x  << ", " << y - 1 << "). Detected width of " << currentWidth << ", expected " << lineWidth << tcu::TestLog::EndMessage;
							invalidWidthFound = true;
						}
					}

					currentLine = lineID;
					currentWidth = 1;
					fullyVisibleLine = false;
				}
			}
		}

		if (invalidWidthFound)
		{
			log << tcu::TestLog::Message << "Invalid line width found, image is not valid." << tcu::TestLog::EndMessage;
			allOK = false;
		}
		else
		{
			log << tcu::TestLog::Message << "Line widths are valid." << tcu::TestLog::EndMessage;
		}
	}

	//\todo [2013-10-24 jarkko].
	//Requirement 4. If two line segments share a common endpoint, and both segments are either
	//x-major (both left-to-right or both right-to-left) or y-major (both bottom-totop
	//or both top-to-bottom), then rasterizing both segments may not produce
	//duplicate fragments, nor may any fragments be omitted so as to interrupt
	//continuity of the connected segments.

	{
		tcu::Surface reference(surface.getWidth(), surface.getHeight());
		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("Reference", "Reference",	reference)
			<< tcu::TestLog::Image("Result", "Result", surface)
			<< tcu::TestLog::EndImageSet;
	}

	return allOK;
}

struct SingleSampleNarrowLineCandidate
{
	int			lineNdx;
	tcu::IVec3	colorMin;
	tcu::IVec3	colorMax;
	tcu::Vec3	colorMinF;
	tcu::Vec3	colorMaxF;
	tcu::Vec3	valueRangeMin;
	tcu::Vec3	valueRangeMax;
};

void setMaskMapCoverageBitForLine (int bitNdx, const tcu::Vec2& screenSpaceP0, const tcu::Vec2& screenSpaceP1, float lineWidth, tcu::PixelBufferAccess maskMap, const int subpixelBits)
{
	enum
	{
		MAX_PACKETS = 32,
	};

	rr::SingleSampleLineRasterizer	rasterizer				(tcu::IVec4(0, 0, maskMap.getWidth(), maskMap.getHeight()), subpixelBits);
	int								numRasterized			= MAX_PACKETS;
	rr::FragmentPacket				packets[MAX_PACKETS];

	rasterizer.init(tcu::Vec4(screenSpaceP0.x(), screenSpaceP0.y(), 0.0f, 1.0f),
					tcu::Vec4(screenSpaceP1.x(), screenSpaceP1.y(), 0.0f, 1.0f),
					lineWidth,
					1, 0xFFFF);

	while (numRasterized == MAX_PACKETS)
	{
		rasterizer.rasterize(packets, DE_NULL, MAX_PACKETS, numRasterized);

		for (int packetNdx = 0; packetNdx < numRasterized; ++packetNdx)
		{
			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			{
				if ((deUint32)packets[packetNdx].coverage & (1 << fragNdx))
				{
					const tcu::IVec2	fragPos			= packets[packetNdx].position + tcu::IVec2(fragNdx%2, fragNdx/2);

					DE_ASSERT(deInBounds32(fragPos.x(), 0, maskMap.getWidth()));
					DE_ASSERT(deInBounds32(fragPos.y(), 0, maskMap.getHeight()));

					const deUint32		previousMask	= maskMap.getPixelUint(fragPos.x(), fragPos.y()).x();
					const deUint32		newMask			= (previousMask) | ((deUint32)1u << bitNdx);

					maskMap.setPixel(tcu::UVec4(newMask, 0, 0, 0), fragPos.x(), fragPos.y());
				}
			}
		}
	}
}

void setMaskMapCoverageBitForLines (const std::vector<tcu::Vec4>& screenspaceLines, float lineWidth, tcu::PixelBufferAccess maskMap, const int subpixelBits)
{
	for (int lineNdx = 0; lineNdx < (int)screenspaceLines.size(); ++lineNdx)
	{
		const tcu::Vec2 pa = screenspaceLines[lineNdx].swizzle(0, 1);
		const tcu::Vec2 pb = screenspaceLines[lineNdx].swizzle(2, 3);

		setMaskMapCoverageBitForLine(lineNdx, pa, pb, lineWidth, maskMap, subpixelBits);
	}
}

// verify line interpolation assuming line pixels are interpolated independently depending only on screen space location
bool verifyLineGroupPixelIndependentInterpolation (const tcu::Surface&				surface,
												   const LineSceneSpec&				scene,
												   const RasterizationArguments&	args,
												   tcu::TestLog&					log,
												   LineInterpolationMethod			interpolationMethod)
{
	DE_ASSERT(scene.lines.size() < 8); // coverage indices are stored as bitmask in a unsigned 8-bit ints
	DE_ASSERT(interpolationMethod == LINEINTERPOLATION_STRICTLY_CORRECT || interpolationMethod == LINEINTERPOLATION_PROJECTED);

	const tcu::RGBA			invalidPixelColor	= tcu::RGBA(255, 0, 0, 255);
	const tcu::IVec2		viewportSize		= tcu::IVec2(surface.getWidth(), surface.getHeight());
	const int				errorFloodThreshold	= 4;
	int						errorCount			= 0;
	tcu::Surface			errorMask			(surface.getWidth(), surface.getHeight());
	int						invalidPixels		= 0;
	std::vector<tcu::Vec4>	screenspaceLines	(scene.lines.size()); //!< packed (x0, y0, x1, y1)

	// Reference renderer produces correct fragments using the diamond-exit-rule. Make 2D int array, store line coverage as a 8-bit bitfield
	// The map is used to find lines with potential coverage to a given pixel
	tcu::TextureLevel		referenceLineMap	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT8), surface.getWidth(), surface.getHeight());

	tcu::clear(referenceLineMap.getAccess(), tcu::IVec4(0, 0, 0, 0));
	tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	// log format

	log << tcu::TestLog::Message << "Verifying rasterization result. Native format is RGB" << args.redBits << args.greenBits << args.blueBits << tcu::TestLog::EndMessage;
	if (args.redBits > 8 || args.greenBits > 8 || args.blueBits > 8)
		log << tcu::TestLog::Message << "Warning! More than 8 bits in a color channel, this may produce false negatives." << tcu::TestLog::EndMessage;

	// prepare lookup map

	genScreenSpaceLines(screenspaceLines, scene.lines, viewportSize);
	setMaskMapCoverageBitForLines(screenspaceLines, scene.lineWidth, referenceLineMap.getAccess(), args.subpixelBits);

	// Find all possible lines with coverage, check pixel color matches one of them

	for (int y = 1; y < surface.getHeight() - 1; ++y)
	for (int x = 1; x < surface.getWidth()  - 1; ++x)
	{
		const tcu::RGBA		color					= surface.getPixel(x, y);
		const tcu::IVec3	pixelNativeColor		= convertRGB8ToNativeFormat(color, args);	// Convert pixel color from rgba8 to the real pixel format. Usually rgba8 or 565
		int					lineCoverageSet			= 0;										// !< lines that may cover this fragment
		int					lineSurroundingCoverage = 0xFFFF;									// !< lines that will cover this fragment
		bool				matchFound				= false;
		const tcu::IVec3	formatLimit				((1 << args.redBits) - 1, (1 << args.greenBits) - 1, (1 << args.blueBits) - 1);

		std::vector<SingleSampleNarrowLineCandidate> candidates;

		// Find lines with possible coverage

		for (int dy = -1; dy < 2; ++dy)
		for (int dx = -1; dx < 2; ++dx)
		{
			const int coverage = referenceLineMap.getAccess().getPixelInt(x+dx, y+dy).x();

			lineCoverageSet			|= coverage;
			lineSurroundingCoverage	&= coverage;
		}

		// background color is possible?
		if (lineSurroundingCoverage == 0 && compareColors(color, tcu::RGBA::black(), args.redBits, args.greenBits, args.blueBits))
			continue;

		// Check those lines

		for (int lineNdx = 0; lineNdx < (int)scene.lines.size(); ++lineNdx)
		{
			if (((lineCoverageSet >> lineNdx) & 0x01) != 0)
			{
				const float						wa				= scene.lines[lineNdx].positions[0].w();
				const float						wb				= scene.lines[lineNdx].positions[1].w();
				const tcu::Vec2					pa				= screenspaceLines[lineNdx].swizzle(0, 1);
				const tcu::Vec2					pb				= screenspaceLines[lineNdx].swizzle(2, 3);

				const LineInterpolationRange	range			= (interpolationMethod == LINEINTERPOLATION_STRICTLY_CORRECT)
																	? (calcSingleSampleLineInterpolationRange(pa, wa, pb, wb, tcu::IVec2(x, y), args.subpixelBits))
																	: (calcSingleSampleLineInterpolationRangeAxisProjected(pa, wa, pb, wb, tcu::IVec2(x, y), args.subpixelBits));

				const tcu::Vec4					valueMin		= de::clamp(range.min.x(), 0.0f, 1.0f) * scene.lines[lineNdx].colors[0] + de::clamp(range.min.y(), 0.0f, 1.0f) * scene.lines[lineNdx].colors[1];
				const tcu::Vec4					valueMax		= de::clamp(range.max.x(), 0.0f, 1.0f) * scene.lines[lineNdx].colors[0] + de::clamp(range.max.y(), 0.0f, 1.0f) * scene.lines[lineNdx].colors[1];

				const tcu::Vec3					colorMinF		(de::clamp(valueMin.x() * (float)formatLimit.x(), 0.0f, (float)formatLimit.x()),
																 de::clamp(valueMin.y() * (float)formatLimit.y(), 0.0f, (float)formatLimit.y()),
																 de::clamp(valueMin.z() * (float)formatLimit.z(), 0.0f, (float)formatLimit.z()));
				const tcu::Vec3					colorMaxF		(de::clamp(valueMax.x() * (float)formatLimit.x(), 0.0f, (float)formatLimit.x()),
																 de::clamp(valueMax.y() * (float)formatLimit.y(), 0.0f, (float)formatLimit.y()),
																 de::clamp(valueMax.z() * (float)formatLimit.z(), 0.0f, (float)formatLimit.z()));
				const tcu::IVec3				colorMin		((int)deFloatFloor(colorMinF.x()),
																 (int)deFloatFloor(colorMinF.y()),
																 (int)deFloatFloor(colorMinF.z()));
				const tcu::IVec3				colorMax		((int)deFloatCeil (colorMaxF.x()),
																 (int)deFloatCeil (colorMaxF.y()),
																 (int)deFloatCeil (colorMaxF.z()));

				// Verify validity
				if (pixelNativeColor.x() < colorMin.x() ||
					pixelNativeColor.y() < colorMin.y() ||
					pixelNativeColor.z() < colorMin.z() ||
					pixelNativeColor.x() > colorMax.x() ||
					pixelNativeColor.y() > colorMax.y() ||
					pixelNativeColor.z() > colorMax.z())
				{
					if (errorCount < errorFloodThreshold)
					{
						// Store candidate information for logging
						SingleSampleNarrowLineCandidate candidate;

						candidate.lineNdx		= lineNdx;
						candidate.colorMin		= colorMin;
						candidate.colorMax		= colorMax;
						candidate.colorMinF		= colorMinF;
						candidate.colorMaxF		= colorMaxF;
						candidate.valueRangeMin	= valueMin.swizzle(0, 1, 2);
						candidate.valueRangeMax	= valueMax.swizzle(0, 1, 2);

						candidates.push_back(candidate);
					}
				}
				else
				{
					matchFound = true;
					break;
				}
			}
		}

		if (matchFound)
			continue;

		// invalid fragment
		++invalidPixels;
		errorMask.setPixel(x, y, invalidPixelColor);

		++errorCount;

		// don't fill the logs with too much data
		if (errorCount < errorFloodThreshold)
		{
			log << tcu::TestLog::Message
				<< "Found an invalid pixel at (" << x << "," << y << "), " << (int)candidates.size() << " candidate reference value(s) found:\n"
				<< "\tPixel color:\t\t" << color << "\n"
				<< "\tNative color:\t\t" << pixelNativeColor << "\n"
				<< tcu::TestLog::EndMessage;

			for (int candidateNdx = 0; candidateNdx < (int)candidates.size(); ++candidateNdx)
			{
				const SingleSampleNarrowLineCandidate& candidate = candidates[candidateNdx];

				log << tcu::TestLog::Message << "\tCandidate (line " << candidate.lineNdx << "):\n"
					<< "\t\tReference native color min: " << tcu::clamp(candidate.colorMin, tcu::IVec3(0,0,0), formatLimit) << "\n"
					<< "\t\tReference native color max: " << tcu::clamp(candidate.colorMax, tcu::IVec3(0,0,0), formatLimit) << "\n"
					<< "\t\tReference native float min: " << tcu::clamp(candidate.colorMinF, tcu::Vec3(0.0f, 0.0f, 0.0f), formatLimit.cast<float>()) << "\n"
					<< "\t\tReference native float max: " << tcu::clamp(candidate.colorMaxF, tcu::Vec3(0.0f, 0.0f, 0.0f), formatLimit.cast<float>()) << "\n"
					<< "\t\tFmin:\t" << tcu::clamp(candidate.valueRangeMin, tcu::Vec3(0.0f, 0.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 1.0f)) << "\n"
					<< "\t\tFmax:\t" << tcu::clamp(candidate.valueRangeMax, tcu::Vec3(0.0f, 0.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 1.0f)) << "\n"
					<< tcu::TestLog::EndMessage;
			}
		}
	}

	// don't just hide failures
	if (errorCount > errorFloodThreshold)
		log << tcu::TestLog::Message << "Omitted " << (errorCount-errorFloodThreshold) << " pixel error description(s)." << tcu::TestLog::EndMessage;

	// report result
	if (invalidPixels)
	{
		log << tcu::TestLog::Message << invalidPixels << " invalid pixel(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;

		return false;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", surface)
			<< tcu::TestLog::EndImageSet;

		return true;
	}
}

bool verifySinglesampleNarrowLineGroupInterpolation (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	DE_ASSERT(scene.lineWidth == 1.0f);
	return verifyLineGroupPixelIndependentInterpolation(surface, scene, args, log, LINEINTERPOLATION_STRICTLY_CORRECT);
}

bool verifyLineGroupInterpolationWithProjectedWeights (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	return verifyLineGroupPixelIndependentInterpolation(surface, scene, args, log, LINEINTERPOLATION_PROJECTED);
}

struct SingleSampleWideLineCandidate
{
	struct InterpolationPointCandidate
	{
		tcu::IVec2	interpolationPoint;
		tcu::IVec3	colorMin;
		tcu::IVec3	colorMax;
		tcu::Vec3	colorMinF;
		tcu::Vec3	colorMaxF;
		tcu::Vec3	valueRangeMin;
		tcu::Vec3	valueRangeMax;
	};

	int							lineNdx;
	int							numCandidates;
	InterpolationPointCandidate	interpolationCandidates[3];
};

// return point on line at a given position on a given axis
tcu::Vec2 getLineCoordAtAxisCoord (const tcu::Vec2& pa, const tcu::Vec2& pb, bool isXAxis, float axisCoord)
{
	const int	fixedCoordNdx		= (isXAxis) ? (0) : (1);
	const int	varyingCoordNdx		= (isXAxis) ? (1) : (0);

	const float	fixedDifference		= pb[fixedCoordNdx] - pa[fixedCoordNdx];
	const float	varyingDifference	= pb[varyingCoordNdx] - pa[varyingCoordNdx];

	DE_ASSERT(fixedDifference != 0.0f);

	const float	resultFixedCoord	= axisCoord;
	const float	resultVaryingCoord	= pa[varyingCoordNdx] + (axisCoord - pa[fixedCoordNdx]) * (varyingDifference / fixedDifference);

	return (isXAxis) ? (tcu::Vec2(resultFixedCoord, resultVaryingCoord))
					 : (tcu::Vec2(resultVaryingCoord, resultFixedCoord));
}

bool isBlack (const tcu::RGBA& c)
{
	return c.getRed() == 0 && c.getGreen() == 0 && c.getBlue() == 0;
}

bool verifySinglesampleWideLineGroupInterpolation (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	DE_ASSERT(deFloatFrac(scene.lineWidth) != 0.5f); // rounding direction is not defined, disallow undefined cases
	DE_ASSERT(scene.lines.size() < 8); // coverage indices are stored as bitmask in a unsigned 8-bit ints

	enum
	{
		FLAG_ROOT_NOT_SET = (1u << 16)
	};

	const tcu::RGBA						invalidPixelColor	= tcu::RGBA(255, 0, 0, 255);
	const tcu::IVec2					viewportSize		= tcu::IVec2(surface.getWidth(), surface.getHeight());
	const int							errorFloodThreshold	= 4;
	int									errorCount			= 0;
	tcu::Surface						errorMask			(surface.getWidth(), surface.getHeight());
	int									invalidPixels		= 0;
	std::vector<tcu::Vec4>				effectiveLines		(scene.lines.size()); //!< packed (x0, y0, x1, y1)
	std::vector<bool>					lineIsXMajor		(scene.lines.size());

	// for each line, for every distinct major direction fragment, store root pixel location (along
	// minor direction);
	std::vector<std::vector<deUint32> >	rootPixelLocation	(scene.lines.size()); //!< packed [16b - flags] [16b - coordinate]

	// log format

	log << tcu::TestLog::Message << "Verifying rasterization result. Native format is RGB" << args.redBits << args.greenBits << args.blueBits << tcu::TestLog::EndMessage;
	if (args.redBits > 8 || args.greenBits > 8 || args.blueBits > 8)
		log << tcu::TestLog::Message << "Warning! More than 8 bits in a color channel, this may produce false negatives." << tcu::TestLog::EndMessage;

	// Reference renderer produces correct fragments using the diamond-exit-rule. Make 2D int array, store line coverage as a 8-bit bitfield
	// The map is used to find lines with potential coverage to a given pixel
	tcu::TextureLevel referenceLineMap(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT8), surface.getWidth(), surface.getHeight());
	tcu::clear(referenceLineMap.getAccess(), tcu::IVec4(0, 0, 0, 0));

	tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	// calculate mask and effective line coordinates
	{
		std::vector<tcu::Vec4> screenspaceLines(scene.lines.size());

		genScreenSpaceLines(screenspaceLines, scene.lines, viewportSize);
		setMaskMapCoverageBitForLines(screenspaceLines, scene.lineWidth, referenceLineMap.getAccess(), args.subpixelBits);

		for (int lineNdx = 0; lineNdx < (int)scene.lines.size(); ++lineNdx)
		{
			const tcu::Vec2	lineScreenSpaceP0	= screenspaceLines[lineNdx].swizzle(0, 1);
			const tcu::Vec2	lineScreenSpaceP1	= screenspaceLines[lineNdx].swizzle(2, 3);
			const bool		isXMajor			= isPackedSSLineXMajor(screenspaceLines[lineNdx]);

			lineIsXMajor[lineNdx] = isXMajor;

			// wide line interpolations are calculated for a line moved in minor direction
			{
				const float		offsetLength	= (scene.lineWidth - 1.0f) / 2.0f;
				const tcu::Vec2	offsetDirection	= (isXMajor) ? (tcu::Vec2(0.0f, -1.0f)) : (tcu::Vec2(-1.0f, 0.0f));
				const tcu::Vec2	offset			= offsetDirection * offsetLength;

				effectiveLines[lineNdx] = tcu::Vec4(lineScreenSpaceP0.x() + offset.x(),
													lineScreenSpaceP0.y() + offset.y(),
													lineScreenSpaceP1.x() + offset.x(),
													lineScreenSpaceP1.y() + offset.y());
			}
		}
	}

	for (int lineNdx = 0; lineNdx < (int)scene.lines.size(); ++lineNdx)
	{
		// Calculate root pixel lookup table for this line. Since the implementation's fragment
		// major coordinate range might not be a subset of the correct line range (they are allowed
		// to vary by one pixel), we must extend the domain to cover whole viewport along major
		// dimension.
		//
		// Expanding line strip to (effectively) infinite line might result in exit-diamnod set
		// that is not a superset of the exit-diamond set of the line strip. In practice, this
		// won't be an issue, since the allow-one-pixel-variation rule should tolerate this even
		// if the original and extended line would resolve differently a diamond the line just
		// touches (precision lost in expansion changes enter/exit status).

		{
			const bool						isXMajor			= lineIsXMajor[lineNdx];
			const int						majorSize			= (isXMajor) ? (surface.getWidth()) : (surface.getHeight());
			rr::LineExitDiamondGenerator	diamondGenerator	(args.subpixelBits);
			rr::LineExitDiamond				diamonds[32];
			int								numRasterized		= DE_LENGTH_OF_ARRAY(diamonds);

			// Expand to effectively infinite line (endpoints are just one pixel over viewport boundaries)
			const tcu::Vec2					expandedP0		= getLineCoordAtAxisCoord(effectiveLines[lineNdx].swizzle(0, 1), effectiveLines[lineNdx].swizzle(2, 3), isXMajor, -1.0f);
			const tcu::Vec2					expandedP1		= getLineCoordAtAxisCoord(effectiveLines[lineNdx].swizzle(0, 1), effectiveLines[lineNdx].swizzle(2, 3), isXMajor, (float)majorSize + 1.0f);

			diamondGenerator.init(tcu::Vec4(expandedP0.x(), expandedP0.y(), 0.0f, 1.0f),
								  tcu::Vec4(expandedP1.x(), expandedP1.y(), 0.0f, 1.0f));

			rootPixelLocation[lineNdx].resize(majorSize, FLAG_ROOT_NOT_SET);

			while (numRasterized == DE_LENGTH_OF_ARRAY(diamonds))
			{
				diamondGenerator.rasterize(diamonds, DE_LENGTH_OF_ARRAY(diamonds), numRasterized);

				for (int packetNdx = 0; packetNdx < numRasterized; ++packetNdx)
				{
					const tcu::IVec2	fragPos			= diamonds[packetNdx].position;
					const int			majorPos		= (isXMajor) ? (fragPos.x()) : (fragPos.y());
					const int			rootPos			= (isXMajor) ? (fragPos.y()) : (fragPos.x());
					const deUint32		packed			= (deUint32)((deUint16)((deInt16)rootPos));

					// infinite line will generate some diamonds outside the viewport
					if (deInBounds32(majorPos, 0, majorSize))
					{
						DE_ASSERT((rootPixelLocation[lineNdx][majorPos] & FLAG_ROOT_NOT_SET) != 0u);
						rootPixelLocation[lineNdx][majorPos] = packed;
					}
				}
			}

			// Filled whole lookup table
			for (int majorPos = 0; majorPos < majorSize; ++majorPos)
				DE_ASSERT((rootPixelLocation[lineNdx][majorPos] & FLAG_ROOT_NOT_SET) == 0u);
		}
	}

	// Find all possible lines with coverage, check pixel color matches one of them

	for (int y = 1; y < surface.getHeight() - 1; ++y)
	for (int x = 1; x < surface.getWidth()  - 1; ++x)
	{
		const tcu::RGBA		color					= surface.getPixel(x, y);
		const tcu::IVec3	pixelNativeColor		= convertRGB8ToNativeFormat(color, args);	// Convert pixel color from rgba8 to the real pixel format. Usually rgba8 or 565
		int					lineCoverageSet			= 0;										// !< lines that may cover this fragment
		int					lineSurroundingCoverage = 0xFFFF;									// !< lines that will cover this fragment
		bool				matchFound				= false;
		const tcu::IVec3	formatLimit				((1 << args.redBits) - 1, (1 << args.greenBits) - 1, (1 << args.blueBits) - 1);

		std::vector<SingleSampleWideLineCandidate> candidates;

		// Find lines with possible coverage

		for (int dy = -1; dy < 2; ++dy)
		for (int dx = -1; dx < 2; ++dx)
		{
			const int coverage = referenceLineMap.getAccess().getPixelInt(x+dx, y+dy).x();

			lineCoverageSet			|= coverage;
			lineSurroundingCoverage	&= coverage;
		}

		// background color is possible?
		if (lineSurroundingCoverage == 0 && compareColors(color, tcu::RGBA::black(), args.redBits, args.greenBits, args.blueBits))
			continue;

		// Check those lines

		for (int lineNdx = 0; lineNdx < (int)scene.lines.size(); ++lineNdx)
		{
			if (((lineCoverageSet >> lineNdx) & 0x01) != 0)
			{
				const float						wa				= scene.lines[lineNdx].positions[0].w();
				const float						wb				= scene.lines[lineNdx].positions[1].w();
				const tcu::Vec2					pa				= effectiveLines[lineNdx].swizzle(0, 1);
				const tcu::Vec2					pb				= effectiveLines[lineNdx].swizzle(2, 3);

				// \note Wide line fragments are generated by replicating the root fragment for each
				//       fragment column (row for y-major). Calculate interpolation at the root
				//       fragment.
				const bool						isXMajor		= lineIsXMajor[lineNdx];
				const int						majorPosition	= (isXMajor) ? (x) : (y);
				const deUint32					minorInfoPacked	= rootPixelLocation[lineNdx][majorPosition];
				const int						minorPosition	= (int)((deInt16)((deUint16)(minorInfoPacked & 0xFFFFu)));
				const tcu::IVec2				idealRootPos	= (isXMajor) ? (tcu::IVec2(majorPosition, minorPosition)) : (tcu::IVec2(minorPosition, majorPosition));
				const tcu::IVec2				minorDirection	= (isXMajor) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));

				SingleSampleWideLineCandidate	candidate;

				candidate.lineNdx		= lineNdx;
				candidate.numCandidates	= 0;
				DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(candidate.interpolationCandidates) == 3);

				// Interpolation happens at the root fragment, which is then replicated in minor
				// direction. Search for implementation's root position near accurate root.
				for (int minorOffset = -1; minorOffset < 2; ++minorOffset)
				{
					const tcu::IVec2				rootPosition	= idealRootPos + minorOffset * minorDirection;

					// A fragment can be root fragment only if it exists
					// \note root fragment can "exist" outside viewport
					// \note no pixel format theshold since in this case allowing only black is more conservative
					if (deInBounds32(rootPosition.x(), 0, surface.getWidth()) &&
						deInBounds32(rootPosition.y(), 0, surface.getHeight()) &&
						isBlack(surface.getPixel(rootPosition.x(), rootPosition.y())))
					{
						continue;
					}

					const LineInterpolationRange	range			= calcSingleSampleLineInterpolationRange(pa, wa, pb, wb, rootPosition, args.subpixelBits);

					const tcu::Vec4					valueMin		= de::clamp(range.min.x(), 0.0f, 1.0f) * scene.lines[lineNdx].colors[0] + de::clamp(range.min.y(), 0.0f, 1.0f) * scene.lines[lineNdx].colors[1];
					const tcu::Vec4					valueMax		= de::clamp(range.max.x(), 0.0f, 1.0f) * scene.lines[lineNdx].colors[0] + de::clamp(range.max.y(), 0.0f, 1.0f) * scene.lines[lineNdx].colors[1];

					const tcu::Vec3					colorMinF		(de::clamp(valueMin.x() * (float)formatLimit.x(), 0.0f, (float)formatLimit.x()),
																	 de::clamp(valueMin.y() * (float)formatLimit.y(), 0.0f, (float)formatLimit.y()),
																	 de::clamp(valueMin.z() * (float)formatLimit.z(), 0.0f, (float)formatLimit.z()));
					const tcu::Vec3					colorMaxF		(de::clamp(valueMax.x() * (float)formatLimit.x(), 0.0f, (float)formatLimit.x()),
																	 de::clamp(valueMax.y() * (float)formatLimit.y(), 0.0f, (float)formatLimit.y()),
																	 de::clamp(valueMax.z() * (float)formatLimit.z(), 0.0f, (float)formatLimit.z()));
					const tcu::IVec3				colorMin		((int)deFloatFloor(colorMinF.x()),
																	 (int)deFloatFloor(colorMinF.y()),
																	 (int)deFloatFloor(colorMinF.z()));
					const tcu::IVec3				colorMax		((int)deFloatCeil (colorMaxF.x()),
																	 (int)deFloatCeil (colorMaxF.y()),
																	 (int)deFloatCeil (colorMaxF.z()));

					// Verify validity
					if (pixelNativeColor.x() < colorMin.x() ||
						pixelNativeColor.y() < colorMin.y() ||
						pixelNativeColor.z() < colorMin.z() ||
						pixelNativeColor.x() > colorMax.x() ||
						pixelNativeColor.y() > colorMax.y() ||
						pixelNativeColor.z() > colorMax.z())
					{
						if (errorCount < errorFloodThreshold)
						{
							// Store candidate information for logging
							SingleSampleWideLineCandidate::InterpolationPointCandidate& interpolationCandidate = candidate.interpolationCandidates[candidate.numCandidates++];
							DE_ASSERT(candidate.numCandidates <= DE_LENGTH_OF_ARRAY(candidate.interpolationCandidates));

							interpolationCandidate.interpolationPoint	= rootPosition;
							interpolationCandidate.colorMin				= colorMin;
							interpolationCandidate.colorMax				= colorMax;
							interpolationCandidate.colorMinF			= colorMinF;
							interpolationCandidate.colorMaxF			= colorMaxF;
							interpolationCandidate.valueRangeMin		= valueMin.swizzle(0, 1, 2);
							interpolationCandidate.valueRangeMax		= valueMax.swizzle(0, 1, 2);
						}
					}
					else
					{
						matchFound = true;
						break;
					}
				}

				if (!matchFound)
				{
					// store info for logging
					if (errorCount < errorFloodThreshold && candidate.numCandidates > 0)
						candidates.push_back(candidate);
				}
				else
				{
					// no need to check other lines
					break;
				}
			}
		}

		if (matchFound)
			continue;

		// invalid fragment
		++invalidPixels;
		errorMask.setPixel(x, y, invalidPixelColor);

		++errorCount;

		// don't fill the logs with too much data
		if (errorCount < errorFloodThreshold)
		{
			tcu::MessageBuilder msg(&log);

			msg	<< "Found an invalid pixel at (" << x << "," << y << "), " << (int)candidates.size() << " candidate reference value(s) found:\n"
				<< "\tPixel color:\t\t" << color << "\n"
				<< "\tNative color:\t\t" << pixelNativeColor << "\n";

			for (int lineCandidateNdx = 0; lineCandidateNdx < (int)candidates.size(); ++lineCandidateNdx)
			{
				const SingleSampleWideLineCandidate& candidate = candidates[lineCandidateNdx];

				msg << "\tCandidate line (line " << candidate.lineNdx << "):\n";

				for (int interpolationCandidateNdx = 0; interpolationCandidateNdx < candidate.numCandidates; ++interpolationCandidateNdx)
				{
					const SingleSampleWideLineCandidate::InterpolationPointCandidate& interpolationCandidate = candidate.interpolationCandidates[interpolationCandidateNdx];

					msg	<< "\t\tCandidate interpolation point (index " << interpolationCandidateNdx << "):\n"
						<< "\t\t\tRoot fragment position (non-replicated fragment): " << interpolationCandidate.interpolationPoint << ":\n"
						<< "\t\t\tReference native color min: " << tcu::clamp(interpolationCandidate.colorMin, tcu::IVec3(0,0,0), formatLimit) << "\n"
						<< "\t\t\tReference native color max: " << tcu::clamp(interpolationCandidate.colorMax, tcu::IVec3(0,0,0), formatLimit) << "\n"
						<< "\t\t\tReference native float min: " << tcu::clamp(interpolationCandidate.colorMinF, tcu::Vec3(0.0f, 0.0f, 0.0f), formatLimit.cast<float>()) << "\n"
						<< "\t\t\tReference native float max: " << tcu::clamp(interpolationCandidate.colorMaxF, tcu::Vec3(0.0f, 0.0f, 0.0f), formatLimit.cast<float>()) << "\n"
						<< "\t\t\tFmin:\t" << tcu::clamp(interpolationCandidate.valueRangeMin, tcu::Vec3(0.0f, 0.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 1.0f)) << "\n"
						<< "\t\t\tFmax:\t" << tcu::clamp(interpolationCandidate.valueRangeMax, tcu::Vec3(0.0f, 0.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 1.0f)) << "\n";
				}
			}

			msg << tcu::TestLog::EndMessage;
		}
	}

	// don't just hide failures
	if (errorCount > errorFloodThreshold)
		log << tcu::TestLog::Message << "Omitted " << (errorCount-errorFloodThreshold) << " pixel error description(s)." << tcu::TestLog::EndMessage;

	// report result
	if (invalidPixels)
	{
		log << tcu::TestLog::Message << invalidPixels << " invalid pixel(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;

		return false;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", surface)
			<< tcu::TestLog::EndImageSet;

		return true;
	}
}

} // anonymous

CoverageType calculateTriangleCoverage (const tcu::Vec4& p0, const tcu::Vec4& p1, const tcu::Vec4& p2, const tcu::IVec2& pixel, const tcu::IVec2& viewportSize, int subpixelBits, bool multisample)
{
	typedef tcu::Vector<deInt64, 2> I64Vec2;

	const deUint64		numSubPixels						= ((deUint64)1) << subpixelBits;
	const deUint64		pixelHitBoxSize						= (multisample) ? (numSubPixels) : 5;		//!< 5 = ceil(6 * sqrt(2) / 2) to account for a 3 subpixel fuzz around pixel center
	const bool			order								= isTriangleClockwise(p0, p1, p2);			//!< clockwise / counter-clockwise
	const tcu::Vec4&	orderedP0							= p0;										//!< vertices of a clockwise triangle
	const tcu::Vec4&	orderedP1							= (order) ? (p1) : (p2);
	const tcu::Vec4&	orderedP2							= (order) ? (p2) : (p1);
	const tcu::Vec2		triangleNormalizedDeviceSpace[3]	=
	{
		tcu::Vec2(orderedP0.x() / orderedP0.w(), orderedP0.y() / orderedP0.w()),
		tcu::Vec2(orderedP1.x() / orderedP1.w(), orderedP1.y() / orderedP1.w()),
		tcu::Vec2(orderedP2.x() / orderedP2.w(), orderedP2.y() / orderedP2.w()),
	};
	const tcu::Vec2		triangleScreenSpace[3]				=
	{
		(triangleNormalizedDeviceSpace[0] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
		(triangleNormalizedDeviceSpace[1] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
		(triangleNormalizedDeviceSpace[2] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
	};

	// Broad bounding box - pixel check
	{
		const float minX = de::min(de::min(triangleScreenSpace[0].x(), triangleScreenSpace[1].x()), triangleScreenSpace[2].x());
		const float minY = de::min(de::min(triangleScreenSpace[0].y(), triangleScreenSpace[1].y()), triangleScreenSpace[2].y());
		const float maxX = de::max(de::max(triangleScreenSpace[0].x(), triangleScreenSpace[1].x()), triangleScreenSpace[2].x());
		const float maxY = de::max(de::max(triangleScreenSpace[0].y(), triangleScreenSpace[1].y()), triangleScreenSpace[2].y());

		if ((float)pixel.x() > maxX + 1 ||
			(float)pixel.y() > maxY + 1 ||
			(float)pixel.x() < minX - 1 ||
			(float)pixel.y() < minY - 1)
			return COVERAGE_NONE;
	}

	// Broad triangle - pixel area intersection
	{
		const DVec2 pixelCenterPosition			=	DVec2((double)pixel.x(), (double)pixel.y()) * DVec2((double)numSubPixels, (double)numSubPixels) +
													DVec2((double)numSubPixels / 2, (double)numSubPixels / 2);
		const DVec2 triangleSubPixelSpace[3]	=
		{
			DVec2(triangleScreenSpace[0].x() * (double)numSubPixels, triangleScreenSpace[0].y() * (double)numSubPixels),
			DVec2(triangleScreenSpace[1].x() * (double)numSubPixels, triangleScreenSpace[1].y() * (double)numSubPixels),
			DVec2(triangleScreenSpace[2].x() * (double)numSubPixels, triangleScreenSpace[2].y() * (double)numSubPixels),
		};

		// Check (using cross product) if pixel center is
		// a) too far from any edge
		// b) fully inside all edges
		bool insideAllEdges = true;
		for (int vtxNdx = 0; vtxNdx < 3; ++vtxNdx)
		{
			const int		otherVtxNdx				= (vtxNdx + 1) % 3;
			const double	maxPixelDistanceSquared	= (double)(pixelHitBoxSize * pixelHitBoxSize); // Max distance from the pixel center from within the pixel is (sqrt(2) * boxWidth/2). Use 2x value for rounding tolerance
			const DVec2		edge					= triangleSubPixelSpace[otherVtxNdx]	- triangleSubPixelSpace[vtxNdx];
			const DVec2		v						= pixelCenterPosition					- triangleSubPixelSpace[vtxNdx];
			const double	crossProduct			= (edge.x() * v.y() - edge.y() * v.x());

			// distance from edge: (edge x v) / |edge|
			//     (edge x v) / |edge| > maxPixelDistance
			// ==> (edge x v)^2 / edge^2 > maxPixelDistance^2    | edge x v > 0
			// ==> (edge x v)^2 > maxPixelDistance^2 * edge^2
			if (crossProduct < 0 && crossProduct*crossProduct > maxPixelDistanceSquared * tcu::lengthSquared(edge))
				return COVERAGE_NONE;
			if (crossProduct < 0 || crossProduct*crossProduct < maxPixelDistanceSquared * tcu::lengthSquared(edge))
				insideAllEdges = false;
		}

		if (insideAllEdges)
			return COVERAGE_FULL;
	}

	// Accurate intersection for edge pixels
	{
		//  In multisampling, the sample points can be anywhere in the pixel, and in single sampling only in the center.
		const I64Vec2 pixelCorners[4] =
		{
			I64Vec2((pixel.x()+0) * numSubPixels, (pixel.y()+0) * numSubPixels),
			I64Vec2((pixel.x()+1) * numSubPixels, (pixel.y()+0) * numSubPixels),
			I64Vec2((pixel.x()+1) * numSubPixels, (pixel.y()+1) * numSubPixels),
			I64Vec2((pixel.x()+0) * numSubPixels, (pixel.y()+1) * numSubPixels),
		};

		// 3 subpixel tolerance around pixel center to account for accumulated errors during various line rasterization methods
		const I64Vec2 pixelCenterCorners[4] =
		{
			I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 - 3, pixel.y() * numSubPixels + numSubPixels/2 - 3),
			I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 + 3, pixel.y() * numSubPixels + numSubPixels/2 - 3),
			I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 + 3, pixel.y() * numSubPixels + numSubPixels/2 + 3),
			I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 - 3, pixel.y() * numSubPixels + numSubPixels/2 + 3),
		};

		// both rounding directions
		const I64Vec2 triangleSubPixelSpaceFloor[3] =
		{
			I64Vec2(deFloorFloatToInt32(triangleScreenSpace[0].x() * (float)numSubPixels), deFloorFloatToInt32(triangleScreenSpace[0].y() * (float)numSubPixels)),
			I64Vec2(deFloorFloatToInt32(triangleScreenSpace[1].x() * (float)numSubPixels), deFloorFloatToInt32(triangleScreenSpace[1].y() * (float)numSubPixels)),
			I64Vec2(deFloorFloatToInt32(triangleScreenSpace[2].x() * (float)numSubPixels), deFloorFloatToInt32(triangleScreenSpace[2].y() * (float)numSubPixels)),
		};
		const I64Vec2 triangleSubPixelSpaceCeil[3] =
		{
			I64Vec2(deCeilFloatToInt32(triangleScreenSpace[0].x() * (float)numSubPixels), deCeilFloatToInt32(triangleScreenSpace[0].y() * (float)numSubPixels)),
			I64Vec2(deCeilFloatToInt32(triangleScreenSpace[1].x() * (float)numSubPixels), deCeilFloatToInt32(triangleScreenSpace[1].y() * (float)numSubPixels)),
			I64Vec2(deCeilFloatToInt32(triangleScreenSpace[2].x() * (float)numSubPixels), deCeilFloatToInt32(triangleScreenSpace[2].y() * (float)numSubPixels)),
		};
		const I64Vec2* const corners = (multisample) ? (pixelCorners) : (pixelCenterCorners);

		// Test if any edge (with any rounding) intersects the pixel (boundary). If it does => Partial. If not => fully inside or outside

		for (int edgeNdx = 0; edgeNdx < 3; ++edgeNdx)
		for (int startRounding = 0; startRounding < 4; ++startRounding)
		for (int endRounding = 0; endRounding < 4; ++endRounding)
		{
			const int		nextEdgeNdx	= (edgeNdx+1) % 3;
			const I64Vec2	startPos	((startRounding&0x01)	? (triangleSubPixelSpaceFloor[edgeNdx].x())		: (triangleSubPixelSpaceCeil[edgeNdx].x()),		(startRounding&0x02)	? (triangleSubPixelSpaceFloor[edgeNdx].y())		: (triangleSubPixelSpaceCeil[edgeNdx].y()));
			const I64Vec2	endPos		((endRounding&0x01)		? (triangleSubPixelSpaceFloor[nextEdgeNdx].x())	: (triangleSubPixelSpaceCeil[nextEdgeNdx].x()),	(endRounding&0x02)		? (triangleSubPixelSpaceFloor[nextEdgeNdx].y())	: (triangleSubPixelSpaceCeil[nextEdgeNdx].y()));

			for (int pixelEdgeNdx = 0; pixelEdgeNdx < 4; ++pixelEdgeNdx)
			{
				const int pixelEdgeEnd = (pixelEdgeNdx + 1) % 4;

				if (lineLineIntersect(startPos, endPos, corners[pixelEdgeNdx], corners[pixelEdgeEnd]))
					return COVERAGE_PARTIAL;
			}
		}

		// fully inside or outside
		for (int edgeNdx = 0; edgeNdx < 3; ++edgeNdx)
		{
			const int		nextEdgeNdx		= (edgeNdx+1) % 3;
			const I64Vec2&	startPos		= triangleSubPixelSpaceFloor[edgeNdx];
			const I64Vec2&	endPos			= triangleSubPixelSpaceFloor[nextEdgeNdx];
			const I64Vec2	edge			= endPos - startPos;
			const I64Vec2	v				= corners[0] - endPos;
			const deInt64	crossProduct	= (edge.x() * v.y() - edge.y() * v.x());

			// a corner of the pixel is outside => "fully inside" option is impossible
			if (crossProduct < 0)
				return COVERAGE_NONE;
		}

		return COVERAGE_FULL;
	}
}

CoverageType calculateUnderestimateLineCoverage (const tcu::Vec4& p0, const tcu::Vec4& p1, const float lineWidth, const tcu::IVec2& pixel, const tcu::IVec2& viewportSize)
{
	DE_ASSERT(viewportSize.x() == viewportSize.y() && viewportSize.x() > 0);
	DE_ASSERT(p0.w() == 1.0f && p1.w() == 1.0f);

	const Vec2		p		= Vec2(p0.x(), p0.y());
	const Vec2		q		= Vec2(p1.x(), p1.y());
	const Vec2		pq		= Vec2(p1.x() - p0.x(), p1.y() - p0.y());
	const Vec2		pqn		= normalize(pq);
	const Vec2		lw		= 0.5f * lineWidth * pqn;
	const Vec2		n		= Vec2(lw.y(), -lw.x());
	const Vec2		vp		= Vec2(float(viewportSize.x()), float(viewportSize.y()));
	const Vec2		a		= 0.5f * (p + Vec2(1.0f, 1.0f)) * vp + n;
	const Vec2		b		= 0.5f * (p + Vec2(1.0f, 1.0f)) * vp - n;
	const Vec2		c		= 0.5f * (q + Vec2(1.0f, 1.0f)) * vp - n;
	const Vec2		ba		= b - a;
	const Vec2		bc		= b - c;
	const float		det		= ba.x() * bc.y() - ba.y() * bc.x();
	int				within	= 0;

	if (det != 0.0f)
	{
		for (int cornerNdx = 0; cornerNdx < 4; ++cornerNdx)
		{
			const int		pixelCornerOffsetX	= ((cornerNdx & 1) ? 1 : 0);
			const int		pixelCornerOffsetY	= ((cornerNdx & 2) ? 1 : 0);
			const Vec2		f					= Vec2(float(pixel.x() + pixelCornerOffsetX), float(pixel.y() + pixelCornerOffsetY));
			const Vec2		bf					= b - f;
			const float		alpha				= (bf.x() * bc.y() - bc.x() * bf.y()) / det;
			const float		beta				= (ba.x() * bf.y() - bf.x() * ba.y()) / det;
			bool			cornerWithin		= de::inRange(alpha, 0.0f, 1.0f) && de::inRange(beta, 0.0f, 1.0f);

			if (cornerWithin)
				within++;
		}
	}

	if (within == 0)
		return COVERAGE_NONE;
	else if (within == 4)
		return COVERAGE_FULL;
	else
		return COVERAGE_PARTIAL;
}

CoverageType calculateUnderestimateTriangleCoverage (const tcu::Vec4& p0, const tcu::Vec4& p1, const tcu::Vec4& p2, const tcu::IVec2& pixel, int subpixelBits, const tcu::IVec2& viewportSize)
{
	typedef tcu::Vector<deInt64, 2> I64Vec2;

	const deUint64		numSubPixels						= ((deUint64)1) << subpixelBits;
	const bool			order								= isTriangleClockwise(p0, p1, p2);			//!< clockwise / counter-clockwise
	const tcu::Vec4&	orderedP0							= p0;										//!< vertices of a clockwise triangle
	const tcu::Vec4&	orderedP1							= (order) ? (p1) : (p2);
	const tcu::Vec4&	orderedP2							= (order) ? (p2) : (p1);
	const tcu::Vec2		triangleNormalizedDeviceSpace[3]	=
	{
		tcu::Vec2(orderedP0.x() / orderedP0.w(), orderedP0.y() / orderedP0.w()),
		tcu::Vec2(orderedP1.x() / orderedP1.w(), orderedP1.y() / orderedP1.w()),
		tcu::Vec2(orderedP2.x() / orderedP2.w(), orderedP2.y() / orderedP2.w()),
	};
	const tcu::Vec2		triangleScreenSpace[3]				=
	{
		(triangleNormalizedDeviceSpace[0] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
		(triangleNormalizedDeviceSpace[1] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
		(triangleNormalizedDeviceSpace[2] + tcu::Vec2(1.0f, 1.0f)) * 0.5f * tcu::Vec2((float)viewportSize.x(), (float)viewportSize.y()),
	};

	// Broad bounding box - pixel check
	{
		const float minX = de::min(de::min(triangleScreenSpace[0].x(), triangleScreenSpace[1].x()), triangleScreenSpace[2].x());
		const float minY = de::min(de::min(triangleScreenSpace[0].y(), triangleScreenSpace[1].y()), triangleScreenSpace[2].y());
		const float maxX = de::max(de::max(triangleScreenSpace[0].x(), triangleScreenSpace[1].x()), triangleScreenSpace[2].x());
		const float maxY = de::max(de::max(triangleScreenSpace[0].y(), triangleScreenSpace[1].y()), triangleScreenSpace[2].y());

		if ((float)pixel.x() > maxX + 1 ||
			(float)pixel.y() > maxY + 1 ||
			(float)pixel.x() < minX - 1 ||
			(float)pixel.y() < minY - 1)
			return COVERAGE_NONE;
	}

	// Accurate intersection for edge pixels
	{
		//  In multisampling, the sample points can be anywhere in the pixel, and in single sampling only in the center.
		const I64Vec2 pixelCorners[4] =
		{
			I64Vec2((pixel.x()+0) * numSubPixels, (pixel.y()+0) * numSubPixels),
			I64Vec2((pixel.x()+1) * numSubPixels, (pixel.y()+0) * numSubPixels),
			I64Vec2((pixel.x()+1) * numSubPixels, (pixel.y()+1) * numSubPixels),
			I64Vec2((pixel.x()+0) * numSubPixels, (pixel.y()+1) * numSubPixels),
		};
		// both rounding directions
		const I64Vec2 triangleSubPixelSpaceFloor[3] =
		{
			I64Vec2(deFloorFloatToInt32(triangleScreenSpace[0].x() * (float)numSubPixels), deFloorFloatToInt32(triangleScreenSpace[0].y() * (float)numSubPixels)),
			I64Vec2(deFloorFloatToInt32(triangleScreenSpace[1].x() * (float)numSubPixels), deFloorFloatToInt32(triangleScreenSpace[1].y() * (float)numSubPixels)),
			I64Vec2(deFloorFloatToInt32(triangleScreenSpace[2].x() * (float)numSubPixels), deFloorFloatToInt32(triangleScreenSpace[2].y() * (float)numSubPixels)),
		};
		const I64Vec2 triangleSubPixelSpaceCeil[3] =
		{
			I64Vec2(deCeilFloatToInt32(triangleScreenSpace[0].x() * (float)numSubPixels), deCeilFloatToInt32(triangleScreenSpace[0].y() * (float)numSubPixels)),
			I64Vec2(deCeilFloatToInt32(triangleScreenSpace[1].x() * (float)numSubPixels), deCeilFloatToInt32(triangleScreenSpace[1].y() * (float)numSubPixels)),
			I64Vec2(deCeilFloatToInt32(triangleScreenSpace[2].x() * (float)numSubPixels), deCeilFloatToInt32(triangleScreenSpace[2].y() * (float)numSubPixels)),
		};

		// Test if any edge (with any rounding) intersects the pixel (boundary). If it does => Partial. If not => fully inside or outside

		for (int edgeNdx = 0; edgeNdx < 3; ++edgeNdx)
		for (int startRounding = 0; startRounding < 4; ++startRounding)
		for (int endRounding = 0; endRounding < 4; ++endRounding)
		{
			const int		nextEdgeNdx	= (edgeNdx+1) % 3;
			const I64Vec2	startPos	((startRounding&0x01)	? (triangleSubPixelSpaceFloor[edgeNdx].x())		: (triangleSubPixelSpaceCeil[edgeNdx].x()),		(startRounding&0x02)	? (triangleSubPixelSpaceFloor[edgeNdx].y())		: (triangleSubPixelSpaceCeil[edgeNdx].y()));
			const I64Vec2	endPos		((endRounding&0x01)		? (triangleSubPixelSpaceFloor[nextEdgeNdx].x())	: (triangleSubPixelSpaceCeil[nextEdgeNdx].x()),	(endRounding&0x02)		? (triangleSubPixelSpaceFloor[nextEdgeNdx].y())	: (triangleSubPixelSpaceCeil[nextEdgeNdx].y()));

			for (int pixelEdgeNdx = 0; pixelEdgeNdx < 4; ++pixelEdgeNdx)
			{
				const int pixelEdgeEnd = (pixelEdgeNdx + 1) % 4;

				if (lineLineIntersect(startPos, endPos, pixelCorners[pixelEdgeNdx], pixelCorners[pixelEdgeEnd]))
					return COVERAGE_PARTIAL;
			}
		}

		// fully inside or outside
		for (int edgeNdx = 0; edgeNdx < 3; ++edgeNdx)
		{
			const int		nextEdgeNdx		= (edgeNdx+1) % 3;
			const I64Vec2&	startPos		= triangleSubPixelSpaceFloor[edgeNdx];
			const I64Vec2&	endPos			= triangleSubPixelSpaceFloor[nextEdgeNdx];
			const I64Vec2	edge			= endPos - startPos;
			const I64Vec2	v				= pixelCorners[0] - endPos;
			const deInt64	crossProduct	= (edge.x() * v.y() - edge.y() * v.x());

			// a corner of the pixel is outside => "fully inside" option is impossible
			if (crossProduct < 0)
				return COVERAGE_NONE;
		}

		return COVERAGE_FULL;
	}
}

static void logTriangleGroupRasterizationStash (const tcu::Surface& surface, tcu::TestLog& log, VerifyTriangleGroupRasterizationLogStash& logStash)
{
	// Output results
	log << tcu::TestLog::Message << "Verifying rasterization result." << tcu::TestLog::EndMessage;

	for (size_t msgNdx = 0; msgNdx < logStash.messages.size(); ++msgNdx)
		log << tcu::TestLog::Message << logStash.messages[msgNdx] << tcu::TestLog::EndMessage;

	if (!logStash.result)
	{
		log << tcu::TestLog::Message << "Invalid pixels found:\n\t"
			<< logStash.missingPixels << " missing pixels. (Marked with purple)\n\t"
			<< logStash.unexpectedPixels << " incorrectly filled pixels. (Marked with red)\n\t"
			<< "Unknown (subpixel on edge) pixels are marked with yellow."
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		surface)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	logStash.errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", surface)
			<< tcu::TestLog::EndImageSet;
	}
}

bool verifyTriangleGroupRasterization (const tcu::Surface& surface, const TriangleSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, VerificationMode mode, VerifyTriangleGroupRasterizationLogStash* logStash, const bool vulkanLinesTest)
{
	DE_ASSERT(mode < VERIFICATIONMODE_LAST);

	const tcu::RGBA		backGroundColor				= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		triangleColor				= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		missingPixelColor			= tcu::RGBA(255, 0, 255, 255);
	const tcu::RGBA		unexpectedPixelColor		= tcu::RGBA(255, 0, 0, 255);
	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;
	int					unexpectedPixels			= 0;
	int					subPixelBits				= args.subpixelBits;
	tcu::TextureLevel	coverageMap					(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT8), surface.getWidth(), surface.getHeight());
	tcu::Surface		errorMask					(surface.getWidth(), surface.getHeight());
	bool				result						= false;

	// subpixel bits in a valid range?

	if (subPixelBits < 0)
	{
		log << tcu::TestLog::Message << "Invalid subpixel count (" << subPixelBits << "), assuming 0" << tcu::TestLog::EndMessage;
		subPixelBits = 0;
	}
	else if (subPixelBits > 16)
	{
		// At high subpixel bit counts we might overflow. Checking at lower bit count is ok, but is less strict
		log << tcu::TestLog::Message << "Subpixel count is greater than 16 (" << subPixelBits << "). Checking results using less strict 16 bit requirements. This may produce false positives." << tcu::TestLog::EndMessage;
		subPixelBits = 16;
	}

	// generate coverage map

	tcu::clear(coverageMap.getAccess(), tcu::IVec4(COVERAGE_NONE, 0, 0, 0));

	for (int triNdx = 0; triNdx < (int)scene.triangles.size(); ++triNdx)
	{
		const tcu::IVec4 aabb = getTriangleAABB(scene.triangles[triNdx], viewportSize);

		for (int y = de::max(0, aabb.y()); y <= de::min(aabb.w(), coverageMap.getHeight() - 1); ++y)
		for (int x = de::max(0, aabb.x()); x <= de::min(aabb.z(), coverageMap.getWidth() - 1); ++x)
		{
			if (coverageMap.getAccess().getPixelUint(x, y).x() == COVERAGE_FULL)
				continue;

			const CoverageType coverage = calculateTriangleCoverage(scene.triangles[triNdx].positions[0],
																	scene.triangles[triNdx].positions[1],
																	scene.triangles[triNdx].positions[2],
																	tcu::IVec2(x, y),
																	viewportSize,
																	subPixelBits,
																	multisampled);

			if (coverage == COVERAGE_FULL)
			{
				coverageMap.getAccess().setPixel(tcu::IVec4(COVERAGE_FULL, 0, 0, 0), x, y);
			}
			else if (coverage == COVERAGE_PARTIAL)
			{
				CoverageType resultCoverage = COVERAGE_PARTIAL;

				// Sharing an edge with another triangle?
				// There should always be such a triangle, but the pixel in the other triangle might be
				// on multiple edges, some of which are not shared. In these cases the coverage cannot be determined.
				// Assume full coverage if the pixel is only on a shared edge in shared triangle too.
				if (pixelOnlyOnASharedEdge(tcu::IVec2(x, y), scene.triangles[triNdx], viewportSize))
				{
					bool friendFound = false;
					for (int friendTriNdx = 0; friendTriNdx < (int)scene.triangles.size(); ++friendTriNdx)
					{
						if (friendTriNdx == triNdx)
							continue;

						const CoverageType friendCoverage	= calculateTriangleCoverage(scene.triangles[friendTriNdx].positions[0],
																						scene.triangles[friendTriNdx].positions[1],
																						scene.triangles[friendTriNdx].positions[2],
																						tcu::IVec2(x, y),
																						viewportSize,
																						subPixelBits,
																						multisampled);

						if (friendCoverage != COVERAGE_NONE && pixelOnlyOnASharedEdge(tcu::IVec2(x, y), scene.triangles[friendTriNdx], viewportSize))
						{
							friendFound = true;
							break;
						}
					}

					if (friendFound)
						resultCoverage = COVERAGE_FULL;
				}

				coverageMap.getAccess().setPixel(tcu::IVec4(resultCoverage, 0, 0, 0), x, y);
			}
		}
	}

	// check pixels

	tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	// Use these to sanity check there is something drawn when a test expects something else than an empty picture.
	bool referenceEmpty	= true;
	bool resultEmpty	= true;

	for (int y = 0; y < surface.getHeight(); ++y)
	for (int x = 0; x < surface.getWidth(); ++x)
	{
		const tcu::RGBA		color				= surface.getPixel(x, y);
		const bool			imageNoCoverage		= compareColors(color, backGroundColor, args.redBits, args.greenBits, args.blueBits);
		const bool			imageFullCoverage	= compareColors(color, triangleColor, args.redBits, args.greenBits, args.blueBits);
		CoverageType		referenceCoverage	= (CoverageType)coverageMap.getAccess().getPixelUint(x, y).x();

		if (!imageNoCoverage)
			resultEmpty = false;

		switch (referenceCoverage)
		{
			case COVERAGE_NONE:
				if (!imageNoCoverage)
				{
					// coverage where there should not be
					++unexpectedPixels;
					errorMask.setPixel(x, y, unexpectedPixelColor);
				}
				break;

			case COVERAGE_PARTIAL:
				{
					referenceEmpty = false;
					bool foundFragment = false;
					if (vulkanLinesTest == true)
					{
						for (int dy = -1; dy < 2 && !foundFragment; ++dy)
							for (int dx = -1; dx < 2 && !foundFragment; ++dx)
							{
								if (x + dx >= 0 && x + dx != surface.getWidth() && y + dy >= 0 && y + dy != surface.getHeight()
									&& (CoverageType)coverageMap.getAccess().getPixelUint(x + dx, y + dy).x() != COVERAGE_NONE)
								{
									const tcu::RGBA color2 = surface.getPixel(x + dx , y + dy);
									if (compareColors(color2, triangleColor, args.redBits, args.greenBits, args.blueBits))
										foundFragment = true;
								}
							}
					}
					// anything goes
					if (foundFragment == false)
					{
						errorMask.setPixel(x, y, partialPixelColor);
						if (vulkanLinesTest == true)
							++missingPixels;
					}
				}
				break;

			case COVERAGE_FULL:
				referenceEmpty = false;
				if (!imageFullCoverage)
				{
					// no coverage where there should be
					++missingPixels;
					errorMask.setPixel(x, y, missingPixelColor);
				}
				else
				{
					errorMask.setPixel(x, y, primitivePixelColor);
				}
				break;

			default:
				DE_ASSERT(false);
		};
	}

	if (((mode == VERIFICATIONMODE_STRICT) && (missingPixels + unexpectedPixels > 0)) ||
		((mode == VERIFICATIONMODE_WEAK)   && (missingPixels + unexpectedPixels > weakVerificationThreshold)) ||
		((mode == VERIFICATIONMODE_WEAKER) && (missingPixels + unexpectedPixels > weakerVerificationThreshold)) ||
		((mode == VERIFICATIONMODE_SMOOTH) && (missingPixels > weakVerificationThreshold)) ||
		referenceEmpty != resultEmpty)
	{
		result = false;
	}
	else
	{
		result = true;
	}

	// Output or stash results
	{
		VerifyTriangleGroupRasterizationLogStash* tempLogStash = (logStash == DE_NULL) ? new VerifyTriangleGroupRasterizationLogStash : logStash;

		tempLogStash->result			= result;
		tempLogStash->missingPixels		= missingPixels;
		tempLogStash->unexpectedPixels	= unexpectedPixels;
		tempLogStash->errorMask			= errorMask;

		if (logStash == DE_NULL)
		{
			logTriangleGroupRasterizationStash(surface, log, *tempLogStash);
			delete tempLogStash;
		}
	}

	return result;
}

bool verifyLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	const bool multisampled = args.numSamples != 0;

	if (multisampled)
		return verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_NO_CLIPPING, DE_NULL, false, true);
	else
		return verifySinglesampleLineGroupRasterization(surface, scene, args, log);
}

bool verifyClippedTriangulatedLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	return verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_USE_CLIPPING_BOX, DE_NULL, false, true);
}

bool verifyRelaxedLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, const bool vulkanLinesTest, const bool strict)
{
	VerifyTriangleGroupRasterizationLogStash useClippingLogStash;
	VerifyTriangleGroupRasterizationLogStash noClippingLogStash;
	VerifyTriangleGroupRasterizationLogStash useClippingForcedStrictLogStash;
	VerifyTriangleGroupRasterizationLogStash noClippingForcedStrictLogStash;

	if (verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_USE_CLIPPING_BOX, &useClippingLogStash, vulkanLinesTest, strict))
	{
		logTriangleGroupRasterizationStash(surface, log, useClippingLogStash);

		return true;
	}
	else if (verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_NO_CLIPPING, &noClippingLogStash, vulkanLinesTest, strict))
	{
		logTriangleGroupRasterizationStash(surface, log, noClippingLogStash);

		return true;
	}
	else if (strict == false && verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_USE_CLIPPING_BOX, &useClippingForcedStrictLogStash, vulkanLinesTest, true))
	{
		logTriangleGroupRasterizationStash(surface, log, useClippingForcedStrictLogStash);

		return true;
	}
	else if (strict == false && verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_NO_CLIPPING, &noClippingForcedStrictLogStash, vulkanLinesTest, true))
	{
		logTriangleGroupRasterizationStash(surface, log, noClippingForcedStrictLogStash);

		return true;
	}
	else if (strict == false && args.numSamples == 0 && verifyLineGroupRasterization(surface, scene, args, log))
	{
		return true;
	}
	else
	{
		log << tcu::TestLog::Message << "Relaxed rasterization failed, details follow." << tcu::TestLog::EndMessage;

		logTriangleGroupRasterizationStash(surface, log, useClippingLogStash);
		logTriangleGroupRasterizationStash(surface, log, noClippingLogStash);

		if (strict == false)
		{
			logTriangleGroupRasterizationStash(surface, log, useClippingForcedStrictLogStash);
			logTriangleGroupRasterizationStash(surface, log, noClippingForcedStrictLogStash);
		}

		return false;
	}
}

bool verifyPointGroupRasterization (const tcu::Surface& surface, const PointSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	// Splitting to triangles is a valid solution in multisampled cases and even in non-multisample cases too.
	return verifyMultisamplePointGroupRasterization(surface, scene, args, log);
}

bool verifyTriangleGroupInterpolation (const tcu::Surface& surface, const TriangleSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	VerifyTriangleGroupInterpolationLogStash	logStash;
	const bool									result		= verifyTriangleGroupInterpolationWithInterpolator(surface, scene, args, logStash, TriangleInterpolator(scene));

	logTriangleGroupnterpolationStash(surface, log, logStash);

	return result;
}

LineInterpolationMethod verifyLineGroupInterpolation (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
{
	const bool multisampled = args.numSamples != 0;

	if (multisampled)
	{
		if (verifyMultisampleLineGroupInterpolation(surface, scene, args, log))
			return LINEINTERPOLATION_STRICTLY_CORRECT;
		return LINEINTERPOLATION_INCORRECT;
	}
	else
	{
		const bool isNarrow = (scene.lineWidth == 1.0f);

		// accurate interpolation
		if (isNarrow)
		{
			if (verifySinglesampleNarrowLineGroupInterpolation(surface, scene, args, log))
				return LINEINTERPOLATION_STRICTLY_CORRECT;
		}
		else
		{
			if (verifySinglesampleWideLineGroupInterpolation(surface, scene, args, log))
				return LINEINTERPOLATION_STRICTLY_CORRECT;
		}

		// check with projected (inaccurate) interpolation
		log << tcu::TestLog::Message << "Accurate verification failed, checking with projected weights (inaccurate equation)." << tcu::TestLog::EndMessage;
		if (verifyLineGroupInterpolationWithProjectedWeights(surface, scene, args, log))
			return LINEINTERPOLATION_PROJECTED;

		return LINEINTERPOLATION_INCORRECT;
	}
}

bool verifyTriangulatedLineGroupInterpolation (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, const bool strictMode, const bool allowBresenhamForNonStrictLines)
{
	return verifyMultisampleLineGroupInterpolation(surface, scene, args, log, strictMode, allowBresenhamForNonStrictLines);
}

} // tcu
