/*-------------------------------------------------------------------------
 * drawElements Quality Program Reference Renderer
 * -----------------------------------------------
 *
 * 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 Reference rasterizer
 *//*--------------------------------------------------------------------*/

#include "rrRasterizer.hpp"
#include "deMath.h"
#include "tcuVectorUtil.hpp"

namespace rr
{

inline deInt64 toSubpixelCoord (float v)
{
	return (deInt64)(v * (1<<RASTERIZER_SUBPIXEL_BITS) + (v < 0.f ? -0.5f : 0.5f));
}

inline deInt64 toSubpixelCoord (deInt32 v)
{
	return v << RASTERIZER_SUBPIXEL_BITS;
}

inline deInt32 ceilSubpixelToPixelCoord (deInt64 coord, bool fillEdge)
{
	if (coord >= 0)
		return (deInt32)((coord + ((1ll<<RASTERIZER_SUBPIXEL_BITS) - (fillEdge ? 0 : 1))) >> RASTERIZER_SUBPIXEL_BITS);
	else
		return (deInt32)((coord + (fillEdge ? 1 : 0)) >> RASTERIZER_SUBPIXEL_BITS);
}

inline deInt32 floorSubpixelToPixelCoord (deInt64 coord, bool fillEdge)
{
	if (coord >= 0)
		return (deInt32)((coord - (fillEdge ? 1 : 0)) >> RASTERIZER_SUBPIXEL_BITS);
	else
		return (deInt32)((coord - ((1ll<<RASTERIZER_SUBPIXEL_BITS) - (fillEdge ? 0 : 1))) >> RASTERIZER_SUBPIXEL_BITS);
}

static inline void initEdgeCCW (EdgeFunction& edge, const HorizontalFill horizontalFill, const VerticalFill verticalFill, const deInt64 x0, const deInt64 y0, const deInt64 x1, const deInt64 y1)
{
	// \note See EdgeFunction documentation for details.

	const deInt64	xd			= x1-x0;
	const deInt64	yd			= y1-y0;
	bool			inclusive	= false;	//!< Inclusive in CCW orientation.

	if (yd == 0)
		inclusive = verticalFill == FILL_BOTTOM ? xd >= 0 : xd <= 0;
	else
		inclusive = horizontalFill == FILL_LEFT ? yd <= 0 : yd >= 0;

	edge.a			= (y0 - y1);
	edge.b			= (x1 - x0);
	edge.c			= x0*y1 - y0*x1;
	edge.inclusive	= inclusive; //!< \todo [pyry] Swap for CW triangles
}

static inline void reverseEdge (EdgeFunction& edge)
{
	edge.a			= -edge.a;
	edge.b			= -edge.b;
	edge.c			= -edge.c;
	edge.inclusive	= !edge.inclusive;
}

static inline deInt64 evaluateEdge (const EdgeFunction& edge, const deInt64 x, const deInt64 y)
{
	return edge.a*x + edge.b*y + edge.c;
}

static inline bool isInsideCCW (const EdgeFunction& edge, const deInt64 edgeVal)
{
	return edge.inclusive ? (edgeVal >= 0) : (edgeVal > 0);
}

namespace LineRasterUtil
{

struct SubpixelLineSegment
{
	const tcu::Vector<deInt64,2>	m_v0;
	const tcu::Vector<deInt64,2>	m_v1;

	SubpixelLineSegment (const tcu::Vector<deInt64,2>& v0, const tcu::Vector<deInt64,2>& v1)
		: m_v0(v0)
		, m_v1(v1)
	{
	}

