13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 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 Multisample tests
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fMultisampleTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluCallLogWrapper.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw;
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic std::string sampleMaskToString (const std::vector<deUint32>& bitfield, int numBits)
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string result(numBits, '0');
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// move from back to front and set chars to 1
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int wordNdx = 0; wordNdx < (int)bitfield.size(); ++wordNdx)
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int bit = 0; bit < 32; ++bit)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int targetCharNdx = numBits - (wordNdx*32+bit) - 1;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// beginning of the string reached
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (targetCharNdx < 0)
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return result;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((bitfield[wordNdx] >> bit) & 0x01)
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result[targetCharNdx] = '1';
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Returns the number of words needed to represent mask of given length
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getEffectiveSampleMaskWordCount (int highestBitNdx)
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int wordSize	= 32;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int maskLen	= highestBitNdx + 1;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ((maskLen - 1) / wordSize) + 1; // round_up(mask_len /  wordSize)
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Creates sample mask with all less significant bits than nthBit set
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic std::vector<deUint32> genAllSetToNthBitSampleMask (int nthBit)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				wordSize	= 32;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numWords	= getEffectiveSampleMaskWordCount(nthBit - 1);
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			topWordBits	= (deUint32)(nthBit - (numWords - 1) * wordSize);
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint32>	mask		(numWords);
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numWords - 1; ++ndx)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mask[ndx] = 0xFFFFFFFF;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	mask[numWords - 1] = (deUint32)((1ULL << topWordBits) - (deUint32)1);
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return mask;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SamplePosQueryCase : public TestCase
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					SamplePosQueryCase (Context& context, const char* name, const char* desc);
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init				(void);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate				(void);
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySamplePosQueryCase::SamplePosQueryCase (Context& context, const char* name, const char* desc)
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase(context, name, desc)
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SamplePosQueryCase::init (void)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context.getRenderTarget().getNumSamples() == 0)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("No multisample buffers");
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySamplePosQueryCase::IterateResult SamplePosQueryCase::iterate (void)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::CallLogWrapper gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				error	= false;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enableLogging(true);
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < m_context.getRenderTarget().getNumSamples(); ++ndx)
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2 samplePos = tcu::Vec2(-1, -1);
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.glGetMultisamplefv(GL_SAMPLE_POSITION, ndx, samplePos.getPtr());
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.glGetError(), "getMultisamplefv");
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// check value range
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (samplePos.x() < 0.0f || samplePos.x() > 1.0f ||
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			samplePos.y() < 0.0f || samplePos.y() > 1.0f)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Sample " << ndx << " is not in valid range [0,1], got " << samplePos << tcu::TestLog::EndMessage;
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			error = true;
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!error)
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid sample pos");
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Abstract base class handling common stuff for default fbo multisample cases.
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DefaultFBOMultisampleCase : public TestCase
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								DefaultFBOMultisampleCase	(Context& context, const char* name, const char* desc, int desiredViewportSize);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~DefaultFBOMultisampleCase	(void);
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				init						(void);
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				deinit						(void);
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderTriangle				(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderTriangle				(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderTriangle				(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderTriangle				(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const;
1763c827367444ee418f129b2c238299f49d3264554Jarkko 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;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderQuad					(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						randomizeViewport			(void);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						readImage					(tcu::Surface& dst) const;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_numSamples;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_viewportSize;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								DefaultFBOMultisampleCase	(const DefaultFBOMultisampleCase& other);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DefaultFBOMultisampleCase&	operator=					(const DefaultFBOMultisampleCase& other);
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					m_desiredViewportSize;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*			m_program;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_attrPositionLoc;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_attrColorLoc;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_viewportX;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_viewportY;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random					m_rnd;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						m_initCalled;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDefaultFBOMultisampleCase::DefaultFBOMultisampleCase (Context& context, const char* name, const char* desc, int desiredViewportSize)
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, desc)
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numSamples			(0)
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportSize		(0)
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_desiredViewportSize	(desiredViewportSize)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program				(DE_NULL)
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_attrPositionLoc		(-1)
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_attrColorLoc		(-1)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportX			(0)
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportY			(0)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rnd					(deStringHash(name))
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_initCalled			(false)
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDefaultFBOMultisampleCase::~DefaultFBOMultisampleCase (void)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DefaultFBOMultisampleCase::deinit();
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::init (void)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* vertShaderSource =
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 310 es\n"
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec4 a_position;\n"
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in mediump vec4 a_color;\n"
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"out mediump vec4 v_color;\n"
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_position;\n"
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_color = a_color;\n"
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* fragShaderSource =
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 310 es\n"
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in mediump vec4 v_color;\n"
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out mediump vec4 o_color;\n"
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	o_color = v_color;\n"
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log	= m_testCtx.getLog();
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context.getRenderTarget().getNumSamples() <= 1)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("No multisample buffers");
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_initCalled = true;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Query and log number of samples per pixel.
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_SAMPLES, &m_numSamples);
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv(GL_SAMPLES)");
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "GL_SAMPLES = " << m_numSamples << TestLog::EndMessage;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prepare program.
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_program->isOk())
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Failed to compile program", DE_NULL, __FILE__, __LINE__);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attrPositionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_position");
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attrColorLoc		= gl.getAttribLocation(m_program->getProgram(), "a_color");
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation");
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_attrPositionLoc < 0 || m_attrColorLoc < 0)
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_program;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Invalid attribute locations", DE_NULL, __FILE__, __LINE__);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get suitable viewport size.
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportSize = de::min<int>(m_desiredViewportSize, de::min(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight()));
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::deinit (void)
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Do not try to call GL functions during case list creation
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_initCalled)
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float vertexPositions[] =
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		p0.x(), p0.y(), p0.z(), 1.0f,
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		p1.x(), p1.y(), p1.z(), 1.0f,
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		p2.x(), p2.y(), p2.z(), 1.0f
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float vertexColors[] =
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		c0.x(), c0.y(), c0.z(), c0.w(),
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		c1.x(), c1.y(), c1.z(), c1.w(),
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		c2.x(), c2.y(), c2.z(), c2.w(),
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Buffer				vtxBuf	(m_context.getRenderContext());
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Buffer				colBuf	(m_context.getRenderContext());
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::VertexArray		vao		(m_context.getRenderContext());
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindVertexArray(*vao);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ARRAY_BUFFER, *vtxBuf);
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), &vertexPositions[0], GL_STATIC_DRAW);
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "vtx buf");
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enableVertexAttribArray(m_attrPositionLoc);
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, DE_NULL);
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "vtx vertexAttribPointer");
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ARRAY_BUFFER, *colBuf);
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexColors), &vertexColors[0], GL_STATIC_DRAW);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "col buf");
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enableVertexAttribArray(m_attrColorLoc);
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, DE_NULL);
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "col vertexAttribPointer");
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(m_program->getProgram());
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.drawArrays(GL_TRIANGLES, 0, 3);
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(p0, p1, p2, color, color, color);
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(Vec3(p0.x(), p0.y(), 0.0f),
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   Vec3(p1.x(), p1.y(), 0.0f),
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   Vec3(p2.x(), p2.y(), 0.0f),
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   c0, c1, c2);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(p0, p1, p2, color, color, color);
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::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
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(p0, p1, p2, c0, c1, c2);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTriangle(p2, p1, p3, c2, c1, c3);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderQuad(p0, p1, p2, p3, color, color, color, color);
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::randomizeViewport (void)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportX = m_rnd.getInt(0, m_context.getRenderTarget().getWidth()  - m_viewportSize);
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportY = m_rnd.getInt(0, m_context.getRenderTarget().getHeight() - m_viewportSize);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(m_viewportX, m_viewportY, m_viewportSize, m_viewportSize);
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::readImage (tcu::Surface& dst) const
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), m_viewportX, m_viewportY, dst.getAccess());
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask inversion validity.
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the coverage masks obtained by masks set with glSampleMaski(mask)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and glSampleMaski(~mask) are indeed each others' inverses.
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is done by drawing a pattern, with varying coverage values,
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * overlapped by a pattern that has inverted masks and is otherwise
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * identical. The resulting image is compared to one obtained by drawing
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the same pattern but with all-ones coverage masks.
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaskInvertCase : public DefaultFBOMultisampleCase
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					MaskInvertCase				(Context& context, const char* name, const char* description);
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~MaskInvertCase				(void) {}
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init						(void);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate						(void);
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			drawPattern					(bool invert) const;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskInvertCase::MaskInvertCase (Context& context, const char* name, const char* description)
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: DefaultFBOMultisampleCase	(context, name, description, 256)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskInvertCase::init (void)
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// check the test is even possible
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint maxSampleMaskWords = 0;
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords);
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (getEffectiveSampleMaskWordCount(m_numSamples - 1) > maxSampleMaskWords)
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS");
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// normal init
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DefaultFBOMultisampleCase::init();
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskInvertCase::IterateResult MaskInvertCase::iterate (void)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log								= m_testCtx.getLog();
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			renderedImgNoSampleCoverage		(m_viewportSize, m_viewportSize);
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			renderedImgSampleCoverage		(m_viewportSize, m_viewportSize);
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_BLEND);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.blendEquation(GL_FUNC_ADD);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.blendFunc(GL_ONE, GL_ONE);
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "set blend");
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples" << TestLog::EndMessage;
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_MASK disabled" << TestLog::EndMessage;
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawPattern(false);
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImgNoSampleCoverage);
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImageNoSampleMask", "Rendered image with GL_SAMPLE_MASK disabled", renderedImgNoSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_SAMPLE_MASK);
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_SAMPLE_MASK)");
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_MASK enabled, using non-inverted sample masks" << TestLog::EndMessage;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawPattern(false);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_MASK enabled, using inverted sample masks" << TestLog::EndMessage;
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawPattern(true);
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImgSampleCoverage);
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImageSampleMask", "Rendered image with GL_SAMPLE_MASK enabled", renderedImgSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool passed = tcu::pixelThresholdCompare(log,
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 "CoverageVsNoCoverage",
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 "Comparison of same pattern with GL_SAMPLE_MASK disabled and enabled",
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 renderedImgNoSampleCoverage,
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 renderedImgSampleCoverage,
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 tcu::RGBA(0),
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 tcu::COMPARE_LOG_ON_ERROR);
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (passed)
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 passed ? "Passed"				: "Failed");
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskInvertCase::drawPattern (bool invert) const
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numTriangles	= 25;
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int triNdx = 0; triNdx < numTriangles; triNdx++)
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	angle0	= 2.0f*DE_PI * (float)triNdx			/ (float)numTriangles;
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	angle1	= 2.0f*DE_PI * (float)(triNdx + 0.5f)	/ (float)numTriangles;
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4	color	= Vec4(0.4f + (float)triNdx/(float)numTriangles*0.6f,
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		                           0.5f + (float)triNdx/(float)numTriangles*0.3f,
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		                           0.6f - (float)triNdx/(float)numTriangles*0.5f,
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		                           0.7f - (float)triNdx/(float)numTriangles*0.7f);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			wordCount		= getEffectiveSampleMaskWordCount(m_numSamples - 1);
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLbitfield	finalWordBits	= m_numSamples - 32 * ((m_numSamples-1) / 32);
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLbitfield	finalWordMask	= (GLbitfield)(1ULL << finalWordBits) - 1UL;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int wordNdx = 0; wordNdx < wordCount; ++wordNdx)
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLbitfield	rawMask		= (GLbitfield)deUint32Hash(wordNdx * 32 + triNdx);
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLbitfield	mask		= (invert) ? (~rawMask) : (rawMask);
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool			isFinalWord	= (wordNdx + 1) == wordCount;
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLbitfield	maskMask	= (isFinalWord) ? (finalWordMask) : (0xFFFFFFFFUL); // maskMask prevents setting coverage bits higher than sample count
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.sampleMaski(wordNdx, mask & maskMask);
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski");
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderTriangle(Vec2(0.0f, 0.0f),
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   color);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask generation proportionality property.
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the number of coverage bits in a coverage mask set with
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * glSampleMaski is, on average, proportional to the number of set bits.
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws multiple frames, each time increasing the number of mask bits set
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and checks that the average color is changing appropriately.
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaskProportionalityCase : public DefaultFBOMultisampleCase
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					MaskProportionalityCase				(Context& context, const char* name, const char* description);
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~MaskProportionalityCase			(void) {}
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init								(void);
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate								(void);
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				m_numIterations;
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				m_currentIteration;
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32			m_previousIterationColorSum;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskProportionalityCase::MaskProportionalityCase (Context& context, const char* name, const char* description)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: DefaultFBOMultisampleCase		(context, name, description, 32)
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numIterations				(-1)
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentIteration			(0)
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_previousIterationColorSum	(-1)
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskProportionalityCase::init (void)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log	= m_testCtx.getLog();
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// check the test is even possible
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint maxSampleMaskWords = 0;
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords);
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (getEffectiveSampleMaskWordCount(m_numSamples - 1) > maxSampleMaskWords)
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS");
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DefaultFBOMultisampleCase::init();
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// set state
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_SAMPLE_MASK);
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_SAMPLE_MASK)");
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "GL_SAMPLE_MASK is enabled" << TestLog::EndMessage;
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numIterations = m_numSamples + 1;
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport(); // \note Using the same viewport for every iteration since coverage mask may depend on window-relative pixel coordinate.
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskProportionalityCase::IterateResult MaskProportionalityCase::iterate (void)
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log				= m_testCtx.getLog();
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			renderedImg		(m_viewportSize, m_viewportSize);
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32					numPixels		= (deInt32)renderedImg.getWidth()*(deInt32)renderedImg.getHeight();
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numIterations >= 0);
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw quad.
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2					pt0						(-1.0f, -1.0f);
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2					pt1						( 1.0f, -1.0f);
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2					pt2						(-1.0f,  1.0f);
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2					pt3						( 1.0f,  1.0f);
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4						quadColor				(1.0f, 0.0f, 0.0f, 1.0f);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::vector<deUint32>	sampleMask				= genAllSetToNthBitSampleMask(m_currentIteration);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_currentIteration <= m_numSamples + 1);
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Drawing a red quad using sample mask 0b" << sampleMaskToString(sampleMask, m_numSamples) << TestLog::EndMessage;
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int wordNdx = 0; wordNdx < getEffectiveSampleMaskWordCount(m_numSamples - 1); ++wordNdx)
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLbitfield mask = (wordNdx < (int)sampleMask.size()) ? ((GLbitfield)(sampleMask[wordNdx])) : (0);
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.sampleMaski(wordNdx, mask);
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski");
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderQuad(pt0, pt1, pt2, pt3, quadColor);
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read ang log image.
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImg);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute average red component in rendered image.
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32 sumRed = 0;
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < renderedImg.getWidth(); x++)
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sumRed += renderedImg.getPixel(x, y).getRed();
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Average red color component: " << de::floatToString((float)sumRed / 255.0f / (float)numPixels, 2) << TestLog::EndMessage;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check if average color has decreased from previous frame's color.
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sumRed < m_previousIterationColorSum)
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Failure: Current average red color component is lower than previous" << TestLog::EndMessage;
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check if coverage mask is not all-zeros if alpha or coverage value is 0 (or 1, if inverted).
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration == 0 && sumRed != 0)
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Failure: Image should be completely black" << TestLog::EndMessage;
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration == m_numIterations-1 && sumRed != 0xff*numPixels)
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Failure: Image should be completely red" << TestLog::EndMessage;
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_previousIterationColorSum = sumRed;
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentIteration++;
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration >= m_numIterations)
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: Number of coverage mask bits set appears to be, on average, proportional to the number of set sample mask bits" << TestLog::EndMessage;
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTINUE;
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask generation constancy property.
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the coverage mask created by GL_SAMPLE_MASK is constant at
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * given pixel coordinates. Draws two quads, with the second one fully
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * overlapping the first one such that at any given pixel, both quads have
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the same coverage mask value. This way, if the constancy property is
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * fulfilled, only the second quad should be visible.
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaskConstancyCase : public DefaultFBOMultisampleCase
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseBits
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASEBIT_ALPHA_TO_COVERAGE			= 1,	//!< Use alpha-to-coverage.
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASEBIT_SAMPLE_COVERAGE				= 2,	//!< Use sample coverage.
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASEBIT_SAMPLE_COVERAGE_INVERTED	= 4,	//!< Inverted sample coverage.
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASEBIT_SAMPLE_MASK					= 8,	//!< Use sample mask.
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					MaskConstancyCase			(Context& context, const char* name, const char* description, deUint32 typeBits);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~MaskConstancyCase			(void) {}
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init						(void);
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate						(void);
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_isAlphaToCoverageCase;
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_isSampleCoverageCase;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_isInvertedSampleCoverageCase;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_isSampleMaskCase;
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskConstancyCase::MaskConstancyCase (Context& context, const char* name, const char* description, deUint32 typeBits)
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: DefaultFBOMultisampleCase			(context, name, description, 256)
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isAlphaToCoverageCase			(0 != (typeBits & CASEBIT_ALPHA_TO_COVERAGE))
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isSampleCoverageCase			(0 != (typeBits & CASEBIT_SAMPLE_COVERAGE))
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isInvertedSampleCoverageCase	(0 != (typeBits & CASEBIT_SAMPLE_COVERAGE_INVERTED))
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isSampleMaskCase				(0 != (typeBits & CASEBIT_SAMPLE_MASK))
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// CASEBIT_SAMPLE_COVERAGE_INVERT => CASEBIT_SAMPLE_COVERAGE
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((typeBits & CASEBIT_SAMPLE_COVERAGE) || ~(typeBits & CASEBIT_SAMPLE_COVERAGE_INVERTED));
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_isSampleMaskCase); // no point testing non-sample-mask cases, they are checked already in gles3
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskConstancyCase::init (void)
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// check the test is even possible
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isSampleMaskCase)
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint maxSampleMaskWords = 0;
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (getEffectiveSampleMaskWordCount(m_numSamples - 1) > maxSampleMaskWords)
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS");
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// normal init
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DefaultFBOMultisampleCase::init();
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskConstancyCase::IterateResult MaskConstancyCase::iterate (void)
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log				= m_testCtx.getLog();
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			renderedImg		(m_viewportSize, m_viewportSize);
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isAlphaToCoverageCase)
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable(GL_SAMPLE_ALPHA_TO_COVERAGE);
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "enable GL_SAMPLE_ALPHA_TO_COVERAGE");
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Color mask is TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isSampleCoverageCase)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable(GL_SAMPLE_COVERAGE);
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "enable GL_SAMPLE_COVERAGE");
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isSampleMaskCase)
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable(GL_SAMPLE_MASK);
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "enable GL_SAMPLE_MASK");
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "GL_SAMPLE_MASK is enabled" << TestLog::EndMessage;
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Drawing several green quads, each fully overlapped by a red quad with the same "
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isAlphaToCoverageCase ? "alpha" : "")
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isAlphaToCoverageCase && (m_isSampleCoverageCase || m_isSampleMaskCase) ? " and " : "")
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isInvertedSampleCoverageCase ? "inverted " : "")
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isSampleCoverageCase ? "sample coverage" : "")
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isSampleCoverageCase && m_isSampleMaskCase ? " and " : "")
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isSampleMaskCase ? "sample mask" : "")
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< " values"
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numQuadRowsCols = m_numSamples*4;
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < numQuadRowsCols; row++)
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < numQuadRowsCols; col++)
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		x0			= (float)(col+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		x1			= (float)(col+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		y0			= (float)(row+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		y1			= (float)(row+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4	baseGreen	(0.0f, 1.0f, 0.0f, 0.0f);
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4	baseRed		(1.0f, 0.0f, 0.0f, 0.0f);
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4		alpha0		(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)col / (float)(numQuadRowsCols-1) : 1.0f);
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4		alpha1		(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)row / (float)(numQuadRowsCols-1) : 1.0f);
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_isSampleCoverageCase)
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float value = (float)(row*numQuadRowsCols + col) / (float)(numQuadRowsCols*numQuadRowsCols-1);
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.sampleCoverage(m_isInvertedSampleCoverageCase ? 1.0f - value : value, m_isInvertedSampleCoverageCase ? GL_TRUE : GL_FALSE);
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleCoverage");
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_isSampleMaskCase)
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			wordCount		= getEffectiveSampleMaskWordCount(m_numSamples - 1);
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLbitfield	finalWordBits	= m_numSamples - 32 * ((m_numSamples-1) / 32);
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLbitfield	finalWordMask	= (GLbitfield)(1ULL << finalWordBits) - 1UL;
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int wordNdx = 0; wordNdx < wordCount; ++wordNdx)
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const GLbitfield	mask		= (GLbitfield)deUint32Hash((col << (m_numSamples / 2)) ^ row);
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const bool			isFinalWord	= (wordNdx + 1) == wordCount;
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const GLbitfield	maskMask	= (isFinalWord) ? (finalWordMask) : (0xFFFFFFFFUL); // maskMask prevents setting coverage bits higher than sample count
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.sampleMaski(wordNdx, mask & maskMask);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski");
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseGreen + alpha0,	baseGreen + alpha1,	baseGreen + alpha0,	baseGreen + alpha1);
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseRed + alpha0,	baseRed + alpha1,	baseRed + alpha0,	baseRed + alpha1);
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImg);
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < renderedImg.getWidth(); x++)
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (renderedImg.getPixel(x, y).getGreen() > 0)
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Failure: Non-zero green color component detected - should have been completely overwritten by red quad" << TestLog::EndMessage;
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Success: Coverage mask appears to be constant at a given pixel coordinate with a given "
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isAlphaToCoverageCase ? "alpha" : "")
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< (m_isSampleCoverageCase ? "coverage value" : "")
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests that unused bits of a sample mask have no effect
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the bits in the sample mask with positions higher than
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the number of samples do not have effect. In multisample fragment
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * operations the sample mask is ANDed with the fragment coverage value.
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The coverage value cannot have the corresponding bits set.
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is done by drawing a quads with varying sample masks and then
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * redrawing the quads with identical masks but with the mask's high bits
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * having different values. Only the latter quad pattern should be visible.
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SampleMaskHighBitsCase : public DefaultFBOMultisampleCase
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					SampleMaskHighBitsCase		(Context& context, const char* name, const char* description);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~SampleMaskHighBitsCase		(void) {}
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init						(void);
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate						(void);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8793c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySampleMaskHighBitsCase::SampleMaskHighBitsCase (Context& context, const char* name, const char* description)
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: DefaultFBOMultisampleCase(context, name, description, 256)
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SampleMaskHighBitsCase::init (void)
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint					 maxSampleMaskWords	= 0;
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// check the test is even possible
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords);
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (getEffectiveSampleMaskWordCount(m_numSamples - 1) > maxSampleMaskWords)
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS");
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// normal init
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DefaultFBOMultisampleCase::init();
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8983c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySampleMaskHighBitsCase::IterateResult SampleMaskHighBitsCase::iterate (void)
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log				= m_testCtx.getLog();
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			renderedImg		(m_viewportSize, m_viewportSize);
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd				(12345);
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_numSamples % 32 == 0)
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Sample count is multiple of word size. No unused high bits in sample mask.\nSkipping." << TestLog::EndMessage;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Skipped");
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomizeViewport();
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_SAMPLE_MASK);
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "enable GL_SAMPLE_MASK");
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "GL_SAMPLE_MASK is enabled" << TestLog::EndMessage;
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Drawing several green quads, each fully overlapped by a red quad with the same effective sample mask values" << TestLog::EndMessage;
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numQuadRowsCols = m_numSamples*4;
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < numQuadRowsCols; row++)
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < numQuadRowsCols; col++)
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				x0				= (float)(col+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				x1				= (float)(col+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				y0				= (float)(row+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				y1				= (float)(row+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4			baseGreen		(0.0f, 1.0f, 0.0f, 1.0f);
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4			baseRed			(1.0f, 0.0f, 0.0f, 1.0f);
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int			wordCount		= getEffectiveSampleMaskWordCount(m_numSamples - 1);
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLbitfield	finalWordBits	= m_numSamples - 32 * ((m_numSamples-1) / 32);
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLbitfield	finalWordMask	= (GLbitfield)(1ULL << finalWordBits) - 1UL;
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int wordNdx = 0; wordNdx < wordCount; ++wordNdx)
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLbitfield	mask		= (GLbitfield)deUint32Hash((col << (m_numSamples / 2)) ^ row);
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const bool			isFinalWord	= (wordNdx + 1) == wordCount;
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLbitfield	maskMask	= (isFinalWord) ? (finalWordMask) : (0xFFFFFFFFUL); // maskMask is 1 on bits in lower positions than sample count
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLbitfield	highBits	= rnd.getUint32();
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.sampleMaski(wordNdx, (mask & maskMask) | (highBits & ~maskMask));
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski");
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseGreen, baseGreen, baseGreen, baseGreen);
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int wordNdx = 0; wordNdx < wordCount; ++wordNdx)
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLbitfield	mask		= (GLbitfield)deUint32Hash((col << (m_numSamples / 2)) ^ row);
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const bool			isFinalWord	= (wordNdx + 1) == wordCount;
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLbitfield	maskMask	= (isFinalWord) ? (finalWordMask) : (0xFFFFFFFFUL); // maskMask is 1 on bits in lower positions than sample count
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLbitfield	highBits	= rnd.getUint32();
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.sampleMaski(wordNdx, (mask & maskMask) | (highBits & ~maskMask));
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski");
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseRed, baseRed, baseRed, baseRed);
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readImage(renderedImg);
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < renderedImg.getWidth(); x++)
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (renderedImg.getPixel(x, y).getGreen() > 0)
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Failure: Non-zero green color component detected - should have been completely overwritten by red quad. Mask unused bits have effect." << TestLog::EndMessage;
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Unused mask bits modified mask");
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Success: Coverage mask high bits appear to have no effect." << TestLog::EndMessage;
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleTests::MultisampleTests (Context& context)
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "multisample", "Multisample tests")
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleTests::~MultisampleTests (void)
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleTests::init (void)
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "default_framebuffer", "Test with default framebuffer");
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(group);
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .default_framebuffer
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// sample positions
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new SamplePosQueryCase			(m_context, "sample_position", "test SAMPLE_POSITION"));
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// sample mask
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new MaskInvertCase				(m_context, "sample_mask_sum_of_inverses",	"Test that mask and its negation's sum equal the fully set mask"));
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new MaskProportionalityCase		(m_context, "proportionality_sample_mask",	"Test the proportionality property of GL_SAMPLE_MASK"));
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new MaskConstancyCase			(m_context, "constancy_sample_mask",
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_MASK",
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	MaskConstancyCase::CASEBIT_SAMPLE_MASK));
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new MaskConstancyCase			(m_context, "constancy_alpha_to_coverage_sample_mask",
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"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_MASK",
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	MaskConstancyCase::CASEBIT_ALPHA_TO_COVERAGE | MaskConstancyCase::CASEBIT_SAMPLE_MASK));
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new MaskConstancyCase			(m_context, "constancy_sample_coverage_sample_mask",
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_COVERAGE and GL_SAMPLE_MASK",
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	MaskConstancyCase::CASEBIT_SAMPLE_COVERAGE | MaskConstancyCase::CASEBIT_SAMPLE_MASK));
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new MaskConstancyCase			(m_context, "constancy_alpha_to_coverage_sample_coverage_sample_mask",
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE, GL_SAMPLE_COVERAGE and GL_SAMPLE_MASK",
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	MaskConstancyCase::CASEBIT_ALPHA_TO_COVERAGE | MaskConstancyCase::CASEBIT_SAMPLE_COVERAGE | MaskConstancyCase::CASEBIT_SAMPLE_MASK));
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new SampleMaskHighBitsCase		(m_context, "sample_mask_non_effective_bits",
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"Test that values of unused bits of a sample mask (bit index > sample count) have no effect"));
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1034