13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 2.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Multisampling tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2fMultisampleTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glw.h"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec2;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec4;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float SQRT_HALF = 0.707107f;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct QuadCorners
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2 p0;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2 p1;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2 p2;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2 p3;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	QuadCorners(const Vec2& p0_, const Vec2& p1_, const Vec2& p2_, const Vec2& p3_) : p0(p0_), p1(p1_), p2(p2_), p3(p3_) {}
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getIterationCount (const tcu::TestContext& ctx, int defaultCount)
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int cmdLineValue = ctx.getCommandLine().getTestIterationCount();
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return cmdLineValue > 0 ? cmdLineValue : defaultCount;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getGLInteger (GLenum name)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int result;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glGetIntegerv(name, &result));
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T>
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T min4 (T a, T b, T c, T d)
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::min(de::min(de::min(a, b), c), d);
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T>
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T max4 (T a, T b, T c, T d)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::max(de::max(de::max(a, b), c), d);
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isInsideQuad (const IVec2& point, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int dot0 = (point.x()-p0.x()) * (p1.y()-p0.y()) + (point.y()-p0.y()) * (p0.x()-p1.x());
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int dot1 = (point.x()-p1.x()) * (p2.y()-p1.y()) + (point.y()-p1.y()) * (p1.x()-p2.x());
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int dot2 = (point.x()-p2.x()) * (p3.y()-p2.y()) + (point.y()-p2.y()) * (p2.x()-p3.x());
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int dot3 = (point.x()-p3.x()) * (p0.y()-p3.y()) + (point.y()-p3.y()) * (p3.x()-p0.x());
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (dot0 > 0) == (dot1 > 0) && (dot1 > 0) == (dot2 > 0) && (dot2 > 0) == (dot3 > 0);
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Check if a region in an image is unicolored.
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Checks if the pixels in img inside the convex quadilateral defined by
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * p0, p1, p2 and p3 are all (approximately) of the same color.
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isPixelRegionUnicolored (const tcu::Surface& img, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			xMin				= de::clamp(min4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			yMin				= de::clamp(min4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			xMax				= de::clamp(max4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			yMax				= de::clamp(max4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		insideEncountered	= false;	//!< Whether we have already seen at least one pixel inside the region.
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::RGBA	insideColor;					//!< Color of the first pixel inside the region.
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = yMin; y <= yMax; y++)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = xMin; x <= xMax; x++)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isInsideQuad(IVec2(x, y), p0, p1, p2, p3))
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::RGBA pixColor = img.getPixel(x, y);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (insideEncountered)
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!tcu::compareThreshold(pixColor, insideColor, tcu::RGBA(3, 3, 3, 3))) // Pixel color differs from already-detected color inside same region - region not unicolored.
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				insideEncountered = true;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				insideColor = pixColor;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool drawUnicolorTestErrors (tcu::Surface& img, const tcu::PixelBufferAccess& errorImg, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			xMin		= de::clamp(min4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			yMin		= de::clamp(min4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			xMax		= de::clamp(max4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			yMax		= de::clamp(max4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::RGBA	refColor	= img.getPixel((xMin + xMax) / 2, (yMin + yMax) / 2);
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = yMin; y <= yMax; y++)
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = xMin; x <= xMax; x++)
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isInsideQuad(IVec2(x, y), p0, p1, p2, p3))
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!tcu::compareThreshold(img.getPixel(x, y), refColor, tcu::RGBA(3, 3, 3, 3)))
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				img.setPixel(x, y, tcu::RGBA::red);
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				errorImg.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Abstract base class handling common stuff for multisample cases.
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MultisampleCase : public TestCase
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						MultisampleCase			(Context& context, const char* name, const char* desc);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual				~MultisampleCase		(void);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void		init					(void);
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void		deinit					(void);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual int			getDesiredViewportSize	(void) const = 0;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderTriangle			(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderTriangle			(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderTriangle			(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderTriangle			(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderQuad				(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& c0, const Vec4& c1, const Vec4& c2, const Vec4& c3) const;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderQuad				(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderLine				(const Vec2& p0, const Vec2& p1, const Vec4& color) const;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				randomizeViewport		(void);
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				readImage				(tcu::Surface& dst) const;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numSamples;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_viewportSize;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						MultisampleCase			(const MultisampleCase& other);
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MultisampleCase&	operator=				(const MultisampleCase& other);
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*	m_program;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_attrPositionLoc;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_attrColorLoc;
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_viewportX;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_viewportY;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random			m_rnd;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleCase::MultisampleCase (Context& context, const char* name, const char* desc)
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numSamples		(0)
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportSize	(0)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program			(DE_NULL)
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_attrPositionLoc	(-1)
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_attrColorLoc	(-1)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportX		(0)
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportY		(0)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rnd				(deStringHash(name))
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float vertexPositions[] =
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		p0.x(), p0.y(), p0.z(), 1.0f,
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		p1.x(), p1.y(), p1.z(), 1.0f,
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		p2.x(), p2.y(), p2.z(), 1.0f
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float vertexColors[] =
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		c0.x(), c0.y(), c0.z(), c0.w(),
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		c1.x(), c1.y(), c1.z(), c1.w(),
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		c2.x(), c2.y(), c2.z(), c2.w(),
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrPositionLoc));
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glVertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, &vertexPositions[0]));
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrColorLoc));
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glVertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, &vertexColors[0]));
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(p0, p1, p2, color, color, color);
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(Vec3(p0.x(), p0.y(), 0.0f),
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   Vec3(p1.x(), p1.y(), 0.0f),
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   Vec3(p2.x(), p2.y(), 0.0f),
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   c0, c1, c2);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(p0, p1, p2, color, color, color);
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& c0, const Vec4& c1, const Vec4& c2, const Vec4& c3) const
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(p0, p1, p2, c0, c1, c2);
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(p2, p1, p3, c2, c1, c3);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderQuad(p0, p1, p2, p3, color, color, color, color);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::renderLine (const Vec2& p0, const Vec2& p1, const Vec4& color) const
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float vertexPositions[] =
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		p0.x(), p0.y(), 0.0f, 1.0f,
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		p1.x(), p1.y(), 0.0f, 1.0f
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float vertexColors[] =
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		color.x(), color.y(), color.z(), color.w(),
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		color.x(), color.y(), color.z(), color.w()
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrPositionLoc));
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glVertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, &vertexPositions[0]));
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrColorLoc));
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glVertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, &vertexColors[0]));
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glDrawArrays(GL_LINES, 0, 2));
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::randomizeViewport (void)
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportX = m_rnd.getInt(0, m_context.getRenderTarget().getWidth() - m_viewportSize);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportY = m_rnd.getInt(0, m_context.getRenderTarget().getHeight() - m_viewportSize);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glViewport(m_viewportX, m_viewportY, m_viewportSize, m_viewportSize));
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::readImage (tcu::Surface& dst) const
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), m_viewportX, m_viewportY, dst.getAccess());
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::init (void)
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* vertShaderSource =
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec4 a_position;\n"
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute mediump vec4 a_color;\n"
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_color;\n"
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_position;\n"
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_color = a_color;\n"
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* fragShaderSource =
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_color;\n"
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_FragColor = v_color;\n"
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check multisample support.
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context.getRenderTarget().getNumSamples() <= 1)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("No multisample buffers");
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prepare program.
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_program->isOk())
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Failed to compile program", DE_NULL, __FILE__, __LINE__);
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(m_attrPositionLoc	= glGetAttribLocation(m_program->getProgram(), "a_position"));
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(m_attrColorLoc		= glGetAttribLocation(m_program->getProgram(), "a_color"));
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_attrPositionLoc < 0 || m_attrColorLoc < 0)
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_program;
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Invalid attribute locations", DE_NULL, __FILE__, __LINE__);
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get suitable viewport size.
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportSize = de::min<int>(getDesiredViewportSize(), de::min(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight()));
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Query and log number of samples per pixel.
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numSamples = getGLInteger(GL_SAMPLES);
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "GL_SAMPLES = " << m_numSamples << TestLog::EndMessage;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleCase::~MultisampleCase (void)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleCase::deinit (void)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Base class for cases testing the value of GL_SAMPLES.
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws a test pattern (defined by renderPattern() of an inheriting class)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and counts the number of distinct colors in the resulting image. That
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * number should be at least the value of GL_SAMPLES plus one. This is
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * repeated with increased values of m_currentIteration until this correct
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * number of colors is detected or m_currentIteration reaches
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * m_maxNumIterations.
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass NumSamplesCase : public MultisampleCase
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						NumSamplesCase			(Context& context, const char* name, const char* description);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~NumSamplesCase			(void) {}
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate					(void);
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getDesiredViewportSize	(void) const { return 256; }
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void		renderPattern			(void) const = 0;
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_currentIteration;
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum { DEFAULT_MAX_NUM_ITERATIONS = 16 };
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			m_maxNumIterations;
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<tcu::RGBA>	m_detectedColors;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryNumSamplesCase::NumSamplesCase (Context& context, const char* name, const char* description)
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: MultisampleCase		(context, name, description)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentIteration	(0)
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxNumIterations	(getIterationCount(m_testCtx, DEFAULT_MAX_NUM_ITERATIONS))
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryNumSamplesCase::IterateResult NumSamplesCase::iterate (void)
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log				= m_testCtx.getLog();
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderPattern();
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read and log rendered image.
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImg);
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Detect new, previously unseen colors from image.
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int requiredNumDistinctColors = m_numSamples + 1;
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight() && (int)m_detectedColors.size() < requiredNumDistinctColors; y++)
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < renderedImg.getWidth() && (int)m_detectedColors.size() < requiredNumDistinctColors; x++)
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::RGBA color = renderedImg.getPixel(x, y);
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int i;
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (i = 0; i < (int)m_detectedColors.size(); i++)
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (tcu::compareThreshold(color, m_detectedColors[i], tcu::RGBA(3, 3, 3, 3)))
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i == (int)m_detectedColors.size())
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_detectedColors.push_back(color); // Color not previously detected.
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Log results.
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Number of distinct colors detected so far: "
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< ((int)m_detectedColors.size() >= requiredNumDistinctColors ? "at least " : "")
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< de::toString(m_detectedColors.size())
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((int)m_detectedColors.size() < requiredNumDistinctColors)
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Haven't detected enough different colors yet.
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_currentIteration++;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_currentIteration >= m_maxNumIterations)
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Failure: Number of distinct colors detected is lower than GL_SAMPLES+1" << TestLog::EndMessage;
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "The number of distinct colors detected is lower than GL_SAMPLES+1 - trying again with a slightly altered pattern" << TestLog::EndMessage;
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return CONTINUE;
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: The number of distinct colors detected is at least GL_SAMPLES+1" << TestLog::EndMessage;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PolygonNumSamplesCase : public NumSamplesCase
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PolygonNumSamplesCase	(Context& context, const char* name, const char* description);
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			~PolygonNumSamplesCase	(void) {}
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	renderPattern			(void) const;
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPolygonNumSamplesCase::PolygonNumSamplesCase (Context& context, const char* name, const char* description)
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NumSamplesCase(context, name, description)
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PolygonNumSamplesCase::renderPattern (void) const
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// The test pattern consists of several triangles with edges at different angles.
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numTriangles = 25;
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numTriangles; i++)
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles + 0.001f*(float)m_currentIteration;
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float angle1 = 2.0f*DE_PI * (float)(i + 0.5f)	/ (float)numTriangles + 0.001f*(float)m_currentIteration;
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderTriangle(Vec2(0.0f, 0.0f),
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec4(1.0f));
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LineNumSamplesCase : public NumSamplesCase
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LineNumSamplesCase		(Context& context, const char* name, const char* description);
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			~LineNumSamplesCase		(void) {}
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	renderPattern			(void) const;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLineNumSamplesCase::LineNumSamplesCase (Context& context, const char* name, const char* description)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NumSamplesCase (context, name, description)
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LineNumSamplesCase::renderPattern (void) const
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// The test pattern consists of several lines at different angles.
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// We scale the number of lines based on the viewport size. This is because a gl line's thickness is
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// constant in pixel units, i.e. they get relatively thicker as viewport size decreases. Thus we must
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// decrease the number of lines in order to decrease the extent of overlap among the lines in the
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// center of the pattern.
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numLines = (int)(100.0f * deFloatSqrt((float)m_viewportSize / 256.0f));
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numLines; i++)
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float angle = 2.0f*DE_PI * (float)i / (float)numLines + 0.001f*(float)m_currentIteration;
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderLine(Vec2(0.0f, 0.0f), Vec2(deFloatCos(angle)*0.95f, deFloatSin(angle)*0.95f), Vec4(1.0f));
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Case testing behaviour of common edges when multisampling.
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws a number of test patterns, each with a number of quads, each made
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * of two triangles, rotated at different angles. The inner edge inside the
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * quad (i.e. the common edge of the two triangles) still should not be
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * visible, despite multisampling - i.e. the two triangles forming the quad
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * should never get any common coverage bits in any pixel.
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CommonEdgeCase : public MultisampleCase
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_SMALL_QUADS = 0,				//!< Draw several small quads per iteration.
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_BIGGER_THAN_VIEWPORT_QUAD,		//!< Draw one bigger-than-viewport quad per iteration.
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_FIT_VIEWPORT_QUAD,				//!< Draw one exactly viewport-sized, axis aligned quad per iteration.
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LAST
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					CommonEdgeCase			(Context& context, const char* name, const char* description, CaseType caseType);
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~CommonEdgeCase			(void) {}
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init					(void);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate					(void);
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				getDesiredViewportSize	(void) const { return m_caseType == CASETYPE_SMALL_QUADS ? 128 : 32; }
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DEFAULT_SMALL_QUADS_ITERATIONS					= 16,
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS	= 8*8
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note With CASETYPE_FIT_VIEWPORT_QUAD, we don't do rotations other than multiples of 90 deg -> constant number of iterations.
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseType	m_caseType;
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		m_numIterations;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				m_currentIteration;
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCommonEdgeCase::CommonEdgeCase (Context& context, const char* name, const char* description, CaseType caseType)
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: MultisampleCase		(context, name, description)
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseType			(caseType)
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numIterations		(caseType == CASETYPE_SMALL_QUADS					? getIterationCount(m_testCtx, DEFAULT_SMALL_QUADS_ITERATIONS)
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: caseType == CASETYPE_BIGGER_THAN_VIEWPORT_QUAD	? getIterationCount(m_testCtx, DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS)
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: 8)
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentIteration	(0)
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CommonEdgeCase::init (void)
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MultisampleCase::init();
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_caseType == CASETYPE_SMALL_QUADS)
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Check for a big enough viewport. With too small viewports the test case can't analyze the resulting image well enough.
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int minViewportSize = 32;
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(minViewportSize <= getDesiredViewportSize());
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_viewportSize < minViewportSize)
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::InternalError("Render target width or height too low (is " + de::toString(m_viewportSize) + ", should be at least " + de::toString(minViewportSize) + ")");
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnable(GL_BLEND));
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBlendEquation(GL_FUNC_ADD));
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBlendFunc(GL_ONE, GL_ONE));
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples" << TestLog::EndMessage;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCommonEdgeCase::IterateResult CommonEdgeCase::iterate (void)
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log				= m_testCtx.getLog();
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	errorImg		(m_viewportSize, m_viewportSize);
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw test pattern. Test patterns consist of quads formed with two triangles.
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// After drawing the pattern, we check that the interior pixels of each quad are
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// all the same color - this is meant to verify that there are no artifacts on the inner edge.
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<QuadCorners> unicoloredRegions;
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_caseType == CASETYPE_SMALL_QUADS)
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw several quads, rotated at different angles.
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		quadDiagLen = 2.0f / 3.0f * 0.9f; // \note Fit 3 quads in both x and y directions.
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float			angleCos;
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float			angleSin;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note First and second iteration get exact 0 (and 90, 180, 270) and 45 (and 135, 225, 315) angle quads, as they are kind of a special case.
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_currentIteration == 0)
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleCos = 1.0f;
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleSin = 0.0f;
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_currentIteration == 1)
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleCos = SQRT_HALF;
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleSin = SQRT_HALF;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float angle = 0.5f * DE_PI * (float)(m_currentIteration-1) / (float)(m_numIterations-1);
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleCos = deFloatCos(angle);
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleSin = deFloatSin(angle);
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec2 corners[4] =
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0.5f * quadDiagLen * Vec2( angleCos,  angleSin),
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0.5f * quadDiagLen * Vec2(-angleSin,  angleCos),
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0.5f * quadDiagLen * Vec2(-angleCos, -angleSin),
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0.5f * quadDiagLen * Vec2( angleSin, -angleCos)
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		unicoloredRegions.reserve(8);
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw 8 quads.
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// First four are rotated at angles angle+0, angle+90, angle+180 and angle+270.
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Last four are rotated the same angles as the first four, but the ordering of the last triangle's vertices is reversed.
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int quadNdx = 0; quadNdx < 8; quadNdx++)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec2 center = (2.0f-quadDiagLen) * Vec2((float)(quadNdx%3), (float)(quadNdx/3)) / 2.0f - 0.5f*(2.0f-quadDiagLen);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderTriangle(corners[(0+quadNdx) % 4] + center,
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(1+quadNdx) % 4] + center,
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(2+quadNdx) % 4] + center,
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (quadNdx >= 4)
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				renderTriangle(corners[(3+quadNdx) % 4] + center,
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							   corners[(2+quadNdx) % 4] + center,
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							   corners[(0+quadNdx) % 4] + center,
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				renderTriangle(corners[(0+quadNdx) % 4] + center,
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							   corners[(2+quadNdx) % 4] + center,
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							   corners[(3+quadNdx) % 4] + center,
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// The size of the "interior" of a quad is assumed to be approximately unicolorRegionScale*<actual size of quad>.
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// By "interior" we here mean the region of non-boundary pixels of the rendered quad for which we can safely assume
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// that it has all coverage bits set to 1, for every pixel.
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float unicolorRegionScale = 1.0f - 6.0f*2.0f / (float)m_viewportSize / quadDiagLen;
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			unicoloredRegions.push_back(QuadCorners((center + corners[0]*unicolorRegionScale),
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													(center + corners[1]*unicolorRegionScale),
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													(center + corners[2]*unicolorRegionScale),
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													(center + corners[3]*unicolorRegionScale)));
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_caseType == CASETYPE_BIGGER_THAN_VIEWPORT_QUAD)
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw a bigger-than-viewport quad, rotated at an angle depending on m_currentIteration.
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				quadBaseAngleNdx		= m_currentIteration / 8;
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				quadSubAngleNdx			= m_currentIteration % 8;
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float			angleCos;
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float			angleSin;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (quadBaseAngleNdx == 0)
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleCos = 1.0f;
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleSin = 0.0f;
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (quadBaseAngleNdx == 1)
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleCos = SQRT_HALF;
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleSin = SQRT_HALF;
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float angle = 0.5f * DE_PI * (float)(m_currentIteration-1) / (float)(m_numIterations-1);
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleCos = deFloatCos(angle);
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			angleSin = deFloatSin(angle);
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float quadDiagLen = 2.5f / de::max(angleCos, angleSin);
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec2 corners[4] =
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0.5f * quadDiagLen * Vec2( angleCos,  angleSin),
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0.5f * quadDiagLen * Vec2(-angleSin,  angleCos),
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0.5f * quadDiagLen * Vec2(-angleCos, -angleSin),
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0.5f * quadDiagLen * Vec2( angleSin, -angleCos)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderTriangle(corners[(0+quadSubAngleNdx) % 4],
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   corners[(1+quadSubAngleNdx) % 4],
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   corners[(2+quadSubAngleNdx) % 4],
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (quadSubAngleNdx >= 4)
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderTriangle(corners[(3+quadSubAngleNdx) % 4],
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(2+quadSubAngleNdx) % 4],
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(0+quadSubAngleNdx) % 4],
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderTriangle(corners[(0+quadSubAngleNdx) % 4],
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(2+quadSubAngleNdx) % 4],
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(3+quadSubAngleNdx) % 4],
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float unicolorRegionScale = 1.0f - 6.0f*2.0f / (float)m_viewportSize / quadDiagLen;
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		unicoloredRegions.push_back(QuadCorners((corners[0]*unicolorRegionScale),
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												(corners[1]*unicolorRegionScale),
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												(corners[2]*unicolorRegionScale),
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												(corners[3]*unicolorRegionScale)));
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_caseType == CASETYPE_FIT_VIEWPORT_QUAD)
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw an exactly viewport-sized quad, rotated by multiples of 90 degrees angle depending on m_currentIteration.
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int quadSubAngleNdx = m_currentIteration % 8;
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec2 corners[4] =
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec2( 1.0f,  1.0f),
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec2(-1.0f,  1.0f),
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec2(-1.0f, -1.0f),
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec2( 1.0f, -1.0f)
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderTriangle(corners[(0+quadSubAngleNdx) % 4],
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   corners[(1+quadSubAngleNdx) % 4],
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   corners[(2+quadSubAngleNdx) % 4],
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (quadSubAngleNdx >= 4)
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderTriangle(corners[(3+quadSubAngleNdx) % 4],
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(2+quadSubAngleNdx) % 4],
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(0+quadSubAngleNdx) % 4],
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderTriangle(corners[(0+quadSubAngleNdx) % 4],
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(2+quadSubAngleNdx) % 4],
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   corners[(3+quadSubAngleNdx) % 4],
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		unicoloredRegions.push_back(QuadCorners(corners[0], corners[1], corners[2], corners[3]));
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read pixels and check unicolored regions.
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImg);
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(errorImg.getAccess(), Vec4(0.0f, 1.0f, 0.0f, 1.0f));
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool errorsDetected = false;
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)unicoloredRegions.size(); i++)
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const QuadCorners&	region					= unicoloredRegions[i];
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2				p0Win					= ((region.p0+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2				p1Win					= ((region.p1+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2				p2Win					= ((region.p2+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2				p3Win					= ((region.p3+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool				errorsInCurrentRegion	= !isPixelRegionUnicolored(renderedImg, p0Win, p1Win, p2Win, p3Win);
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (errorsInCurrentRegion)
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			drawUnicolorTestErrors(renderedImg, errorImg.getAccess(), p0Win, p1Win, p2Win, p3Win);
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errorsDetected = errorsDetected || errorsInCurrentRegion;
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentIteration++;
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (errorsDetected)
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Failure: Not all quad interiors seem unicolored - common-edge artifacts?" << TestLog::EndMessage;
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Erroneous pixels are drawn red in the following image" << TestLog::EndMessage;
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("RenderedImageWithErrors",	"Rendered image with errors marked",	renderedImg,	QP_IMAGE_COMPRESSION_MODE_PNG);
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("ErrorsOnly",					"Image with error pixels only",			errorImg,		QP_IMAGE_COMPRESSION_MODE_PNG);
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_currentIteration < m_numIterations)
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Quads seem OK - moving on to next pattern" << TestLog::EndMessage;
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTINUE;
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: All quad interiors seem unicolored (no common-edge artifacts)" << TestLog::EndMessage;
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test that depth values are per-sample.
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws intersecting, differently-colored polygons and checks that there
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * are at least GL_SAMPLES+1 distinct colors present, due to some of the
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * samples at the intersection line belonging to one and some to another
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * polygon.
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SampleDepthCase : public NumSamplesCase
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						SampleDepthCase			(Context& context, const char* name, const char* description);
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~SampleDepthCase		(void) {}
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init					(void);
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderPattern			(void) const;
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8953c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySampleDepthCase::SampleDepthCase (Context& context, const char* name, const char* description)
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NumSamplesCase (context, name, description)
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SampleDepthCase::init (void)
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog& log = m_testCtx.getLog();
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MultisampleCase::init();
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnable(GL_DEPTH_TEST));
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glDepthFunc(GL_LESS));
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Depth test enabled, depth func is GL_LESS" << TestLog::EndMessage;
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing several bigger-than-viewport black or white polygons intersecting each other" << TestLog::EndMessage;
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SampleDepthCase::renderPattern (void) const
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearDepthf(1.0f));
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numPolygons = 50;
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numPolygons; i++)
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4	color	= i % 2 == 0 ? Vec4(1.0f, 1.0f, 1.0f, 1.0f) : Vec4(0.0f, 0.0f, 0.0f, 1.0f);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	angle	= 2.0f * DE_PI * (float)i / (float)numPolygons + 0.001f*(float)m_currentIteration;
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec3	pt0		(3.0f*deFloatCos(angle + 2.0f*DE_PI*0.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*0.0f/3.0f), 1.0f);
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec3	pt1		(3.0f*deFloatCos(angle + 2.0f*DE_PI*1.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*1.0f/3.0f), 0.0f);
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec3	pt2		(3.0f*deFloatCos(angle + 2.0f*DE_PI*2.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*2.0f/3.0f), 0.0f);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderTriangle(pt0, pt1, pt2, color);
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test that stencil buffer values are per-sample.
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws a unicolored pattern and marks drawn samples in stencil buffer;
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * then clears and draws a viewport-size quad with that color and with
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * proper stencil test such that the resulting image should be exactly the
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * same as after the pattern was first drawn.
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SampleStencilCase : public MultisampleCase
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						SampleStencilCase		(Context& context, const char* name, const char* description);
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~SampleStencilCase		(void) {}
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate					(void);
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getDesiredViewportSize	(void) const { return 256; }
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9553c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySampleStencilCase::SampleStencilCase (Context& context, const char* name, const char* description)
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: MultisampleCase (context, name, description)
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9603c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySampleStencilCase::IterateResult SampleStencilCase::iterate (void)
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log					= m_testCtx.getLog();
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	renderedImgFirst	(m_viewportSize, m_viewportSize);
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	renderedImgSecond	(m_viewportSize, m_viewportSize);
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearStencil(0));
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnable(GL_STENCIL_TEST));
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glStencilFunc(GL_ALWAYS, 1, 1));
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE));
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing a pattern with glStencilFunc(GL_ALWAYS, 1, 1) and glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)" << TestLog::EndMessage;
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numTriangles = 25;
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numTriangles; i++)
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles;
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float angle1 = 2.0f*DE_PI * (float)(i + 0.5f)	/ (float)numTriangles;
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderTriangle(Vec2(0.0f, 0.0f),
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   Vec4(1.0f));
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImgFirst);
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImgFirst", "First image rendered", renderedImgFirst, QP_IMAGE_COMPRESSION_MODE_PNG);
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color buffer to black" << TestLog::EndMessage;
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glStencilFunc(GL_EQUAL, 1, 1));
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP));
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Checking that color buffer was actually cleared to black" << TestLog::EndMessage;
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface clearedImg(m_viewportSize, m_viewportSize);
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		readImage(clearedImg);
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < clearedImg.getHeight(); y++)
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < clearedImg.getWidth(); x++)
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::RGBA& clr = clearedImg.getPixel(x, y);
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (clr != tcu::RGBA::black)
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "Failure: first non-black pixel, color " << clr << ", detected at coordinates (" << x << ", " << y << ")" << TestLog::EndMessage;
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Image("ClearedImg", "Image after clearing, erroneously non-black", clearedImg);
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return STOP;
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing a viewport-sized quad with glStencilFunc(GL_EQUAL, 1, 1) and glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) - should result in same image as the first" << TestLog::EndMessage;
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderQuad(Vec2(-1.0f, -1.0f),
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   Vec2( 1.0f, -1.0f),
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   Vec2(-1.0f,  1.0f),
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   Vec2( 1.0f,  1.0f),
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   Vec4(1.0f));
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImgSecond);
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImgSecond", "Second image rendered", renderedImgSecond, QP_IMAGE_COMPRESSION_MODE_PNG);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool passed = tcu::pixelThresholdCompare(log,
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 "ImageCompare",
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 "Image comparison",
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 renderedImgFirst,
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 renderedImgSecond,
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 tcu::RGBA(0),
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 tcu::COMPARE_LOG_ON_ERROR);
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (passed)
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 passed ? "Passed"				: "Failed");
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask generation proportionality property.
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the number of coverage bits in a coverage mask created by
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * GL_SAMPLE_ALPHA_TO_COVERAGE or GL_SAMPLE_COVERAGE is, on average,
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * proportional to the alpha or coverage value, respectively. Draws
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * multiple frames, each time increasing the alpha or coverage value used,
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and checks that the average color is changing appropriately.
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaskProportionalityCase : public MultisampleCase
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_ALPHA_TO_COVERAGE = 0,
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_SAMPLE_COVERAGE,
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_SAMPLE_COVERAGE_INVERTED,
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LAST
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					MaskProportionalityCase				(Context& context, const char* name, const char* description, CaseType type);
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~MaskProportionalityCase			(void) {}
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init								(void);
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate								(void);
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				getDesiredViewportSize				(void) const { return 32; }
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseType	m_type;
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				m_numIterations;
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				m_currentIteration;
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32			m_previousIterationColorSum;
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskProportionalityCase::MaskProportionalityCase (Context& context, const char* name, const char* description, CaseType type)
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: MultisampleCase				(context, name, description)
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type						(type)
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentIteration			(0)
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_previousIterationColorSum	(-1)
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskProportionalityCase::init (void)
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog& log = m_testCtx.getLog();
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MultisampleCase::init();
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE));
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_type == CASETYPE_SAMPLE_COVERAGE || m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numIterations = de::max(2, getIterationCount(m_testCtx, m_numSamples * 5));
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport(); // \note Using the same viewport for every iteration since coverage mask may depend on window-relative pixel coordinate.
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskProportionalityCase::IterateResult MaskProportionalityCase::iterate (void)
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log				= m_testCtx.getLog();
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32			numPixels		= (deInt32)renderedImg.getWidth()*(deInt32)renderedImg.getHeight();
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE));
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Using color mask TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw quad.
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2		pt0						(-1.0f, -1.0f);
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2		pt1						( 1.0f, -1.0f);
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2		pt2						(-1.0f,  1.0f);
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2		pt3						( 1.0f,  1.0f);
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4			quadColor				(1.0f, 0.0f, 0.0f, 1.0f);
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float			alphaOrCoverageValue	= (float)m_currentIteration / (float)(m_numIterations-1);
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Drawing a red quad using alpha value " + de::floatToString(alphaOrCoverageValue, 2) << TestLog::EndMessage;
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			quadColor.w() = alphaOrCoverageValue;
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_type == CASETYPE_SAMPLE_COVERAGE || m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED);
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool	isInverted		= m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED;
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	coverageValue	= isInverted ? 1.0f - alphaOrCoverageValue : alphaOrCoverageValue;
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Drawing a red quad using sample coverage value " + de::floatToString(coverageValue, 2) << (isInverted ? " (inverted)" : "") << TestLog::EndMessage;
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glSampleCoverage(coverageValue, isInverted ? GL_TRUE : GL_FALSE));
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderQuad(pt0, pt1, pt2, pt3, quadColor);
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read ang log image.
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImg);
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute average red component in rendered image.
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32 sumRed = 0;
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < renderedImg.getWidth(); x++)
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sumRed += renderedImg.getPixel(x, y).getRed();
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Average red color component: " << de::floatToString((float)sumRed / 255.0f / (float)numPixels, 2) << TestLog::EndMessage;
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check if average color has decreased from previous frame's color.
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sumRed < m_previousIterationColorSum)
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Failure: Current average red color component is lower than previous" << TestLog::EndMessage;
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check if coverage mask is not all-zeros if alpha or coverage value is 0 (or 1, if inverted).
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration == 0 && sumRed != 0)
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Failure: Image should be completely black" << TestLog::EndMessage;
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration == m_numIterations-1 && sumRed != 0xff*numPixels)
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Failure: Image should be completely red" << TestLog::EndMessage;
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_previousIterationColorSum = sumRed;
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentIteration++;
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration >= m_numIterations)
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "Success: Number of coverage mask bits set appears to be, on average, proportional to "
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< (m_type == CASETYPE_ALPHA_TO_COVERAGE ? "alpha" : m_type == CASETYPE_SAMPLE_COVERAGE ? "sample coverage value" : "inverted sample coverage value")
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::EndMessage;
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTINUE;
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask generation constancy property.
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the coverage mask created by GL_SAMPLE_ALPHA_TO_COVERAGE or
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * GL_SAMPLE_COVERAGE is constant at given pixel coordinates, with a given
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * alpha component or coverage value, respectively. Draws two quads, with
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the second one fully overlapping the first one such that at any given
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * pixel, both quads have the same alpha or coverage value. This way, if
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the constancy property is fulfilled, only the second quad should be
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * visible.
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaskConstancyCase : public MultisampleCase
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_ALPHA_TO_COVERAGE = 0,		//!< Use only alpha-to-coverage.
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_SAMPLE_COVERAGE,			//!< Use only sample coverage.
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_SAMPLE_COVERAGE_INVERTED,	//!< Use only inverted sample coverage.
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_BOTH,						//!< Use both alpha-to-coverage and sample coverage.
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_BOTH_INVERTED,				//!< Use both alpha-to-coverage and inverted sample coverage.
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LAST
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					MaskConstancyCase			(Context& context, const char* name, const char* description, CaseType type);
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~MaskConstancyCase			(void) {}
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate						(void);
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				getDesiredViewportSize		(void) const { return 256; }
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_isAlphaToCoverageCase;
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_isSampleCoverageCase;
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_isInvertedSampleCoverageCase;
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskConstancyCase::MaskConstancyCase (Context& context, const char* name, const char* description, CaseType type)
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: MultisampleCase					(context, name, description)
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isAlphaToCoverageCase			(type == CASETYPE_ALPHA_TO_COVERAGE			|| type == CASETYPE_BOTH						|| type == CASETYPE_BOTH_INVERTED)
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isSampleCoverageCase			(type == CASETYPE_SAMPLE_COVERAGE			|| type == CASETYPE_SAMPLE_COVERAGE_INVERTED	|| type == CASETYPE_BOTH			|| type == CASETYPE_BOTH_INVERTED)
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isInvertedSampleCoverageCase	(type == CASETYPE_SAMPLE_COVERAGE_INVERTED	|| type == CASETYPE_BOTH_INVERTED)
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskConstancyCase::IterateResult MaskConstancyCase::iterate (void)
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log				= m_testCtx.getLog();
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isAlphaToCoverageCase)
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE));
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE));
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Color mask is TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isSampleCoverageCase)
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Drawing several green quads, each fully overlapped by a red quad with the same "
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isAlphaToCoverageCase ? "alpha" : "")
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isInvertedSampleCoverageCase ? "inverted " : "")
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isSampleCoverageCase ? "sample coverage" : "")
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< " values"
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numQuadRowsCols = m_numSamples*4;
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < numQuadRowsCols; row++)
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < numQuadRowsCols; col++)
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		x0			= (float)(col+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		x1			= (float)(col+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		y0			= (float)(row+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		y1			= (float)(row+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4	baseGreen	(0.0f, 1.0f, 0.0f, 0.0f);
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4	baseRed		(1.0f, 0.0f, 0.0f, 0.0f);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4		alpha0		(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)col / (float)(numQuadRowsCols-1) : 1.0f);
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4		alpha1		(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)row / (float)(numQuadRowsCols-1) : 1.0f);
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_isSampleCoverageCase)
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float value = (float)(row*numQuadRowsCols + col) / (float)(numQuadRowsCols*numQuadRowsCols-1);
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glSampleCoverage(m_isInvertedSampleCoverageCase ? 1.0f - value : value, m_isInvertedSampleCoverageCase ? GL_TRUE : GL_FALSE));
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseGreen + alpha0,	baseGreen + alpha1,	baseGreen + alpha0,	baseGreen + alpha1);
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseRed + alpha0,	baseRed + alpha1,	baseRed + alpha0,	baseRed + alpha1);
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImg);
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < renderedImg.getWidth(); x++)
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (renderedImg.getPixel(x, y).getGreen() > 0)
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Failure: Non-zero green color component detected - should have been completely overwritten by red quad" << TestLog::EndMessage;
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Success: Coverage mask appears to be constant at a given pixel coordinate with a given "
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isAlphaToCoverageCase ? "alpha" : "")
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isSampleCoverageCase ? "coverage value" : "")
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask inversion validity.
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the coverage masks obtained by glSampleCoverage(..., GL_TRUE)
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and glSampleCoverage(..., GL_FALSE) are indeed each others' inverses.
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is done by drawing a pattern, with varying coverage values,
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * overlapped by a pattern that has inverted masks and is otherwise
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * identical. The resulting image is compared to one obtained by drawing
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the same pattern but with all-ones coverage masks.
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CoverageMaskInvertCase : public MultisampleCase
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					CoverageMaskInvertCase		(Context& context, const char* name, const char* description);
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~CoverageMaskInvertCase		(void) {}
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate						(void);
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				getDesiredViewportSize		(void) const { return 256; }
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			drawPattern					(bool invertSampleCoverage) const;
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCoverageMaskInvertCase::CoverageMaskInvertCase (Context& context, const char* name, const char* description)
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: MultisampleCase (context, name, description)
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CoverageMaskInvertCase::drawPattern (bool invertSampleCoverage) const
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numTriangles = 25;
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numTriangles; i++)
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glSampleCoverage((float)i / (float)(numTriangles-1), invertSampleCoverage ? GL_TRUE : GL_FALSE));
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles;
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float angle1 = 2.0f*DE_PI * (float)(i + 0.5f)	/ (float)numTriangles;
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderTriangle(Vec2(0.0f, 0.0f),
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec4(0.4f + (float)i/(float)numTriangles*0.6f,
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							0.5f + (float)i/(float)numTriangles*0.3f,
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							0.6f - (float)i/(float)numTriangles*0.5f,
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							0.7f - (float)i/(float)numTriangles*0.7f));
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCoverageMaskInvertCase::IterateResult CoverageMaskInvertCase::iterate (void)
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log								= m_testCtx.getLog();
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	renderedImgNoSampleCoverage		(m_viewportSize, m_viewportSize);
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	renderedImgSampleCoverage		(m_viewportSize, m_viewportSize);
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnable(GL_BLEND));
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBlendEquation(GL_FUNC_ADD));
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBlendFunc(GL_ONE, GL_ONE));
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples" << TestLog::EndMessage;
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE disabled" << TestLog::EndMessage;
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawPattern(false);
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImgNoSampleCoverage);
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImageNoSampleCoverage", "Rendered image with GL_SAMPLE_COVERAGE disabled", renderedImgNoSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE enabled, using non-inverted masks" << TestLog::EndMessage;
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawPattern(false);
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE enabled, using same sample coverage values but inverted masks" << TestLog::EndMessage;
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawPattern(true);
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImgSampleCoverage);
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImageSampleCoverage", "Rendered image with GL_SAMPLE_COVERAGE enabled", renderedImgSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool passed = tcu::pixelThresholdCompare(log,
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 "CoverageVsNoCoverage",
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 "Comparison of same pattern with GL_SAMPLE_COVERAGE disabled and enabled",
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 renderedImgNoSampleCoverage,
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 renderedImgSampleCoverage,
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 tcu::RGBA(0),
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 tcu::COMPARE_LOG_ON_ERROR);
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (passed)
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 passed ? "Passed"				: "Failed");
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleTests::MultisampleTests (Context& context)
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "multisample", "Multisampling tests")
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleTests::~MultisampleTests (void)
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleTests::init (void)
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new PolygonNumSamplesCase		(m_context, "num_samples_polygon",			"Test sanity of the value of GL_SAMPLES, with polygons"));
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new LineNumSamplesCase			(m_context, "num_samples_line",				"Test sanity of the value of GL_SAMPLES, with lines"));
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new CommonEdgeCase				(m_context, "common_edge_small_quads",		"Test polygons' common edges with small quads",						CommonEdgeCase::CASETYPE_SMALL_QUADS));
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new CommonEdgeCase				(m_context, "common_edge_big_quad",			"Test polygons' common edges with bigger-than-viewport quads",		CommonEdgeCase::CASETYPE_BIGGER_THAN_VIEWPORT_QUAD));
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new CommonEdgeCase				(m_context, "common_edge_viewport_quad",	"Test polygons' common edges with exactly viewport-sized quads",	CommonEdgeCase::CASETYPE_FIT_VIEWPORT_QUAD));
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new SampleDepthCase			(m_context, "depth",						"Test that depth values are per-sample"));
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new SampleStencilCase			(m_context, "stencil",						"Test that stencil values are per-sample"));
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new CoverageMaskInvertCase		(m_context, "sample_coverage_invert",		"Test that non-inverted and inverted sample coverage masks are each other's negations"));
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new MaskProportionalityCase(m_context, "proportionality_alpha_to_coverage",			"Test the proportionality property of GL_SAMPLE_ALPHA_TO_COVERAGE",			MaskProportionalityCase::CASETYPE_ALPHA_TO_COVERAGE));
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new MaskProportionalityCase(m_context, "proportionality_sample_coverage",				"Test the proportionality property of GL_SAMPLE_COVERAGE",					MaskProportionalityCase::CASETYPE_SAMPLE_COVERAGE));
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new MaskProportionalityCase(m_context, "proportionality_sample_coverage_inverted",		"Test the proportionality property of inverted-mask GL_SAMPLE_COVERAGE",	MaskProportionalityCase::CASETYPE_SAMPLE_COVERAGE_INVERTED));
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new MaskConstancyCase(m_context, "constancy_alpha_to_coverage",			"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE",											MaskConstancyCase::CASETYPE_ALPHA_TO_COVERAGE));
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new MaskConstancyCase(m_context, "constancy_sample_coverage",				"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_COVERAGE",													MaskConstancyCase::CASETYPE_SAMPLE_COVERAGE));
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new MaskConstancyCase(m_context, "constancy_sample_coverage_inverted",		"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using inverted-mask GL_SAMPLE_COVERAGE",									MaskConstancyCase::CASETYPE_SAMPLE_COVERAGE_INVERTED));
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new MaskConstancyCase(m_context, "constancy_both",							"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and GL_SAMPLE_COVERAGE",					MaskConstancyCase::CASETYPE_BOTH));
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new MaskConstancyCase(m_context, "constancy_both_inverted",				"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and inverted-mask GL_SAMPLE_COVERAGE",	MaskConstancyCase::CASETYPE_BOTH_INVERTED));
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1493