	tcu::Vector<deInt64,2> direction (void) const
	{
		return m_v1 - m_v0;
	}
};

enum LINE_SIDE
{
	LINE_SIDE_INTERSECT = 0,
	LINE_SIDE_LEFT,
	LINE_SIDE_RIGHT
};

static tcu::Vector<deInt64,2> toSubpixelVector (const tcu::Vec2& v)
{
	return tcu::Vector<deInt64,2>(toSubpixelCoord(v.x()), toSubpixelCoord(v.y()));
}

static tcu::Vector<deInt64,2> toSubpixelVector (const tcu::IVec2& v)
{
	return tcu::Vector<deInt64,2>(toSubpixelCoord(v.x()), toSubpixelCoord(v.y()));
}

#if defined(DE_DEBUG)
static bool isTheCenterOfTheFragment (const tcu::Vector<deInt64,2>& a)
{
	const deUint64 pixelSize = 1ll << (RASTERIZER_SUBPIXEL_BITS);
	const deUint64 halfPixel = 1ll << (RASTERIZER_SUBPIXEL_BITS-1);
	return	((a.x() & (pixelSize-1)) == halfPixel &&
				(a.y() & (pixelSize-1)) == halfPixel);
}

static bool inViewport (const tcu::IVec2& p, const tcu::IVec4& viewport)
{
	return	p.x() >= viewport.x() &&
			p.y() >= viewport.y() &&
			p.x() <  viewport.x() + viewport.z() &&
			p.y() <  viewport.y() + viewport.w();
}
#endif // DE_DEBUG

// returns true if vertex is on the left side of the line
static bool vertexOnLeftSideOfLine (const tcu::Vector<deInt64,2>& p, const SubpixelLineSegment& l)
{
	const tcu::Vector<deInt64,2> u = l.direction();
	const tcu::Vector<deInt64,2> v = ( p - l.m_v0);
	const deInt64 crossProduct = (u.x() * v.y() - u.y() * v.x());
	return crossProduct < 0;
}

// returns true if vertex is on the right side of the line
static bool vertexOnRightSideOfLine (const tcu::Vector<deInt64,2>& p, const SubpixelLineSegment& l)
{
	const tcu::Vector<deInt64,2> u = l.direction();
	const tcu::Vector<deInt64,2> v = ( p - l.m_v0);
	const deInt64 crossProduct = (u.x() * v.y() - u.y() * v.x());
	return crossProduct > 0;
}

// returns true if vertex is on the line
static bool vertexOnLine (const tcu::Vector<deInt64,2>& p, const SubpixelLineSegment& l)
{
	const tcu::Vector<deInt64,2> u = l.direction();
	const tcu::Vector<deInt64,2> v = ( p - l.m_v0);
	const deInt64 crossProduct = (u.x() * v.y() - u.y() * v.x());
	return crossProduct == 0; // cross product == 0
}

// returns true if vertex is on the line segment
static bool vertexOnLineSegment (const tcu::Vector<deInt64,2>& p, const SubpixelLineSegment& l)
{
	if (!vertexOnLine(p, l))
		return false;

	const tcu::Vector<deInt64,2> v	= l.direction();
	const tcu::Vector<deInt64,2> u1	= ( p - l.m_v0);
	const tcu::Vector<deInt64,2> u2	= ( p - l.m_v1);

	if (v.x() == 0 && v.y() == 0)
		return false;

	return	tcu::dot( v, u1) >= 0 &&
			tcu::dot(-v, u2) >= 0; // dot (A->B, A->V) >= 0 and dot (B->A, B->V) >= 0
}

static LINE_SIDE getVertexSide (const tcu::Vector<deInt64,2>& v, const SubpixelLineSegment& l)
{
	if (vertexOnLeftSideOfLine(v, l))
		return LINE_SIDE_LEFT;
	else if (vertexOnRightSideOfLine(v, l))
		return LINE_SIDE_RIGHT;
	else if (vertexOnLine(v, l))
		return LINE_SIDE_INTERSECT;
	else
	{
		DE_ASSERT(false);
		return LINE_SIDE_INTERSECT;
	}
}

// returns true if angle between line and given cornerExitNormal is in range (-45, 45)
bool lineInCornerAngleRange (const SubpixelLineSegment& line, const tcu::Vector<deInt64,2>& cornerExitNormal)
{
	// v0 -> v1 has angle difference to cornerExitNormal in range (-45, 45)
	const tcu::Vector<deInt64,2> v = line.direction();
	const deInt64 dotProduct = dot(v, cornerExitNormal);

	// dotProduct > |v1-v0|*|cornerExitNormal|/sqrt(2)
	if (dotProduct < 0)
		return false;
	return 2 * dotProduct * dotProduct > tcu::lengthSquared(v)*tcu::lengthSquared(cornerExitNormal);
}

// returns true if angle between line and given cornerExitNormal is in range (-135, 135)
bool lineInCornerOutsideAngleRange (const SubpixelLineSegment& line, const tcu::Vector<deInt64,2>& cornerExitNormal)
{
	// v0 -> v1 has angle difference to cornerExitNormal in range (-135, 135)
	const tcu::Vector<deInt64,2> v = line.direction();
	const deInt64 dotProduct = dot(v, cornerExitNormal);

	// dotProduct > -|v1-v0|*|cornerExitNormal|/sqrt(2)
	if (dotProduct >= 0)
		return true;
	return 2 * (-dotProduct) * (-dotProduct) < tcu::lengthSquared(v)*tcu::lengthSquared(cornerExitNormal);
}

bool doesLineSegmentExitDiamond (const SubpixelLineSegment& line, const tcu::Vector<deInt64,2>& diamondCenter)
{
	DE_ASSERT(isTheCenterOfTheFragment(diamondCenter));

	// Diamond Center is at diamondCenter in subpixel coords

	const deInt64 halfPixel = 1ll << (RASTERIZER_SUBPIXEL_BITS-1);

	// Reject distant diamonds early
	{
		const tcu::Vector<deInt64,2>	u				= line.direction();
		const tcu::Vector<deInt64,2>	v				= (diamondCenter - line.m_v0);
		const deInt64					crossProduct	= (u.x() * v.y() - u.y() * v.x());

		// crossProduct = |p| |l| sin(theta)
		// distanceFromLine = |p| sin(theta)
		// => distanceFromLine = crossProduct / |l|
		//
		// |distanceFromLine| > C
		// => distanceFromLine^2 > C^2
		// => crossProduct^2 / |l|^2 > C^2
		// => crossProduct^2 > |l|^2 * C^2

		const deInt64	floorSqrtMaxInt64			= 3037000499LL; //!< floor(sqrt(MAX_INT64))

		const deInt64	broadRejectDistance			= 2 * halfPixel;
		const deInt64	broadRejectDistanceSquared	= broadRejectDistance * broadRejectDistance;
		const bool		crossProductOverflows		= (crossProduct > floorSqrtMaxInt64 || crossProduct < -floorSqrtMaxInt64);
		const deInt64	crossProductSquared			= (crossProductOverflows) ? (0) : (crossProduct * crossProduct); // avoid overflow
		const deInt64	lineLengthSquared			= tcu::lengthSquared(u);
		const bool		limitValueCouldOverflow		= ((64 - deClz64(lineLengthSquared)) + (64 - deClz64(broadRejectDistanceSquared))) > 63;
		const deInt64	limitValue					= (limitValueCouldOverflow) ? (0) : (lineLengthSquared * broadRejectDistanceSquared); // avoid overflow

		// only cross overflows
		if (crossProductOverflows && !limitValueCouldOverflow)
			return false;

		// both representable
		if (!crossProductOverflows && !limitValueCouldOverflow)
		{
			if (crossProductSquared > limitValue)
				return false;
		}
	}

	const struct DiamondBound
	{
		tcu::Vector<deInt64,2>	p0;
		tcu::Vector<deInt64,2>	p1;
		bool					edgeInclusive; // would a point on the bound be inside of the region
	} bounds[] =
	{
		{ diamondCenter + tcu::Vector<deInt64,2>(0,				-halfPixel),	diamondCenter + tcu::Vector<deInt64,2>(-halfPixel,	0),				 false	},
		{ diamondCenter + tcu::Vector<deInt64,2>(-halfPixel,	0),				diamondCenter + tcu::Vector<deInt64,2>(0,			halfPixel),		 false	},
		{ diamondCenter + tcu::Vector<deInt64,2>(0,				halfPixel),		diamondCenter + tcu::Vector<deInt64,2>(halfPixel,	0),				 true	},
		{ diamondCenter + tcu::Vector<deInt64,2>(halfPixel,		0),				diamondCenter + tcu::Vector<deInt64,2>(0,			-halfPixel),	 true	},
	};

	const struct DiamondCorners
	{
		enum CORNER_EDGE_CASE_BEHAVIOR
		{
			CORNER_EDGE_CASE_NONE,							// if the line intersects just a corner, no entering or exiting
			CORNER_EDGE_CASE_HIT,							// if the line intersects just a corner, entering and exit
			CORNER_EDGE_CASE_HIT_FIRST_QUARTER,				// if the line intersects just a corner and the line has either endpoint in (+X,-Y) direction (preturbing moves the line inside)
			CORNER_EDGE_CASE_HIT_SECOND_QUARTER				// if the line intersects just a corner and the line has either endpoint in (+X,+Y) direction (preturbing moves the line inside)
		};
		enum CORNER_START_CASE_BEHAVIOR
		{
			CORNER_START_CASE_NONE,							// the line starting point is outside, no exiting
			CORNER_START_CASE_OUTSIDE,						// exit, if line does not intersect the region (preturbing moves the start point inside)
			CORNER_START_CASE_POSITIVE_Y_45,				// exit, if line the angle of line vector and X-axis is in range (0, 45] in positive Y side.
			CORNER_START_CASE_NEGATIVE_Y_45					// exit, if line the angle of line vector and X-axis is in range [0, 45] in negative Y side.
		};
		enum CORNER_END_CASE_BEHAVIOR
		{
			CORNER_END_CASE_NONE,							// end is inside, no exiting (preturbing moves the line end inside)
			CORNER_END_CASE_DIRECTION,						// exit, if line intersected the region (preturbing moves the line end outside)
			CORNER_END_CASE_DIRECTION_AND_FIRST_QUARTER,	// exit, if line intersected the region, or line originates from (+X,-Y) direction (preturbing moves the line end outside)
			CORNER_END_CASE_DIRECTION_AND_SECOND_QUARTER	// exit, if line intersected the region, or line originates from (+X,+Y) direction (preturbing moves the line end outside)
		};

		tcu::Vector<deInt64,2>		dp;
		bool						pointInclusive;			// would a point in this corner intersect with the region
		CORNER_EDGE_CASE_BEHAVIOR	lineBehavior;			// would a line segment going through this corner intersect with the region
		CORNER_START_CASE_BEHAVIOR	startBehavior;			// how the corner behaves if the start point at the corner
		CORNER_END_CASE_BEHAVIOR	endBehavior;			// how the corner behaves if the end point at the corner
	} corners[] =
	{
		{ tcu::Vector<deInt64,2>(0,				-halfPixel),	false,	DiamondCorners::CORNER_EDGE_CASE_HIT_SECOND_QUARTER,	DiamondCorners::CORNER_START_CASE_POSITIVE_Y_45,	DiamondCorners::CORNER_END_CASE_DIRECTION_AND_SECOND_QUARTER},
		{ tcu::Vector<deInt64,2>(-halfPixel,	0),				false,	DiamondCorners::CORNER_EDGE_CASE_NONE,					DiamondCorners::CORNER_START_CASE_NONE,				DiamondCorners::CORNER_END_CASE_DIRECTION					},
		{ tcu::Vector<deInt64,2>(0,				halfPixel),		false,	DiamondCorners::CORNER_EDGE_CASE_HIT_FIRST_QUARTER,		DiamondCorners::CORNER_START_CASE_NEGATIVE_Y_45,	DiamondCorners::CORNER_END_CASE_DIRECTION_AND_FIRST_QUARTER	},
		{ tcu::Vector<deInt64,2>(halfPixel,		0),				true,	DiamondCorners::CORNER_EDGE_CASE_HIT,					DiamondCorners::CORNER_START_CASE_OUTSIDE,			DiamondCorners::CORNER_END_CASE_NONE						},
	};

	// Corner cases at the corners
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(corners); ++ndx)
	{
		const tcu::Vector<deInt64,2> p	= diamondCenter + corners[ndx].dp;
		const bool intersectsAtCorner	= LineRasterUtil::vertexOnLineSegment(p, line);

		if (!intersectsAtCorner)
			continue;

		// line segment body intersects with the corner
		if (p != line.m_v0 && p != line.m_v1)
		{
			if (corners[ndx].lineBehavior == DiamondCorners::CORNER_EDGE_CASE_HIT)
				return true;

			// endpoint in (+X, -Y) (X or Y may be 0) direction <==> x*y <= 0
			if (corners[ndx].lineBehavior == DiamondCorners::CORNER_EDGE_CASE_HIT_FIRST_QUARTER &&
				(line.direction().x() * line.direction().y()) <= 0)
				return true;

			// endpoint in (+X, +Y) (Y > 0) direction <==> x*y > 0
			if (corners[ndx].lineBehavior == DiamondCorners::CORNER_EDGE_CASE_HIT_SECOND_QUARTER &&
				(line.direction().x() * line.direction().y()) > 0)
				return true;
		}

		// line exits the area at the corner
		if (lineInCornerAngleRange(line, corners[ndx].dp))
		{
			const bool startIsInside = corners[ndx].pointInclusive || p != line.m_v0;
			const bool endIsOutside = !corners[ndx].pointInclusive || p != line.m_v1;

			// starting point is inside the region and end endpoint is outside
			if (startIsInside && endIsOutside)
				return true;
		}

		// line end is at the corner
		if (p == line.m_v1)
		{
			if (corners[ndx].endBehavior == DiamondCorners::CORNER_END_CASE_DIRECTION ||
				corners[ndx].endBehavior == DiamondCorners::CORNER_END_CASE_DIRECTION_AND_FIRST_QUARTER ||
				corners[ndx].endBehavior == DiamondCorners::CORNER_END_CASE_DIRECTION_AND_SECOND_QUARTER)
			{
				// did the line intersect the region
				if (lineInCornerAngleRange(line, corners[ndx].dp))
					return true;
			}

			// due to the perturbed endpoint, lines at this the angle will cause and enter-exit pair
			if (corners[ndx].endBehavior == DiamondCorners::CORNER_END_CASE_DIRECTION_AND_FIRST_QUARTER &&
				line.direction().x() < 0 &&
				line.direction().y() > 0)
				return true;
			if (corners[ndx].endBehavior == DiamondCorners::CORNER_END_CASE_DIRECTION_AND_SECOND_QUARTER &&
				line.direction().x() > 0 &&
				line.direction().y() > 0)
				return true;
		}

		// line start is at the corner
		if (p == line.m_v0)
		{
			if (corners[ndx].startBehavior == DiamondCorners::CORNER_START_CASE_OUTSIDE)
			{
				// if the line is not going inside, it will exit
				if (lineInCornerOutsideAngleRange(line, corners[ndx].dp))
					return true;
			}

			// exit, if line the angle between line vector and X-axis is in range (0, 45] in positive Y side.
			if (corners[ndx].startBehavior == DiamondCorners::CORNER_START_CASE_POSITIVE_Y_45 &&
				line.direction().x() > 0 &&
				line.direction().y() > 0 &&
				line.direction().y() <= line.direction().x())
				return true;

			// exit, if line the angle between line vector and X-axis is in range [0, 45] in negative Y side.
			if (corners[ndx].startBehavior == DiamondCorners::CORNER_START_CASE_NEGATIVE_Y_45 &&
				 line.direction().x() > 0 &&
				 line.direction().y() <= 0 &&
				-line.direction().y() <= line.direction().x())
				return true;
		}
	}

