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 Dithering tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2fDitheringTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDefs.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsFragmentOpUtil.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRGBA.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuPixelFormat.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glw.h"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec4;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::FragmentOpUtil::QuadRenderer;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::FragmentOpUtil::Quad;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::PixelFormat;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Surface;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::Random;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_channelNames[4] = { "red", "green", "blue", "alpha" };
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline IVec4 pixelFormatToIVec4 (const PixelFormat& format)
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return IVec4(format.redBits, format.greenBits, format.blueBits, format.alphaBits);
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T>
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string choiceListStr (const vector<T>& choices)
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string result;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)choices.size(); i++)
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i == (int)choices.size()-1)
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += " or ";
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (i > 0)
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += ", ";
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result += de::toString(choices[i]);
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DitheringCase : public tcu::TestCase
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum PatternType
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PATTERNTYPE_GRADIENT = 0,
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PATTERNTYPE_UNICOLORED_QUAD,
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PATTERNTYPE_LAST
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											DitheringCase				(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, bool isEnabled, PatternType patternType, const tcu::Vec4& color);
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											~DitheringCase				(void);
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult							iterate						(void);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void									init						(void);
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void									deinit						(void);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*						getPatternTypeName			(PatternType type);
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool									checkColor					(const tcu::Vec4& inputClr, const tcu::RGBA& renderedClr, bool logErrors) const;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool									drawAndCheckGradient		(bool isVerticallyIncreasing, const tcu::Vec4& highColor) const;
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool									drawAndCheckUnicoloredQuad	(const tcu::Vec4& color) const;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&				m_renderCtx;
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool								m_ditheringEnabled;
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const PatternType						m_patternType;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4							m_color;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::PixelFormat					m_renderFormat;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const QuadRenderer*						m_renderer;
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int										m_iteration;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* DitheringCase::getPatternTypeName (const PatternType type)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PATTERNTYPE_GRADIENT:			return "gradient";
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PATTERNTYPE_UNICOLORED_QUAD:	return "unicolored_quad";
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDitheringCase::DitheringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* const name, const char* const description, const bool ditheringEnabled, const PatternType patternType, const Vec4& color)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(testCtx, name, description)
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx			(renderCtx)
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_ditheringEnabled	(ditheringEnabled)
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_patternType			(patternType)
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_color				(color)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderFormat		(renderCtx.getRenderTarget().getPixelFormat())
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer			(DE_NULL)
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_iteration			(0)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDitheringCase::~DitheringCase (void)
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DitheringCase::deinit();
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DitheringCase::init (void)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_renderer);
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer = new QuadRenderer(m_renderCtx, glu::GLSL_VERSION_100_ES);
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_iteration = 0;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DitheringCase::deinit (void)
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_renderer;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer = DE_NULL;
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool DitheringCase::checkColor (const Vec4& inputClr, const tcu::RGBA& renderedClr, const bool logErrors) const
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const IVec4		channelBits		= pixelFormatToIVec4(m_renderFormat);
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			allChannelsOk	= true;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int chanNdx = 0; chanNdx < 4; chanNdx++)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (channelBits[chanNdx] == 0)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		channelMax			= (1 << channelBits[chanNdx]) - 1;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		scaledInput			= inputClr[chanNdx] * (float)channelMax;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool		useRoundingMargin	= deFloatAbs(scaledInput - deFloatRound(scaledInput)) < 0.0001f;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<int>		channelChoices;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		channelChoices.push_back(de::min(channelMax,	(int)deFloatCeil(scaledInput)));
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		channelChoices.push_back(de::max(0,				(int)deFloatCeil(scaledInput) - 1));
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// If the input color results in a scaled value that is very close to an integer, account for a little bit of possible inaccuracy.
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (useRoundingMargin)
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (scaledInput > deFloatRound(scaledInput))
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				channelChoices.push_back((int)deFloatCeil(scaledInput) - 2);
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				channelChoices.push_back((int)deFloatCeil(scaledInput) + 1);
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::sort(channelChoices.begin(), channelChoices.end());
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		renderedClrInFormat	= (int)deFloatRound((float)(renderedClr.toIVec()[chanNdx] * channelMax) / 255.0f);
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool			goodChannel			= false;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)channelChoices.size(); i++)
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (renderedClrInFormat == channelChoices[i])
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					goodChannel = true;
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!goodChannel)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (logErrors)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.getLog() << TestLog::Message
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << "Failure: " << channelBits[chanNdx] << "-bit " << s_channelNames[chanNdx] << " channel is " << renderedClrInFormat
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << ", should be " << choiceListStr(channelChoices)
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << " (corresponding fragment color channel is " << inputClr[chanNdx] << ")"
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << TestLog::EndMessage
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << TestLog::Message
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << "Note: " << inputClr[chanNdx] << " * (" << channelMax + 1 << "-1) = " << scaledInput
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << TestLog::EndMessage;
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (useRoundingMargin)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_testCtx.getLog() << TestLog::Message
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   << "Note: one extra color candidate was allowed because fragmentColorChannel * (2^bits-1) is close to an integer"
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   << TestLog::EndMessage;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allChannelsOk = false;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return allChannelsOk;
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool DitheringCase::drawAndCheckGradient (const bool isVerticallyIncreasing, const Vec4& highColor) const
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log					= m_testCtx.getLog();
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random						rnd					(deStringHash(getName()));
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					maxViewportWid		= 256;
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					maxViewportHei		= 256;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportWid			= de::min(m_renderCtx.getRenderTarget().getWidth(), maxViewportWid);
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportHei			= de::min(m_renderCtx.getRenderTarget().getHeight(), maxViewportHei);
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportX			= rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportWid);
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportY			= rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportHei);
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4					quadClr0			(0.0f, 0.0f, 0.0f, 0.0f);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4&					quadClr1			= highColor;
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Quad						quad;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface						renderedImg			(viewportWid, viewportHei);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportWid, viewportHei));
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Dithering is " << (m_ditheringEnabled ? "enabled" : "disabled") << TestLog::EndMessage;
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_ditheringEnabled)
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glEnable(GL_DITHER));
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glDisable(GL_DITHER));
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing a " << (isVerticallyIncreasing ? "vertically" : "horizontally") << " increasing gradient" << TestLog::EndMessage;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	quad.color[0] = quadClr0;
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	quad.color[1] = isVerticallyIncreasing ? quadClr1 : quadClr0;
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	quad.color[2] = isVerticallyIncreasing ? quadClr0 : quadClr1;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	quad.color[3] = quadClr1;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer->render(quad);
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewportX, viewportY, renderedImg.getAccess());
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("glReadPixels()");
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image(isVerticallyIncreasing ? "VerGradient"		: "HorGradient",
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						  isVerticallyIncreasing ? "Vertical gradient"	: "Horizontal gradient",
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						  renderedImg);
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Validate, at each pixel, that each color channel is one of its two allowed values.
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Surface		errorMask		(viewportWid, viewportHei);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool		colorChoicesOk	= true;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < renderedImg.getHeight(); y++)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < renderedImg.getWidth(); x++)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float		inputF		= ((float)(isVerticallyIncreasing ? y : x) + 0.5f) / (float)(isVerticallyIncreasing ? renderedImg.getHeight() : renderedImg.getWidth());
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Vec4		inputClr	= (1.0f-inputF)*quadClr0 + inputF*quadClr1;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!checkColor(inputClr, renderedImg.getPixel(x, y), colorChoicesOk))
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					errorMask.setPixel(x, y, tcu::RGBA::red);
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (colorChoicesOk)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						log << TestLog::Message << "First failure at pixel (" << x << ", " << y << ") (not printing further errors)" << TestLog::EndMessage;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						colorChoicesOk = false;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					errorMask.setPixel(x, y, tcu::RGBA::green);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!colorChoicesOk)
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Image("ColorChoiceErrorMask", "Error mask for color choices", errorMask);
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// When dithering is disabled, the color selection must be coordinate-independent - i.e. the colors must be constant in the gradient's constant direction.
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_ditheringEnabled)
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int increasingDirectionSize	= isVerticallyIncreasing ? renderedImg.getHeight() : renderedImg.getWidth();
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int constantDirectionSize		= isVerticallyIncreasing ? renderedImg.getWidth() : renderedImg.getHeight();
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int incrPos = 0; incrPos < increasingDirectionSize; incrPos++)
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::RGBA prevConstantDirectionPix;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int constPos = 0; constPos < constantDirectionSize; constPos++)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			x		= isVerticallyIncreasing ? constPos : incrPos;
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			y		= isVerticallyIncreasing ? incrPos : constPos;
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::RGBA		clr		= renderedImg.getPixel(x, y);
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (constPos > 0 && clr != prevConstantDirectionPix)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "Failure: colors should be constant per " << (isVerticallyIncreasing ? "row" : "column")
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " (since dithering is disabled), but the color at position (" << x << ", " << y << ") is " << clr
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " and does not equal the color at (" << (isVerticallyIncreasing ? x-1 : x) << ", " << (isVerticallyIncreasing ? y : y-1) << "), which is " << prevConstantDirectionPix
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndMessage;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				prevConstantDirectionPix = clr;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool DitheringCase::drawAndCheckUnicoloredQuad (const Vec4& quadColor) const
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log					= m_testCtx.getLog();
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random						rnd					(deStringHash(getName()));
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					maxViewportWid		= 32;
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					maxViewportHei		= 32;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportWid			= de::min(m_renderCtx.getRenderTarget().getWidth(), maxViewportWid);
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportHei			= de::min(m_renderCtx.getRenderTarget().getHeight(), maxViewportHei);
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportX			= rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportWid);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportY			= rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportHei);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Quad						quad;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface						renderedImg			(viewportWid, viewportHei);
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportWid, viewportHei));
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Dithering is " << (m_ditheringEnabled ? "enabled" : "disabled") << TestLog::EndMessage;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_ditheringEnabled)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glEnable(GL_DITHER));
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glDisable(GL_DITHER));
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing an unicolored quad with color " << quadColor << TestLog::EndMessage;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	quad.color[0] = quadColor;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	quad.color[1] = quadColor;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	quad.color[2] = quadColor;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	quad.color[3] = quadColor;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer->render(quad);
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewportX, viewportY, renderedImg.getAccess());
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("glReadPixels()");
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image(("Quad" + de::toString(m_iteration)).c_str(), ("Quad " + de::toString(m_iteration)).c_str(), renderedImg);
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Validate, at each pixel, that each color channel is one of its two allowed values.
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Surface		errorMask		(viewportWid, viewportHei);
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool		colorChoicesOk	= true;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < renderedImg.getHeight(); y++)
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < renderedImg.getWidth(); x++)
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!checkColor(quadColor, renderedImg.getPixel(x, y), colorChoicesOk))
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					errorMask.setPixel(x, y, tcu::RGBA::red);
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (colorChoicesOk)
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						log << TestLog::Message << "First failure at pixel (" << x << ", " << y << ") (not printing further errors)" << TestLog::EndMessage;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						colorChoicesOk = false;
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					errorMask.setPixel(x, y, tcu::RGBA::green);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!colorChoicesOk)
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Image("ColorChoiceErrorMask", "Error mask for color choices", errorMask);
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// When dithering is disabled, the color selection must be coordinate-independent - i.e. the entire rendered image must be unicolored.
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_ditheringEnabled)
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA renderedClr00 = renderedImg.getPixel(0, 0);
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < renderedImg.getHeight(); y++)
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < renderedImg.getWidth(); x++)
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::RGBA curClr = renderedImg.getPixel(x, y);
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (curClr != renderedClr00)
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "Failure: color at (" << x << ", " << y << ") is " << curClr
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " and does not equal the color at (0, 0), which is " << renderedClr00
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndMessage;
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDitheringCase::IterateResult DitheringCase::iterate (void)
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_patternType == PATTERNTYPE_GRADIENT)
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw horizontal and vertical gradients.
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_iteration < 2);
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success = drawAndCheckGradient(m_iteration == 1, m_color);
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_iteration == 1)
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_patternType == PATTERNTYPE_UNICOLORED_QUAD)
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numQuads = m_testCtx.getCommandLine().getTestIterationCount() > 0 ? m_testCtx.getCommandLine().getTestIterationCount() : 30;
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_iteration < numQuads);
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4 quadColor	= (float)m_iteration / (float)(numQuads-1) * m_color;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success		=  drawAndCheckUnicoloredQuad(quadColor);
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_iteration == numQuads - 1)
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_iteration++;
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CONTINUE;
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDitheringTests::DitheringTests (Context& context)
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "dither", "Dithering tests")
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDitheringTests::~DitheringTests (void)
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DitheringTests::init (void)
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4			color;
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} caseColors[] =
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "white",		Vec4(1.0f, 1.0f, 1.0f, 1.0f) },
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "red",		Vec4(1.0f, 0.0f, 0.0f, 1.0f) },
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "green",		Vec4(0.0f, 1.0f, 0.0f, 1.0f) },
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "blue",		Vec4(0.0f, 0.0f, 1.0f, 1.0f) },
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "alpha",		Vec4(0.0f, 0.0f, 0.0f, 1.0f) }
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ditheringEnabledI = 0; ditheringEnabledI <= 1; ditheringEnabledI++)
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				ditheringEnabled	= ditheringEnabledI != 0;
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const	group				= new TestCaseGroup(m_context, ditheringEnabled ? "enabled" : "disabled", "");
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int patternTypeI = 0; patternTypeI < DitheringCase::PATTERNTYPE_LAST; patternTypeI++)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int caseColorNdx = 0; caseColorNdx < DE_LENGTH_OF_ARRAY(caseColors); caseColorNdx++)
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const DitheringCase::PatternType	patternType		= (DitheringCase::PatternType)patternTypeI;
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string						caseName		= string("") + DitheringCase::getPatternTypeName(patternType) + "_" + caseColors[caseColorNdx].name;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new DitheringCase(m_context.getTestContext(), m_context.getRenderContext(), caseName.c_str(), "", ditheringEnabled, patternType, caseColors[caseColorNdx].color));
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
542