	// Does the line intersect boundary at the left == exits the diamond
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bounds); ++ndx)
	{
		const bool startVertexInside =	LineRasterUtil::vertexOnLeftSideOfLine						(line.m_v0, LineRasterUtil::SubpixelLineSegment(bounds[ndx].p0, bounds[ndx].p1)) ||
										(bounds[ndx].edgeInclusive && LineRasterUtil::vertexOnLine	(line.m_v0, LineRasterUtil::SubpixelLineSegment(bounds[ndx].p0, bounds[ndx].p1)));
		const bool endVertexInside =	LineRasterUtil::vertexOnLeftSideOfLine						(line.m_v1, LineRasterUtil::SubpixelLineSegment(bounds[ndx].p0, bounds[ndx].p1)) ||
										(bounds[ndx].edgeInclusive && LineRasterUtil::vertexOnLine	(line.m_v1, LineRasterUtil::SubpixelLineSegment(bounds[ndx].p0, bounds[ndx].p1)));

		// start must be on inside this half space (left or at the inclusive boundary)
		if (!startVertexInside)
			continue;

		// end must be outside of this half-space (right or at non-inclusive boundary)
		if (endVertexInside)
			continue;

		// Does the line via v0 and v1 intersect the line segment p0-p1
		// <==> p0 and p1 are the different sides (LEFT, RIGHT) of the v0-v1 line.
		// Corners are not allowed, they are checked already
		LineRasterUtil::LINE_SIDE sideP0 = LineRasterUtil::getVertexSide(bounds[ndx].p0, line);
		LineRasterUtil::LINE_SIDE sideP1 = LineRasterUtil::getVertexSide(bounds[ndx].p1, line);

		if (sideP0 != LineRasterUtil::LINE_SIDE_INTERSECT &&
			sideP1 != LineRasterUtil::LINE_SIDE_INTERSECT &&
			sideP0 != sideP1)
			return true;
	}

	return false;
}

} // LineRasterUtil

TriangleRasterizer::TriangleRasterizer (const tcu::IVec4& viewport, const int numSamples, const RasterizationState& state)
	: m_viewport		(viewport)
	, m_numSamples		(numSamples)
	, m_winding			(state.winding)
	, m_horizontalFill	(state.horizontalFill)
	, m_verticalFill	(state.verticalFill)
	, m_face			(FACETYPE_LAST)
{
}

/*--------------------------------------------------------------------*//*!
 * \brief Initialize triangle rasterization
 * \param v0 Screen-space coordinates (x, y, z) and 1/w for vertex 0.
 * \param v1 Screen-space coordinates (x, y, z) and 1/w for vertex 1.
 * \param v2 Screen-space coordinates (x, y, z) and 1/w for vertex 2.
 *//*--------------------------------------------------------------------*/
void TriangleRasterizer::init (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2)
{
	m_v0 = v0;
	m_v1 = v1;
	m_v2 = v2;

	// Positions in fixed-point coordinates.
	const deInt64	x0		= toSubpixelCoord(v0.x());
	const deInt64	y0		= toSubpixelCoord(v0.y());
	const deInt64	x1		= toSubpixelCoord(v1.x());
	const deInt64	y1		= toSubpixelCoord(v1.y());
	const deInt64	x2		= toSubpixelCoord(v2.x());
	const deInt64	y2		= toSubpixelCoord(v2.y());

	// Initialize edge functions.
	if (m_winding == WINDING_CCW)
	{
		initEdgeCCW(m_edge01, m_horizontalFill, m_verticalFill, x0, y0, x1, y1);
		initEdgeCCW(m_edge12, m_horizontalFill, m_verticalFill, x1, y1, x2, y2);
		initEdgeCCW(m_edge20, m_horizontalFill, m_verticalFill, x2, y2, x0, y0);
	}
	else
	{
		// Reverse edges
		initEdgeCCW(m_edge01, m_horizontalFill, m_verticalFill, x1, y1, x0, y0);
		initEdgeCCW(m_edge12, m_horizontalFill, m_verticalFill, x2, y2, x1, y1);
		initEdgeCCW(m_edge20, m_horizontalFill, m_verticalFill, x0, y0, x2, y2);
	}

	// Determine face.
	const deInt64	s				= evaluateEdge(m_edge01, x2, y2);
	const bool		positiveArea	= (m_winding == WINDING_CCW) ? (s > 0) : (s < 0);
	m_face = positiveArea ? FACETYPE_FRONT : FACETYPE_BACK;

	if (!positiveArea)
	{
		// Reverse edges so that we can use CCW area tests & interpolation
		reverseEdge(m_edge01);
		reverseEdge(m_edge12);
		reverseEdge(m_edge20);
	}

	// Bounding box
	const deInt64	xMin	= de::min(de::min(x0, x1), x2);
	const deInt64	xMax	= de::max(de::max(x0, x1), x2);
	const deInt64	yMin	= de::min(de::min(y0, y1), y2);
	const deInt64	yMax	= de::max(de::max(y0, y1), y2);

	m_bboxMin.x() = floorSubpixelToPixelCoord	(xMin, m_horizontalFill	== FILL_LEFT);
	m_bboxMin.y() = floorSubpixelToPixelCoord	(yMin, m_verticalFill	== FILL_BOTTOM);
	m_bboxMax.x() = ceilSubpixelToPixelCoord	(xMax, m_horizontalFill	== FILL_RIGHT);
	m_bboxMax.y() = ceilSubpixelToPixelCoord	(yMax, m_verticalFill	== FILL_TOP);

	// Clamp to viewport
	const int		wX0		= m_viewport.x();
	const int		wY0		= m_viewport.y();
	const int		wX1		= wX0 + m_viewport.z() - 1;
	const int		wY1		= wY0 + m_viewport.w() -1;

	m_bboxMin.x() = de::clamp(m_bboxMin.x(), wX0, wX1);
	m_bboxMin.y() = de::clamp(m_bboxMin.y(), wY0, wY1);
	m_bboxMax.x() = de::clamp(m_bboxMax.x(), wX0, wX1);
	m_bboxMax.y() = de::clamp(m_bboxMax.y(), wY0, wY1);

	m_curPos = m_bboxMin;
}

void TriangleRasterizer::rasterizeSingleSample (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized)
{
	DE_ASSERT(maxFragmentPackets > 0);

	const deUint64	halfPixel	= 1ll << (RASTERIZER_SUBPIXEL_BITS-1);
	int				packetNdx	= 0;

	// For depth interpolation; given barycentrics A, B, C = (1 - A - B)
	// we can reformulate the usual z = z0*A + z1*B + z2*C into more
	// stable equation z = A*(z0 - z2) + B*(z1 - z2) + z2.
	const float		za			= m_v0.z()-m_v2.z();
	const float		zb			= m_v1.z()-m_v2.z();
	const float		zc			= m_v2.z();

	while (m_curPos.y() <= m_bboxMax.y() && packetNdx < maxFragmentPackets)
	{
		const int		x0		= m_curPos.x();
		const int		y0		= m_curPos.y();

		// Subpixel coords
		const deInt64	sx0		= toSubpixelCoord(x0)	+ halfPixel;
		const deInt64	sx1		= toSubpixelCoord(x0+1)	+ halfPixel;
		const deInt64	sy0		= toSubpixelCoord(y0)	+ halfPixel;
		const deInt64	sy1		= toSubpixelCoord(y0+1)	+ halfPixel;

		const deInt64	sx[4]	= { sx0, sx1, sx0, sx1 };
		const deInt64	sy[4]	= { sy0, sy0, sy1, sy1 };

		// Viewport test
		const bool		outX1	= x0+1 == m_viewport.x()+m_viewport.z();
		const bool		outY1	= y0+1 == m_viewport.y()+m_viewport.w();

		DE_ASSERT(x0 < m_viewport.x()+m_viewport.z());
		DE_ASSERT(y0 < m_viewport.y()+m_viewport.w());

		// Edge values
		tcu::Vector<deInt64, 4>	e01;
		tcu::Vector<deInt64, 4>	e12;
		tcu::Vector<deInt64, 4>	e20;

		// Coverage
		deUint64		coverage	= 0;

		// Evaluate edge values
		for (int i = 0; i < 4; i++)
		{
			e01[i] = evaluateEdge(m_edge01, sx[i], sy[i]);
			e12[i] = evaluateEdge(m_edge12, sx[i], sy[i]);
			e20[i] = evaluateEdge(m_edge20, sx[i], sy[i]);
		}

		// Compute coverage mask
		coverage = setCoverageValue(coverage, 1, 0, 0, 0,						isInsideCCW(m_edge01, e01[0]) && isInsideCCW(m_edge12, e12[0]) && isInsideCCW(m_edge20, e20[0]));
		coverage = setCoverageValue(coverage, 1, 1, 0, 0, !outX1 &&				isInsideCCW(m_edge01, e01[1]) && isInsideCCW(m_edge12, e12[1]) && isInsideCCW(m_edge20, e20[1]));
		coverage = setCoverageValue(coverage, 1, 0, 1, 0, !outY1 &&				isInsideCCW(m_edge01, e01[2]) && isInsideCCW(m_edge12, e12[2]) && isInsideCCW(m_edge20, e20[2]));
		coverage = setCoverageValue(coverage, 1, 1, 1, 0, !outX1 && !outY1 &&	isInsideCCW(m_edge01, e01[3]) && isInsideCCW(m_edge12, e12[3]) && isInsideCCW(m_edge20, e20[3]));

		// Advance to next location
		m_curPos.x() += 2;
		if (m_curPos.x() > m_bboxMax.x())
		{
			m_curPos.y() += 2;
			m_curPos.x()  = m_bboxMin.x();
		}

		if (coverage == 0)
			continue; // Discard.

		// Floating-point edge values for barycentrics etc.
		const tcu::Vec4		e01f	= e01.asFloat();
		const tcu::Vec4		e12f	= e12.asFloat();
		const tcu::Vec4		e20f	= e20.asFloat();

		// Compute depth values.
		if (depthValues)
		{
			const tcu::Vec4		edgeSum	= e01f + e12f + e20f;
			const tcu::Vec4		z0		= e12f / edgeSum;
			const tcu::Vec4		z1		= e20f / edgeSum;

			depthValues[packetNdx*4+0] = z0[0]*za + z1[0]*zb + zc;
			depthValues[packetNdx*4+1] = z0[1]*za + z1[1]*zb + zc;
			depthValues[packetNdx*4+2] = z0[2]*za + z1[2]*zb + zc;
			depthValues[packetNdx*4+3] = z0[3]*za + z1[3]*zb + zc;
		}

		// Compute barycentrics and write out fragment packet
		{
			FragmentPacket& packet = fragmentPackets[packetNdx];

			const tcu::Vec4		b0		= e12f * m_v0.w();
			const tcu::Vec4		b1		= e20f * m_v1.w();
			const tcu::Vec4		b2		= e01f * m_v2.w();
			const tcu::Vec4		bSum	= b0 + b1 + b2;

			packet.position			= tcu::IVec2(x0, y0);
			packet.coverage			= coverage;
			packet.barycentric[0]	= b0 / bSum;
			packet.barycentric[1]	= b1 / bSum;
			packet.barycentric[2]	= 1.0f - packet.barycentric[0] - packet.barycentric[1];

			packetNdx += 1;
		}
	}

	DE_ASSERT(packetNdx <= maxFragmentPackets);
	numPacketsRasterized = packetNdx;
}

// Sample positions - ordered as (x, y) list.

// \note Macros are used to eliminate function calls even in debug builds.
#define SAMPLE_POS_TO_SUBPIXEL_COORD(POS)	\
	(deInt64)((POS) * (1<<RASTERIZER_SUBPIXEL_BITS) + 0.5f)

#define SAMPLE_POS(X, Y)	\
	SAMPLE_POS_TO_SUBPIXEL_COORD(X), SAMPLE_POS_TO_SUBPIXEL_COORD(Y)

static const deInt64 s_samplePos2[] =
{
	SAMPLE_POS(0.3f, 0.3f),
	SAMPLE_POS(0.7f, 0.7f)
};

static const deInt64 s_samplePos4[] =
{
	SAMPLE_POS(0.25f, 0.25f),
	SAMPLE_POS(0.75f, 0.25f),
	SAMPLE_POS(0.25f, 0.75f),
	SAMPLE_POS(0.75f, 0.75f)
};
DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_samplePos4) == 4*2);

static const deInt64 s_samplePos8[] =
{
	SAMPLE_POS( 7.f/16.f,  9.f/16.f),
	SAMPLE_POS( 9.f/16.f, 13.f/16.f),
	SAMPLE_POS(11.f/16.f,  3.f/16.f),
	SAMPLE_POS(13.f/16.f, 11.f/16.f),
	SAMPLE_POS( 1.f/16.f,  7.f/16.f),
	SAMPLE_POS( 5.f/16.f,  1.f/16.f),
	SAMPLE_POS(15.f/16.f,  5.f/16.f),
	SAMPLE_POS( 3.f/16.f, 15.f/16.f)
};
DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_samplePos8) == 8*2);

static const deInt64 s_samplePos16[] =
{
	SAMPLE_POS(1.f/8.f, 1.f/8.f),
	SAMPLE_POS(3.f/8.f, 1.f/8.f),
	SAMPLE_POS(5.f/8.f, 1.f/8.f),
	SAMPLE_POS(7.f/8.f, 1.f/8.f),
	SAMPLE_POS(1.f/8.f, 3.f/8.f),
	SAMPLE_POS(3.f/8.f, 3.f/8.f),
	SAMPLE_POS(5.f/8.f, 3.f/8.f),
	SAMPLE_POS(7.f/8.f, 3.f/8.f),
	SAMPLE_POS(1.f/8.f, 5.f/8.f),
	SAMPLE_POS(3.f/8.f, 5.f/8.f),
	SAMPLE_POS(5.f/8.f, 5.f/8.f),
	SAMPLE_POS(7.f/8.f, 5.f/8.f),
	SAMPLE_POS(1.f/8.f, 7.f/8.f),
	SAMPLE_POS(3.f/8.f, 7.f/8.f),
	SAMPLE_POS(5.f/8.f, 7.f/8.f),
	SAMPLE_POS(7.f/8.f, 7.f/8.f)
};
DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_samplePos16) == 16*2);

#undef SAMPLE_POS
#undef SAMPLE_POS_TO_SUBPIXEL_COORD

template<int NumSamples>
void TriangleRasterizer::rasterizeMultiSample (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized)
{
	DE_ASSERT(maxFragmentPackets > 0);

	const deInt64*	samplePos	= DE_NULL;
	const deUint64	halfPixel	= 1ll << (RASTERIZER_SUBPIXEL_BITS-1);
	int				packetNdx	= 0;

	// For depth interpolation, see rasterizeSingleSample
	const float		za			= m_v0.z()-m_v2.z();
	const float		zb			= m_v1.z()-m_v2.z();
	const float		zc			= m_v2.z();

	switch (NumSamples)
	{
		case 2:		samplePos = s_samplePos2;	break;
		case 4:		samplePos = s_samplePos4;	break;
		case 8:		samplePos = s_samplePos8;	break;
		case 16:	samplePos = s_samplePos16;	break;
		default:
			DE_ASSERT(false);
	}

	while (m_curPos.y() <= m_bboxMax.y() && packetNdx < maxFragmentPackets)
	{
		const int		x0		= m_curPos.x();
		const int		y0		= m_curPos.y();

		// Base subpixel coords
		const deInt64	sx0		= toSubpixelCoord(x0);
		const deInt64	sx1		= toSubpixelCoord(x0+1);
		const deInt64	sy0		= toSubpixelCoord(y0);
		const deInt64	sy1		= toSubpixelCoord(y0+1);

		const deInt64	sx[4]	= { sx0, sx1, sx0, sx1 };
		const deInt64	sy[4]	= { sy0, sy0, sy1, sy1 };

		// Viewport test
		const bool		outX1	= x0+1 == m_viewport.x()+m_viewport.z();
		const bool		outY1	= y0+1 == m_viewport.y()+m_viewport.w();

		DE_ASSERT(x0 < m_viewport.x()+m_viewport.z());
		DE_ASSERT(y0 < m_viewport.y()+m_viewport.w());

		// Edge values
		tcu::Vector<deInt64, 4>	e01[NumSamples];
		tcu::Vector<deInt64, 4>	e12[NumSamples];
		tcu::Vector<deInt64, 4>	e20[NumSamples];

		// Coverage
		deUint64		coverage	= 0;

		// Evaluate edge values at sample positions
		for (int sampleNdx = 0; sampleNdx < NumSamples; sampleNdx++)
		{
			const deInt64 ox = samplePos[sampleNdx*2 + 0];
			const deInt64 oy = samplePos[sampleNdx*2 + 1];

			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
			{
				e01[sampleNdx][fragNdx] = evaluateEdge(m_edge01, sx[fragNdx] + ox, sy[fragNdx] + oy);
				e12[sampleNdx][fragNdx] = evaluateEdge(m_edge12, sx[fragNdx] + ox, sy[fragNdx] + oy);
				e20[sampleNdx][fragNdx] = evaluateEdge(m_edge20, sx[fragNdx] + ox, sy[fragNdx] + oy);
			}
		}

		// Compute coverage mask
		for (int sampleNdx = 0; sampleNdx < NumSamples; sampleNdx++)
		{
			coverage = setCoverageValue(coverage, NumSamples, 0, 0, sampleNdx,						isInsideCCW(m_edge01, e01[sampleNdx][0]) && isInsideCCW(m_edge12, e12[sampleNdx][0]) && isInsideCCW(m_edge20, e20[sampleNdx][0]));
			coverage = setCoverageValue(coverage, NumSamples, 1, 0, sampleNdx, !outX1 &&			isInsideCCW(m_edge01, e01[sampleNdx][1]) && isInsideCCW(m_edge12, e12[sampleNdx][1]) && isInsideCCW(m_edge20, e20[sampleNdx][1]));
			coverage = setCoverageValue(coverage, NumSamples, 0, 1, sampleNdx, !outY1 &&			isInsideCCW(m_edge01, e01[sampleNdx][2]) && isInsideCCW(m_edge12, e12[sampleNdx][2]) && isInsideCCW(m_edge20, e20[sampleNdx][2]));
			coverage = setCoverageValue(coverage, NumSamples, 1, 1, sampleNdx, !outX1 && !outY1 &&	isInsideCCW(m_edge01, e01[sampleNdx][3]) && isInsideCCW(m_edge12, e12[sampleNdx][3]) && isInsideCCW(m_edge20, e20[sampleNdx][3]));
		}

		// Advance to next location
		m_curPos.x() += 2;
		if (m_curPos.x() > m_bboxMax.x())
		{
			m_curPos.y() += 2;
			m_curPos.x()  = m_bboxMin.x();
		}

		if (coverage == 0)
			continue; // Discard.

		// Compute depth values.
		if (depthValues)
		{
			for (int sampleNdx = 0; sampleNdx < NumSamples; sampleNdx++)
			{
				// Floating-point edge values at sample coordinates.
				const tcu::Vec4&	e01f	= e01[sampleNdx].asFloat();
				const tcu::Vec4&	e12f	= e12[sampleNdx].asFloat();
				const tcu::Vec4&	e20f	= e20[sampleNdx].asFloat();

				const tcu::Vec4		edgeSum	= e01f + e12f + e20f;
				const tcu::Vec4		z0		= e12f / edgeSum;
				const tcu::Vec4		z1		= e20f / edgeSum;

				depthValues[(packetNdx*4+0)*NumSamples + sampleNdx] = z0[0]*za + z1[0]*zb + zc;
				depthValues[(packetNdx*4+1)*NumSamples + sampleNdx] = z0[1]*za + z1[1]*zb + zc;
				depthValues[(packetNdx*4+2)*NumSamples + sampleNdx] = z0[2]*za + z1[2]*zb + zc;
				depthValues[(packetNdx*4+3)*NumSamples + sampleNdx] = z0[3]*za + z1[3]*zb + zc;
			}
		}

		// Compute barycentrics and write out fragment packet
		{
			FragmentPacket& packet = fragmentPackets[packetNdx];

			// Floating-point edge values at pixel center.
			tcu::Vec4			e01f;
			tcu::Vec4			e12f;
			tcu::Vec4			e20f;

			for (int i = 0; i < 4; i++)
			{
				e01f[i] = float(evaluateEdge(m_edge01, sx[i] + halfPixel, sy[i] + halfPixel));
				e12f[i] = float(evaluateEdge(m_edge12, sx[i] + halfPixel, sy[i] + halfPixel));
				e20f[i] = float(evaluateEdge(m_edge20, sx[i] + halfPixel, sy[i] + halfPixel));
			}

			// Barycentrics & scale.
			const tcu::Vec4		b0		= e12f * m_v0.w();
			const tcu::Vec4		b1		= e20f * m_v1.w();
			const tcu::Vec4		b2		= e01f * m_v2.w();
			const tcu::Vec4		bSum	= b0 + b1 + b2;

			packet.position			= tcu::IVec2(x0, y0);
			packet.coverage			= coverage;
			packet.barycentric[0]	= b0 / bSum;
			packet.barycentric[1]	= b1 / bSum;
			packet.barycentric[2]	= 1.0f - packet.barycentric[0] - packet.barycentric[1];

			packetNdx += 1;
		}
	}

	DE_ASSERT(packetNdx <= maxFragmentPackets);
	numPacketsRasterized = packetNdx;
}

void TriangleRasterizer::rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized)
{
	DE_ASSERT(maxFragmentPackets > 0);

	switch (m_numSamples)
	{
		case 1:		rasterizeSingleSample		(fragmentPackets, depthValues, maxFragmentPackets, numPacketsRasterized);	break;
		case 2:		rasterizeMultiSample<2>		(fragmentPackets, depthValues, maxFragmentPackets, numPacketsRasterized);	break;
		case 4:		rasterizeMultiSample<4>		(fragmentPackets, depthValues, maxFragmentPackets, numPacketsRasterized);	break;
		case 8:		rasterizeMultiSample<8>		(fragmentPackets, depthValues, maxFragmentPackets, numPacketsRasterized);	break;
		case 16:	rasterizeMultiSample<16>	(fragmentPackets, depthValues, maxFragmentPackets, numPacketsRasterized);	break;
		default:
			DE_ASSERT(DE_FALSE);
	}
}

SingleSampleLineRasterizer::SingleSampleLineRasterizer (const tcu::IVec4& viewport)
	: m_viewport		(viewport)
	, m_curRowFragment	(0)
	, m_lineWidth		(0.0f)
{
}

SingleSampleLineRasterizer::~SingleSampleLineRasterizer (void)
{
}

void SingleSampleLineRasterizer::init (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth)
{
	const bool						isXMajor		= de::abs((v1 - v0).x()) >= de::abs((v1 - v0).y());

	// Bounding box \note: with wide lines, the line is actually moved as in the spec
	const deInt32					lineWidthPixels	= (lineWidth > 1.0f) ? (deInt32)floor(lineWidth + 0.5f) : 1;

	const tcu::Vector<deInt64,2>	widthOffset		= (isXMajor ? tcu::Vector<deInt64,2>(0, -1) : tcu::Vector<deInt64,2>(-1, 0)) * (toSubpixelCoord(lineWidthPixels - 1) / 2);

	const deInt64					x0				= toSubpixelCoord(v0.x()) + widthOffset.x();
	const deInt64					y0				= toSubpixelCoord(v0.y()) + widthOffset.y();
	const deInt64					x1				= toSubpixelCoord(v1.x()) + widthOffset.x();
	const deInt64					y1				= toSubpixelCoord(v1.y()) + widthOffset.y();

	// line endpoints might be perturbed, add some margin
	const deInt64					xMin			= de::min(x0, x1) - toSubpixelCoord(1);
	const deInt64					xMax			= de::max(x0, x1) + toSubpixelCoord(1);
	const deInt64					yMin			= de::min(y0, y1) - toSubpixelCoord(1);
	const deInt64					yMax			= de::max(y0, y1) + toSubpixelCoord(1);

	// Remove invisible area

	if (isXMajor)
	{
		// clamp to viewport in major direction
		m_bboxMin.x() = de::clamp(floorSubpixelToPixelCoord(xMin, true), m_viewport.x(), m_viewport.x() + m_viewport.z() - 1);
		m_bboxMax.x() = de::clamp(ceilSubpixelToPixelCoord (xMax, true), m_viewport.x(), m_viewport.x() + m_viewport.z() - 1);

		// clamp to padded viewport in minor direction (wide lines might bleed over viewport in minor direction)
		m_bboxMin.y() = de::clamp(floorSubpixelToPixelCoord(yMin, true), m_viewport.y() - lineWidthPixels, m_viewport.y() + m_viewport.w() - 1);
		m_bboxMax.y() = de::clamp(ceilSubpixelToPixelCoord (yMax, true), m_viewport.y() - lineWidthPixels, m_viewport.y() + m_viewport.w() - 1);
	}
	else
	{
		// clamp to viewport in major direction
		m_bboxMin.y() = de::clamp(floorSubpixelToPixelCoord(yMin, true), m_viewport.y(), m_viewport.y() + m_viewport.w() - 1);
		m_bboxMax.y() = de::clamp(ceilSubpixelToPixelCoord (yMax, true), m_viewport.y(), m_viewport.y() + m_viewport.w() - 1);

		// clamp to padded viewport in minor direction (wide lines might bleed over viewport in minor direction)
		m_bboxMin.x() = de::clamp(floorSubpixelToPixelCoord(xMin, true), m_viewport.x() - lineWidthPixels, m_viewport.x() + m_viewport.z() - 1);
		m_bboxMax.x() = de::clamp(ceilSubpixelToPixelCoord (xMax, true), m_viewport.x() - lineWidthPixels, m_viewport.x() + m_viewport.z() - 1);
	}

	m_lineWidth = lineWidth;

	m_v0 = v0;
	m_v1 = v1;

	m_curPos = m_bboxMin;
	m_curRowFragment = 0;
}

void SingleSampleLineRasterizer::rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized)
{
	DE_ASSERT(maxFragmentPackets > 0);

	const deInt64								halfPixel			= 1ll << (RASTERIZER_SUBPIXEL_BITS-1);
	const deInt32								lineWidth			= (m_lineWidth > 1.0f) ? deFloorFloatToInt32(m_lineWidth + 0.5f) : 1;
	const bool									isXMajor			= de::abs((m_v1 - m_v0).x()) >= de::abs((m_v1 - m_v0).y());
	const tcu::IVec2							minorDirection		= (isXMajor) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));
	const int									minViewportLimit	= (isXMajor) ? (m_viewport.y()) : (m_viewport.x());
	const int									maxViewportLimit	= (isXMajor) ? (m_viewport.y() + m_viewport.w()) : (m_viewport.x() + m_viewport.z());
	const tcu::Vector<deInt64,2>				widthOffset			= -minorDirection.cast<deInt64>() * (toSubpixelCoord(lineWidth - 1) / 2);
	const tcu::Vector<deInt64,2>				pa					= LineRasterUtil::toSubpixelVector(m_v0.xy()) + widthOffset;
	const tcu::Vector<deInt64,2>				pb					= LineRasterUtil::toSubpixelVector(m_v1.xy()) + widthOffset;
	const LineRasterUtil::SubpixelLineSegment	line				= LineRasterUtil::SubpixelLineSegment(pa, pb);

	int											packetNdx			= 0;

	while (m_curPos.y() <= m_bboxMax.y() && packetNdx < maxFragmentPackets)
	{
		const tcu::Vector<deInt64,2> diamondPosition = LineRasterUtil::toSubpixelVector(m_curPos) + tcu::Vector<deInt64,2>(halfPixel,halfPixel);

		// Should current fragment be drawn? == does the segment exit this diamond?
		if (LineRasterUtil::doesLineSegmentExitDiamond(line, diamondPosition))
		{
			const tcu::Vector<deInt64,2>	pr					= diamondPosition;
			const float						t					= tcu::dot((pr - pa).asFloat(), (pb - pa).asFloat()) / tcu::lengthSquared(pb.asFloat() - pa.asFloat());

			// Rasterize on only fragments that are would end up in the viewport (i.e. visible)
			const int						fragmentLocation	= (isXMajor) ? (m_curPos.y()) : (m_curPos.x());
			const int						rowFragBegin		= de::max(0, minViewportLimit - fragmentLocation);
			const int						rowFragEnd			= de::min(maxViewportLimit - fragmentLocation, lineWidth);

			// Wide lines require multiple fragments.
			for (; rowFragBegin + m_curRowFragment < rowFragEnd; m_curRowFragment++)
			{
				const int			replicationId	= rowFragBegin + m_curRowFragment;
				const tcu::IVec2	fragmentPos		= m_curPos + minorDirection * replicationId;

				// We only rasterize visible area
				DE_ASSERT(LineRasterUtil::inViewport(fragmentPos, m_viewport));

				// Compute depth values.
				if (depthValues)
				{
					const float za = m_v0.z();
					const float zb = m_v1.z();

					depthValues[packetNdx*4+0] = (1 - t) * za + t * zb;
					depthValues[packetNdx*4+1] = 0;
					depthValues[packetNdx*4+2] = 0;
					depthValues[packetNdx*4+3] = 0;
				}

				{
					// output this fragment
					// \note In order to make consistent output with multisampled line rasterization, output "barycentric" coordinates
					FragmentPacket& packet = fragmentPackets[packetNdx];

					const tcu::Vec4		b0		= tcu::Vec4(1 - t);
					const tcu::Vec4		b1		= tcu::Vec4(t);
					const tcu::Vec4		ooSum	= 1.0f / (b0 + b1);

					packet.position			= fragmentPos;
					packet.coverage			= getCoverageBit(1, 0, 0, 0);
					packet.barycentric[0]	= b0 * ooSum;
					packet.barycentric[1]	= b1 * ooSum;
					packet.barycentric[2]	= tcu::Vec4(0.0f);

					packetNdx += 1;
				}

				if (packetNdx == maxFragmentPackets)
				{
					m_curRowFragment++; // don't redraw this fragment again next time
					numPacketsRasterized = packetNdx;
					return;
				}
			}

			m_curRowFragment = 0;
		}

		++m_curPos.x();
		if (m_curPos.x() > m_bboxMax.x())
		{
			++m_curPos.y();
			m_curPos.x() = m_bboxMin.x();
		}
	}

	DE_ASSERT(packetNdx <= maxFragmentPackets);
	numPacketsRasterized = packetNdx;
}

MultiSampleLineRasterizer::MultiSampleLineRasterizer (const int numSamples, const tcu::IVec4& viewport)
	: m_numSamples			(numSamples)
	, m_triangleRasterizer0 (viewport, m_numSamples, RasterizationState())
	, m_triangleRasterizer1 (viewport, m_numSamples, RasterizationState())
{
}

MultiSampleLineRasterizer::~MultiSampleLineRasterizer ()
{
}

void MultiSampleLineRasterizer::init (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth)
{
	// allow creation of single sampled rasterizer objects but do not allow using them
	DE_ASSERT(m_numSamples > 1);

	const tcu::Vec2 lineVec		= tcu::Vec2(tcu::Vec4(v1).xy()) - tcu::Vec2(tcu::Vec4(v0).xy());
	const tcu::Vec2 normal2		= tcu::normalize(tcu::Vec2(-lineVec[1], lineVec[0]));
	const tcu::Vec4 normal4		= tcu::Vec4(normal2.x(), normal2.y(), 0, 0);
	const float offset			= lineWidth / 2.0f;

	const tcu::Vec4 p0 = v0 + normal4 * offset;
	const tcu::Vec4 p1 = v0 - normal4 * offset;
	const tcu::Vec4 p2 = v1 - normal4 * offset;
	const tcu::Vec4 p3 = v1 + normal4 * offset;

	// Edge 0 -> 1 is always along the line and edge 1 -> 2 is in 90 degree angle to the line
	m_triangleRasterizer0.init(p0, p3, p2);
	m_triangleRasterizer1.init(p2, p1, p0);
}

void MultiSampleLineRasterizer::rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized)
{
	DE_ASSERT(maxFragmentPackets > 0);

	m_triangleRasterizer0.rasterize(fragmentPackets, depthValues, maxFragmentPackets, numPacketsRasterized);

	// Remove 3rd barycentric value and rebalance. Lines do not have non-zero barycentric at index 2
	for (int packNdx = 0; packNdx < numPacketsRasterized; ++packNdx)
	for (int fragNdx = 0; fragNdx < 4; fragNdx++)
	{
		float removedValue = fragmentPackets[packNdx].barycentric[2][fragNdx];
		fragmentPackets[packNdx].barycentric[2][fragNdx] = 0.0f;
		fragmentPackets[packNdx].barycentric[1][fragNdx] += removedValue;
	}

	// rasterizer 0 filled the whole buffer?
	if (numPacketsRasterized == maxFragmentPackets)
		return;

	{
		FragmentPacket* const nextFragmentPackets	= fragmentPackets + numPacketsRasterized;
		float* nextDepthValues						= (depthValues) ? (depthValues+4*numPacketsRasterized*m_numSamples) : (DE_NULL);
		int numPacketsRasterized2					= 0;

		m_triangleRasterizer1.rasterize(nextFragmentPackets, nextDepthValues, maxFragmentPackets - numPacketsRasterized, numPacketsRasterized2);

		numPacketsRasterized += numPacketsRasterized2;

		// Fix swapped barycentrics in the second triangle
		for (int packNdx = 0; packNdx < numPacketsRasterized2; ++packNdx)
		for (int fragNdx = 0; fragNdx < 4; fragNdx++)
		{
			float removedValue = nextFragmentPackets[packNdx].barycentric[2][fragNdx];
			nextFragmentPackets[packNdx].barycentric[2][fragNdx] = 0.0f;
			nextFragmentPackets[packNdx].barycentric[1][fragNdx] += removedValue;

			// edge has reversed direction
			std::swap(nextFragmentPackets[packNdx].barycentric[0][fragNdx], nextFragmentPackets[packNdx].barycentric[1][fragNdx]);
		}
	}
}

LineExitDiamondGenerator::LineExitDiamondGenerator (void)
{
}

LineExitDiamondGenerator::~LineExitDiamondGenerator (void)
{
}

void LineExitDiamondGenerator::init (const tcu::Vec4& v0, const tcu::Vec4& v1)
{
	const deInt64					x0				= toSubpixelCoord(v0.x());
	const deInt64					y0				= toSubpixelCoord(v0.y());
	const deInt64					x1				= toSubpixelCoord(v1.x());
	const deInt64					y1				= toSubpixelCoord(v1.y());

	// line endpoints might be perturbed, add some margin
	const deInt64					xMin			= de::min(x0, x1) - toSubpixelCoord(1);
	const deInt64					xMax			= de::max(x0, x1) + toSubpixelCoord(1);
	const deInt64					yMin			= de::min(y0, y1) - toSubpixelCoord(1);
	const deInt64					yMax			= de::max(y0, y1) + toSubpixelCoord(1);

	m_bboxMin.x() = floorSubpixelToPixelCoord(xMin, true);
	m_bboxMin.y() = floorSubpixelToPixelCoord(yMin, true);
	m_bboxMax.x() = ceilSubpixelToPixelCoord (xMax, true);
	m_bboxMax.y() = ceilSubpixelToPixelCoord (yMax, true);

	m_v0 = v0;
	m_v1 = v1;

	m_curPos = m_bboxMin;
}

void LineExitDiamondGenerator::rasterize (LineExitDiamond* const lineDiamonds, const int maxDiamonds, int& numWritten)
{
	DE_ASSERT(maxDiamonds > 0);

	const deInt64								halfPixel			= 1ll << (RASTERIZER_SUBPIXEL_BITS-1);
	const tcu::Vector<deInt64,2>				pa					= LineRasterUtil::toSubpixelVector(m_v0.xy());
	const tcu::Vector<deInt64,2>				pb					= LineRasterUtil::toSubpixelVector(m_v1.xy());
	const LineRasterUtil::SubpixelLineSegment	line				= LineRasterUtil::SubpixelLineSegment(pa, pb);

	int											diamondNdx			= 0;

	while (m_curPos.y() <= m_bboxMax.y() && diamondNdx < maxDiamonds)
	{
		const tcu::Vector<deInt64,2> diamondPosition = LineRasterUtil::toSubpixelVector(m_curPos) + tcu::Vector<deInt64,2>(halfPixel,halfPixel);

		if (LineRasterUtil::doesLineSegmentExitDiamond(line, diamondPosition))
		{
			LineExitDiamond& packet = lineDiamonds[diamondNdx];
			packet.position = m_curPos;
			++diamondNdx;
		}

		++m_curPos.x();
		if (m_curPos.x() > m_bboxMax.x())
		{
			++m_curPos.y();
			m_curPos.x() = m_bboxMin.x();
		}
	}

	DE_ASSERT(diamondNdx <= maxDiamonds);
	numWritten = diamondNdx;
}

} // rr
