11f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry/*-------------------------------------------------------------------------
21f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * drawElements Quality Program OpenGL ES 3.1 Module
31f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * -------------------------------------------------
41f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry *
51f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * Copyright 2015 The Android Open Source Project
61f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry *
71f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * Licensed under the Apache License, Version 2.0 (the "License");
81f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * you may not use this file except in compliance with the License.
91f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * You may obtain a copy of the License at
101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry *
111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry *      http://www.apache.org/licenses/LICENSE-2.0
121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry *
131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * Unless required by applicable law or agreed to in writing, software
141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * distributed under the License is distributed on an "AS IS" BASIS,
151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * See the License for the specific language governing permissions and
171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * limitations under the License.
181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry *
191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry *//*!
201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * \file
211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry * \brief Primitive bounding box tests.
221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry *//*--------------------------------------------------------------------*/
231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "es31fPrimitiveBoundingBoxTests.hpp"
251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "tcuTestLog.hpp"
271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "tcuRenderTarget.hpp"
281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "tcuSurface.hpp"
291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "tcuTextureUtil.hpp"
301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "tcuVectorUtil.hpp"
311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "gluCallLogWrapper.hpp"
321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "gluContextInfo.hpp"
331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "gluRenderContext.hpp"
341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "gluStrUtil.hpp"
351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "gluShaderProgram.hpp"
361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "gluObjectWrapper.hpp"
371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "gluPixelTransfer.hpp"
381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "glsStateQueryUtil.hpp"
391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "glwFunctions.hpp"
401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "glwEnums.hpp"
411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "deRandom.hpp"
421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "deUniquePtr.hpp"
431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include "deStringUtil.hpp"
441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include <vector>
461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include <sstream>
471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry#include <algorithm>
481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrynamespace deqp
501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrynamespace gles31
521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrynamespace Functional
541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrynamespace
561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrynamespace StateQueryUtil = ::deqp::gls::StateQueryUtil;
591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystruct BoundingBox
611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Vec4 min;
631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Vec4 max;
641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	/*--------------------------------------------------------------------*//*!
661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	 * Get component by index of a 8-component vector constructed by
671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	 * concatenating 4-component min and max vectors.
681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	 *//*--------------------------------------------------------------------*/
691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	float&			getComponentAccess	(int ndx);
701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const float&	getComponentAccess	(int ndx) const;
711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryfloat& BoundingBox::getComponentAccess (int ndx)
741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(ndx >= 0 && ndx < 8);
761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (ndx < 4)
771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return min[ndx];
781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return max[ndx-4];
801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryconst float& BoundingBox::getComponentAccess (int ndx) const
831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return const_cast<BoundingBox*>(this)->getComponentAccess(ndx);
851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystruct ProjectedBBox
881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Vec3	min;
901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Vec3	max;
911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystatic ProjectedBBox projectBoundingBox (const BoundingBox& bbox)
941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const float		wMin	= de::max(0.0f, bbox.min.w()); // clamp to w=0 as extension requires
961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const float		wMax	= de::max(0.0f, bbox.max.w());
971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	ProjectedBBox	retVal;
981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	retVal.min = tcu::min(bbox.min.swizzle(0, 1, 2) / wMin,
1001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						  bbox.min.swizzle(0, 1, 2) / wMax);
1011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	retVal.max = tcu::max(bbox.max.swizzle(0, 1, 2) / wMin,
1021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						  bbox.max.swizzle(0, 1, 2) / wMax);
1031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return retVal;
1041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
1051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystatic tcu::IVec4 getViewportBoundingBoxArea (const ProjectedBBox& bbox, const tcu::IVec2& viewportSize, float size = 0.0f)
1071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
1081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Vec4	vertexBox;
1091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::IVec4	pixelBox;
1101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1117a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	vertexBox.x() = (bbox.min.x() * 0.5f + 0.5f) * (float)viewportSize.x();
1127a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	vertexBox.y() = (bbox.min.y() * 0.5f + 0.5f) * (float)viewportSize.y();
1137a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	vertexBox.z() = (bbox.max.x() * 0.5f + 0.5f) * (float)viewportSize.x();
1147a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	vertexBox.w() = (bbox.max.y() * 0.5f + 0.5f) * (float)viewportSize.y();
1151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	pixelBox.x() = deFloorFloatToInt32(vertexBox.x() - size/2.0f);
1171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	pixelBox.y() = deFloorFloatToInt32(vertexBox.y() - size/2.0f);
1181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	pixelBox.z() = deCeilFloatToInt32(vertexBox.z() + size/2.0f);
1191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	pixelBox.w() = deCeilFloatToInt32(vertexBox.w() + size/2.0f);
1201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return pixelBox;
1211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
1221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass InitialValueCase : public TestCase
1251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
1261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
1271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					InitialValueCase	(Context& context, const char* name, const char* desc);
1281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void			init				(void);
1301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterateResult	iterate				(void);
1311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
1321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryInitialValueCase::InitialValueCase (Context& context, const char* name, const char* desc)
1341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: TestCase(context, name, desc)
1351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
1361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
1371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid InitialValueCase::init (void)
1391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
1401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"))
1411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
1421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
1431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryInitialValueCase::IterateResult InitialValueCase::iterate (void)
1451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
1461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat[8]>	state;
1471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::CallLogWrapper											gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enableLogging(true);
1501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
1521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
1531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Querying GL_PRIMITIVE_BOUNDING_BOX_EXT, expecting (-1, -1, -1, 1) (1, 1, 1, 1)"
1541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
1551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.glGetFloatv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
1571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
1581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!state.verifyValidity(m_testCtx))
1601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return STOP;
1611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
1631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
1641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Got " << tcu::formatArray(&state[0], &state[8])
1651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
1661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if ((state[0] != -1.0f) || (state[1] != -1.0f) || (state[2] != -1.0f) || (state[3] != 1.0f) ||
1681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		(state[4] !=  1.0f) || (state[5] !=  1.0f) || (state[6] !=  1.0f) || (state[7] != 1.0f))
1691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
1701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
1711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
1721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Error, unexpected value"
1731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
1741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid initial value");
1761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
1771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
1781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return STOP;
1811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
1821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass QueryCase : public TestCase
1841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
1851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
1861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum QueryMethod
1871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
1881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		QUERY_FLOAT = 0,
1891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		QUERY_BOOLEAN,
1901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		QUERY_INT,
1911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		QUERY_INT64,
1921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		QUERY_LAST
1941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
1951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						QueryCase	(Context& context, const char* name, const char* desc, QueryMethod method);
1971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
1991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void				init		(void);
2001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterateResult		iterate		(void);
2011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool				verifyState	(glu::CallLogWrapper& gl, const BoundingBox& bbox) const;
2031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const QueryMethod	m_method;
2051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
2061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryQueryCase::QueryCase (Context& context, const char* name, const char* desc, QueryMethod method)
2081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: TestCase	(context, name, desc)
2091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_method	(method)
2101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
2111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(method < QUERY_LAST);
2121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
2131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid QueryCase::init (void)
2151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
2161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"))
2171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
2181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
2191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryQueryCase::IterateResult QueryCase::iterate (void)
2211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
2221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	static const BoundingBox fixedCases[] =
2231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
2241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{ tcu::Vec4( 0.0f,  0.0f,  0.0f,  0.0f), tcu::Vec4( 0.0f,  0.0f,  0.0f,  0.0f) },
2251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{ tcu::Vec4(-0.0f, -0.0f, -0.0f, -0.0f), tcu::Vec4( 0.0f,  0.0f,  0.0f, -0.0f) },
2261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{ tcu::Vec4( 0.0f,  0.0f,  0.0f,  0.0f), tcu::Vec4( 1.0f,  1.0f,  1.0f, -1.0f) },
2271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{ tcu::Vec4( 2.0f,  2.0f,  2.0f,  2.0f), tcu::Vec4( 1.5f,  1.5f,  1.5f,  1.0f) },
2281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{ tcu::Vec4( 1.0f,  1.0f,  1.0f,  1.0f), tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f) },
2291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{ tcu::Vec4( 1.0f,  1.0f,  1.0f,  0.3f), tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.2f) },
2301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
2311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int					numRandomCases	= 9;
2331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::CallLogWrapper			gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random					rnd				(0xDE3210);
2351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<BoundingBox>	cases;
2361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	cases.insert(cases.begin(), DE_ARRAY_BEGIN(fixedCases), DE_ARRAY_END(fixedCases));
2381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < numRandomCases; ++ndx)
2391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
2401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BoundingBox	boundingBox;
2411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// parameter evaluation order is not guaranteed, cannot just do "max = (rand(), rand(), ...)
2431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int coordNdx = 0; coordNdx < 8; ++coordNdx)
2441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			boundingBox.getComponentAccess(coordNdx) = rnd.getFloat(-4.0f, 4.0f);
2451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		cases.push_back(boundingBox);
2471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
2481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enableLogging(true);
2501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int caseNdx = 0; caseNdx < (int)cases.size(); ++caseNdx)
2531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
25430fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Iteration", "Iteration " + de::toString(caseNdx+1));
25530fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry		const BoundingBox&			boundingBox	= cases[caseNdx];
2561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
257485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe		gl.glPrimitiveBoundingBox(boundingBox.min.x(), boundingBox.min.y(), boundingBox.min.z(), boundingBox.min.w(),
258485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe								  boundingBox.max.x(), boundingBox.max.y(), boundingBox.max.z(), boundingBox.max.w());
2591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (!verifyState(gl, boundingBox))
2611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected query result");
2621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
2631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return STOP;
2651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
2661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool QueryCase::verifyState (glu::CallLogWrapper& gl, const BoundingBox& bbox) const
2681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
2691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	switch (m_method)
2701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
2711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		case QUERY_FLOAT:
2721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
2731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat[8]>	state;
2741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bool														error = false;
2751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.glGetFloatv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
2771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
2781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (!state.verifyValidity(m_testCtx))
2801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return false;
2811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog()
2831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::Message
2841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< "glGetFloatv returned " << tcu::formatArray(&state[0], &state[8])
2851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::EndMessage;
2861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			for (int ndx = 0; ndx < 8; ++ndx)
2881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (state[ndx] != bbox.getComponentAccess(ndx))
2891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					error = true;
2901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
2911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (error)
2921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
2931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				m_testCtx.getLog()
2941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::Message
2951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< "Error, unexpected value\n"
2961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< "Expected ["
2971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< bbox.min.x() << ", " << bbox.min.y() << ", " << bbox.min.z() << ", " << bbox.min.w() << ", "
2981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< bbox.max.x() << ", " << bbox.max.y() << ", " << bbox.max.z() << ", " << bbox.max.w() << "]"
2991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::EndMessage;
3001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return false;
3011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
3021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return true;
3031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
3041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		case QUERY_INT:
3061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
3071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[8]>	state;
3081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bool														error = false;
3091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.glGetIntegerv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
3111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
3121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (!state.verifyValidity(m_testCtx))
3141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return false;
3151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog()
3171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::Message
3181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< "glGetIntegerv returned " << tcu::formatArray(&state[0], &state[8])
3191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::EndMessage;
3201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			for (int ndx = 0; ndx < 8; ++ndx)
3221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (state[ndx] != StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint>(bbox.getComponentAccess(ndx)) &&
3231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					state[ndx] != StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint>(bbox.getComponentAccess(ndx)))
3241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					error = true;
3251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (error)
3271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
3281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				tcu::MessageBuilder builder(&m_testCtx.getLog());
3291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				builder	<< "Error, unexpected value\n"
3311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						<< "Expected [";
3321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				for (int ndx = 0; ndx < 8; ++ndx)
3341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
3351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					const glw::GLint roundDown	= StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint>(bbox.getComponentAccess(ndx));
3361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					const glw::GLint roundUp	= StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint>(bbox.getComponentAccess(ndx));
3371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					if (ndx != 0)
3391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						builder << ", ";
3401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					if (roundDown == roundUp)
3421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						builder << roundDown;
3431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					else
3441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						builder << "{" << roundDown << ", " << roundUp << "}";
3451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
3461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				builder	<< "]"
3481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						<< tcu::TestLog::EndMessage;
3491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return false;
3501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
3511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return true;
3521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
3531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		case QUERY_INT64:
3551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
3561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint64[8]>	state;
3571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bool																error = false;
3581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.glGetInteger64v(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
3601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
3611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (!state.verifyValidity(m_testCtx))
3631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return false;
3641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog()
3661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::Message
3671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< "glGetInteger64v returned " << tcu::formatArray(&state[0], &state[8])
3681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::EndMessage;
3691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			for (int ndx = 0; ndx < 8; ++ndx)
3711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (state[ndx] != StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(bbox.getComponentAccess(ndx)) &&
3721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					state[ndx] != StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(bbox.getComponentAccess(ndx)))
3731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					error = true;
3741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (error)
3761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
3771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				tcu::MessageBuilder builder(&m_testCtx.getLog());
3781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				builder	<< "Error, unexpected value\n"
3801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						<< "Expected [";
3811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				for (int ndx = 0; ndx < 8; ++ndx)
3831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
3841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					const glw::GLint64 roundDown	= StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(bbox.getComponentAccess(ndx));
3851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					const glw::GLint64 roundUp		= StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(bbox.getComponentAccess(ndx));
3861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					if (ndx != 0)
3881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						builder << ", ";
3891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					if (roundDown == roundUp)
3911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						builder << roundDown;
3921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					else
3931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						builder << "{" << roundDown << ", " << roundUp << "}";
3941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
3951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				builder	<< "]"
3971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						<< tcu::TestLog::EndMessage;
3981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return false;
3991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
4001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return true;
4011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
4021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		case QUERY_BOOLEAN:
4041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
4051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean[8]>	state;
4061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bool															error = false;
4071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.glGetBooleanv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
4091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
4101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (!state.verifyValidity(m_testCtx))
4121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return false;
4131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog()
4151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::Message
4161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< "glGetBooleanv returned ["
4171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< glu::getBooleanStr(state[0]) << ", " << glu::getBooleanStr(state[1]) << ", " << glu::getBooleanStr(state[2]) << ", " << glu::getBooleanStr(state[3]) << ", "
4181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< glu::getBooleanStr(state[4]) << ", " << glu::getBooleanStr(state[5]) << ", " << glu::getBooleanStr(state[6]) << ", " << glu::getBooleanStr(state[7]) << "]\n"
4191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< tcu::TestLog::EndMessage;
4201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			for (int ndx = 0; ndx < 8; ++ndx)
4221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (state[ndx] != ((bbox.getComponentAccess(ndx) != 0.0f) ? (GL_TRUE) : (GL_FALSE)))
4231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					error = true;
4241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (error)
4261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
4271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				tcu::MessageBuilder builder(&m_testCtx.getLog());
4281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				builder	<< "Error, unexpected value\n"
4301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						<< "Expected [";
4311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				for (int ndx = 0; ndx < 8; ++ndx)
4331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
4341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					if (ndx != 0)
4351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						builder << ", ";
4361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					builder << ((bbox.getComponentAccess(ndx) != 0.0f) ? ("GL_TRUE") : ("GL_FALSE"));
4381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
4391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				builder	<< "]"
4411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						<< tcu::TestLog::EndMessage;
4421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return false;
4431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
4441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return true;
4451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
4461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		default:
4481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			DE_ASSERT(false);
4491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return true;
4501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
4511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
4521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass BBoxRenderCase : public TestCase
4541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
4551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
4561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
4571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
4581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_RENDERTARGET_DEFAULT	= 1u << 0, //!< render to default renderbuffer
4591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_RENDERTARGET_FBO		= 1u << 1, //!< render to framebuffer object
4601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_BBOXSIZE_EQUAL			= 1u << 2, //!< set tight primitive bounding box
4621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_BBOXSIZE_LARGER		= 1u << 3, //!< set padded primitive bounding box
4631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_BBOXSIZE_SMALLER		= 1u << 4, //!< set too small primitive bounding box
4641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_TESSELLATION			= 1u << 5, //!< use tessellation shader
4661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_GEOMETRY				= 1u << 6, //!< use geometry shader
4671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_SET_BBOX_STATE			= 1u << 7, //!< set primitive bounding box using global state
4691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_SET_BBOX_OUTPUT		= 1u << 8, //!< set primitive bounding box using tessellation output
4701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAG_PER_PRIMITIVE_BBOX		= 1u << 9, //!< set primitive bounding per primitive
4711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FLAGBIT_USER_BIT			= 10u //!< bits N and and up are reserved for subclasses
4731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
4741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									BBoxRenderCase					(Context& context, const char* name, const char* description, int numIterations, deUint32 flags);
4761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									~BBoxRenderCase					(void);
4771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprotected:
4791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum RenderTarget
4801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
4811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		RENDERTARGET_DEFAULT,
4821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		RENDERTARGET_FBO,
4831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
4841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum BBoxSize
4851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
4861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BBOXSIZE_EQUAL,
4871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BBOXSIZE_LARGER,
4881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BBOXSIZE_SMALLER,
4891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
4901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
4921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
4931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		RENDER_TARGET_MIN_SIZE	= 256,
4941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FBO_SIZE				= 512,
4951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		MIN_VIEWPORT_SIZE		= 256,
4961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		MAX_VIEWPORT_SIZE		= 512,
4971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
4981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_STATIC_ASSERT(MIN_VIEWPORT_SIZE <= RENDER_TARGET_MIN_SIZE);
4991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
5011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
5021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		VA_POS_VEC_NDX		= 0,
5031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		VA_COL_VEC_NDX		= 1,
5041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		VA_NUM_ATTRIB_VECS	= 2,
5051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
5061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum AABBRoundDirection
5081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
5091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		ROUND_INWARDS = 0,
5101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		ROUND_OUTWARDS
5111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
5121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	struct IterationConfig
5141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
5151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::IVec2	viewportPos;
5161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::IVec2	viewportSize;
5171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec2	patternPos;		//!< in NDC
5181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec2	patternSize;	//!< in NDC
5191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BoundingBox	bbox;
5201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
5211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual void					init							(void);
5231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual void					deinit							(void);
5241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterateResult					iterate							(void);
5251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual std::string				genVertexSource					(void) const = 0;
5271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual std::string				genFragmentSource				(void) const = 0;
5281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual std::string				genTessellationControlSource	(void) const = 0;
5291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual std::string				genTessellationEvaluationSource	(void) const = 0;
5301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual std::string				genGeometrySource				(void) const = 0;
5311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual IterationConfig			generateConfig					(int iteration, const tcu::IVec2& renderTargetSize) const = 0;
5331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual void					getAttributeData				(std::vector<tcu::Vec4>& data) const = 0;
5341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual void					renderTestPattern				(const IterationConfig& config) = 0;
5351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	virtual void					verifyRenderResult				(const IterationConfig& config) = 0;
5361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterationConfig					generateRandomConfig			(int seed, const tcu::IVec2& renderTargetSize) const;
5381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::IVec4						getViewportPatternArea			(const tcu::Vec2& patternPos, const tcu::Vec2& patternSize, const tcu::IVec2& viewportSize, AABBRoundDirection roundDir) const;
5391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							setupRender						(const IterationConfig& config);
5411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum ShaderFunction
5431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
5441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		SHADER_FUNC_MIRROR_X,
5451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		SHADER_FUNC_MIRROR_Y,
5461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		SHADER_FUNC_INSIDE_BBOX,
5471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
5481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const char*						genShaderFunction				(ShaderFunction func) const;
5501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const RenderTarget				m_renderTarget;
5521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const BBoxSize					m_bboxSize;
5531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool						m_hasTessellationStage;
5541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool						m_hasGeometryStage;
5551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool						m_useGlobalState;
5561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool						m_calcPerPrimitiveBBox;
5571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int						m_numIterations;
5581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::ShaderProgram>	m_program;
5601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Buffer>		m_vbo;
5611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Framebuffer>	m_fbo;
5621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
5641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<IterationConfig>	m_iterationConfigs;
5651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int								m_iteration;
5661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
5671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryBBoxRenderCase::BBoxRenderCase (Context& context, const char* name, const char* description, int numIterations, deUint32 flags)
5691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: TestCase					(context, name, description)
5701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_renderTarget			((flags & FLAG_RENDERTARGET_DEFAULT) ? (RENDERTARGET_DEFAULT) : (RENDERTARGET_FBO))
5711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_bboxSize				((flags & FLAG_BBOXSIZE_EQUAL) ? (BBOXSIZE_EQUAL) : (flags & FLAG_BBOXSIZE_SMALLER) ? (BBOXSIZE_SMALLER) : (BBOXSIZE_LARGER))
5721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_hasTessellationStage	((flags & FLAG_TESSELLATION) != 0)
5731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_hasGeometryStage		((flags & FLAG_GEOMETRY) != 0)
5741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_useGlobalState			((flags & FLAG_SET_BBOX_STATE) != 0)
5751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_calcPerPrimitiveBBox	((flags & FLAG_PER_PRIMITIVE_BBOX) != 0)
5761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_numIterations			(numIterations)
5771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_iteration				(0)
5781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
5791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// validate flags
5801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT((((m_renderTarget == RENDERTARGET_DEFAULT)	?	(FLAG_RENDERTARGET_DEFAULT)	: (0)) |
5811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((m_renderTarget == RENDERTARGET_FBO)		?	(FLAG_RENDERTARGET_FBO)		: (0)) |
5821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((m_bboxSize == BBOXSIZE_EQUAL)				?	(FLAG_BBOXSIZE_EQUAL)		: (0)) |
5831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((m_bboxSize == BBOXSIZE_LARGER)				?	(FLAG_BBOXSIZE_LARGER)		: (0)) |
5841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((m_bboxSize == BBOXSIZE_SMALLER)			?	(FLAG_BBOXSIZE_SMALLER)		: (0)) |
5851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((m_hasTessellationStage)					?	(FLAG_TESSELLATION)			: (0)) |
5861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((m_hasGeometryStage)						?	(FLAG_GEOMETRY)				: (0)) |
5871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((m_useGlobalState)							?	(FLAG_SET_BBOX_STATE)		: (0)) |
5881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((!m_useGlobalState)							?	(FLAG_SET_BBOX_OUTPUT)		: (0)) |
5891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			   ((m_calcPerPrimitiveBBox)					?	(FLAG_PER_PRIMITIVE_BBOX)	: (0))) == (flags & ((1u << FLAGBIT_USER_BIT) - 1)));
5901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(m_useGlobalState || m_hasTessellationStage); // using non-global state requires tessellation
5921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
5931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_calcPerPrimitiveBBox)
5941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
5951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DE_ASSERT(!m_useGlobalState); // per-primitive test requires per-primitive (non-global) state
5961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DE_ASSERT(m_bboxSize == BBOXSIZE_EQUAL); // smaller is hard to verify, larger not interesting
5971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
5981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
5991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryBBoxRenderCase::~BBoxRenderCase (void)
6011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
6021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	deinit();
6031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
6041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid BBoxRenderCase::init (void)
6061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
6071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
6081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2		renderTargetSize	= (m_renderTarget == RENDERTARGET_DEFAULT) ?
6091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													(tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) :
6101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													(tcu::IVec2(FBO_SIZE, FBO_SIZE));
6111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// requirements
6131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"))
6141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
6151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_hasTessellationStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
6161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
6171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_hasGeometryStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
6181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
6191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_renderTarget == RENDERTARGET_DEFAULT && (renderTargetSize.x() < RENDER_TARGET_MIN_SIZE || renderTargetSize.y() < RENDER_TARGET_MIN_SIZE))
6201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError(std::string() + "Test requires " + de::toString<int>(RENDER_TARGET_MIN_SIZE) + "x" + de::toString<int>(RENDER_TARGET_MIN_SIZE) + " default framebuffer");
6211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// log case specifics
6231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
6241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
6251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Setting primitive bounding box "
6261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_calcPerPrimitiveBBox)         ? ("to exactly cover each generated primitive")
6271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			  : (m_bboxSize == BBOXSIZE_EQUAL)   ? ("to exactly cover rendered grid")
6281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			  : (m_bboxSize == BBOXSIZE_LARGER)  ? ("to cover the grid and include some padding")
6291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			  : (m_bboxSize == BBOXSIZE_SMALLER) ? ("to cover only a subset of the grid")
6301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			  : (DE_NULL))
6311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ".\n"
6321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Rendering with vertex"
6331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_hasTessellationStage) ? ("-tessellation{ctrl,eval}") : (""))
6341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_hasGeometryStage) ? ("-geometry") : (""))
6351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "-fragment program.\n"
6361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Set bounding box using "
6371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_useGlobalState) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") : ("gl_BoundingBoxEXT output"))
6381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\n"
6391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Verifying rendering results are valid within the bounding box."
6401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
6411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// resources
6431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
6451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		glu::ProgramSources sources;
6461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		sources << glu::VertexSource(genVertexSource());
6471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		sources << glu::FragmentSource(genFragmentSource());
6481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasTessellationStage)
6501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			sources << glu::TessellationControlSource(genTessellationControlSource())
6511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< glu::TessellationEvaluationSource(genTessellationEvaluationSource());
6521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasGeometryStage)
6531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			sources << glu::GeometrySource(genGeometrySource());
6541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), sources));
6561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "build program");
6571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
6591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const tcu::ScopedLogSection section(m_testCtx.getLog(), "ShaderProgram", "Shader program");
6601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog() << *m_program;
6611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
6621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (!m_program->isOk())
6641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			throw tcu::TestError("failed to build program");
6651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
6661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_renderTarget == RENDERTARGET_FBO)
6681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
6691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		glu::Texture colorAttachment(m_context.getRenderContext());
6701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindTexture(GL_TEXTURE_2D, *colorAttachment);
6721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, FBO_SIZE, FBO_SIZE);
6731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex");
6741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_fbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
6761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, **m_fbo);
6771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *colorAttachment, 0);
6781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "attach");
6791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// unbind to prevent texture name deletion from removing it from current fbo attachments
6811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
6821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
6831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
6851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		std::vector<tcu::Vec4> data;
6861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		getAttributeData(data);
6881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
6901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
6911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bufferData(GL_ARRAY_BUFFER, (int)(data.size() * sizeof(tcu::Vec4)), &data[0], GL_STATIC_DRAW);
6921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "create vbo");
6931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
6941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
6951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// Iterations
6961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int iterationNdx = 0; iterationNdx < m_numIterations; ++iterationNdx)
6971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_iterationConfigs.push_back(generateConfig(iterationNdx, renderTargetSize));
6981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
6991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid BBoxRenderCase::deinit (void)
7011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
7021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_program.clear();
7031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_vbo.clear();
7041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_fbo.clear();
7051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
7061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryBBoxRenderCase::IterateResult BBoxRenderCase::iterate (void)
7081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
7091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::ScopedLogSection	section		(m_testCtx.getLog(),
7101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry											 std::string() + "Iteration" + de::toString((int)m_iteration),
7111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry											 std::string() + "Iteration " + de::toString((int)m_iteration+1) + "/" + de::toString((int)m_iterationConfigs.size()));
7121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const IterationConfig&		config		= m_iterationConfigs[m_iteration];
7131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// default
7151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_iteration == 0)
7161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	renderTestPattern(config);
7191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	verifyRenderResult(config);
7201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (++m_iteration < (int)m_iterationConfigs.size())
7221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return CONTINUE;
7231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return STOP;
7251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
7261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryBBoxRenderCase::IterationConfig BBoxRenderCase::generateRandomConfig (int seed, const tcu::IVec2& renderTargetSize) const
7281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
7291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random		rnd		(seed);
7301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterationConfig	config;
7311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// viewport config
7331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.viewportSize.x()	= rnd.getInt(MIN_VIEWPORT_SIZE, de::min<int>(renderTargetSize.x(), MAX_VIEWPORT_SIZE));
7341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.viewportSize.y()	= rnd.getInt(MIN_VIEWPORT_SIZE, de::min<int>(renderTargetSize.y(), MAX_VIEWPORT_SIZE));
7351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.viewportPos.x()	= rnd.getInt(0, renderTargetSize.x() - config.viewportSize.x());
7361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.viewportPos.y()	= rnd.getInt(0, renderTargetSize.y() - config.viewportSize.y());
7371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// pattern location inside viewport
7391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.patternSize.x()	= rnd.getFloat(0.4f, 1.4f);
7401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.patternSize.y()	= rnd.getFloat(0.4f, 1.4f);
7411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.patternPos.x()	= rnd.getFloat(-1.0f, 1.0f - config.patternSize.x());
7421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.patternPos.y()	= rnd.getFloat(-1.0f, 1.0f - config.patternSize.y());
7431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// accurate bounding box
7451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.bbox.min			= tcu::Vec4(config.patternPos.x(), config.patternPos.y(), 0.0f, 1.0f);
7461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	config.bbox.max			= tcu::Vec4(config.patternPos.x() + config.patternSize.x(), config.patternPos.y() + config.patternSize.y(), 0.0f, 1.0f);
7471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_bboxSize == BBOXSIZE_LARGER)
7491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
7501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// increase bbox size
7511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.min.x() -= rnd.getFloat() * 0.5f;
7521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.min.y() -= rnd.getFloat() * 0.5f;
7531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.min.z() -= rnd.getFloat() * 0.5f;
7541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.max.x() += rnd.getFloat() * 0.5f;
7561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.max.y() += rnd.getFloat() * 0.5f;
7571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.max.z() += rnd.getFloat() * 0.5f;
7581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
7591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else if (m_bboxSize == BBOXSIZE_SMALLER)
7601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
7611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// reduce bbox size
7621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.min.x() += rnd.getFloat() * 0.4f * config.patternSize.x();
7631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.min.y() += rnd.getFloat() * 0.4f * config.patternSize.y();
7641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.max.x() -= rnd.getFloat() * 0.4f * config.patternSize.x();
7661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		config.bbox.max.y() -= rnd.getFloat() * 0.4f * config.patternSize.y();
7671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
7681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return config;
7701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
7711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrytcu::IVec4 BBoxRenderCase::getViewportPatternArea (const tcu::Vec2& patternPos, const tcu::Vec2& patternSize, const tcu::IVec2& viewportSize, AABBRoundDirection roundDir) const
7731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
7741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const float	halfPixel	= 0.5f;
7751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Vec4	vertexBox;
7761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::IVec4	pixelBox;
7771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7787a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	vertexBox.x() = (patternPos.x() * 0.5f + 0.5f) * (float)viewportSize.x();
7797a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	vertexBox.y() = (patternPos.y() * 0.5f + 0.5f) * (float)viewportSize.y();
7807a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	vertexBox.z() = ((patternPos.x() + patternSize.x()) * 0.5f + 0.5f) * (float)viewportSize.x();
7817a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	vertexBox.w() = ((patternPos.y() + patternSize.y()) * 0.5f + 0.5f) * (float)viewportSize.y();
7821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (roundDir == ROUND_INWARDS)
7841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
7851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pixelBox.x() = (int)deFloatCeil(vertexBox.x()+halfPixel);
7861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pixelBox.y() = (int)deFloatCeil(vertexBox.y()+halfPixel);
7871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pixelBox.z() = (int)deFloatFloor(vertexBox.z()-halfPixel);
7881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pixelBox.w() = (int)deFloatFloor(vertexBox.w()-halfPixel);
7891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
7901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
7911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
7921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pixelBox.x() = (int)deFloatFloor(vertexBox.x()-halfPixel);
7931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pixelBox.y() = (int)deFloatFloor(vertexBox.y()-halfPixel);
7941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pixelBox.z() = (int)deFloatCeil(vertexBox.z()+halfPixel);
7951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pixelBox.w() = (int)deFloatCeil(vertexBox.w()+halfPixel);
7961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
7971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
7981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return pixelBox;
7991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
8001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid BBoxRenderCase::setupRender (const IterationConfig& config)
8021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
8031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
8041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		posLocation			= gl.getAttribLocation(m_program->getProgram(), "a_position");
8051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		colLocation			= gl.getAttribLocation(m_program->getProgram(), "a_color");
8061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		posScaleLocation	= gl.getUniformLocation(m_program->getProgram(), "u_posScale");
8071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(posLocation != -1);
8091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(colLocation != -1);
8101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(posScaleLocation != -1);
8111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
8131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
8141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Setting viewport to ("
8151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "x: " << config.viewportPos.x() << ", "
8161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "y: " << config.viewportPos.y() << ", "
8171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "w: " << config.viewportSize.x() << ", "
8181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "h: " << config.viewportSize.y() << ")\n"
8191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Vertex coordinates are in range:\n"
8201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\tx: [" << config.patternPos.x() << ", " << (config.patternPos.x() + config.patternSize.x()) << "]\n"
8211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\ty: [" << config.patternPos.y() << ", " << (config.patternPos.y() + config.patternSize.y()) << "]\n"
8221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
8231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_calcPerPrimitiveBBox)
8251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
8261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
8271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Setting primitive bounding box to:\n"
8281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\t" << config.bbox.min << "\n"
8291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\t" << config.bbox.max << "\n"
8301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
8311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_useGlobalState)
833485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe		gl.primitiveBoundingBox(config.bbox.min.x(), config.bbox.min.y(), config.bbox.min.z(), config.bbox.min.w(),
834485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe								config.bbox.max.x(), config.bbox.max.y(), config.bbox.max.z(), config.bbox.max.w());
8351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
8361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// state is overriden by the tessellation output, set bbox to invisible area to imitiate dirty state left by application
837485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe		gl.primitiveBoundingBox(-2.0f, -2.0f, 0.0f, 1.0f,
838485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe								-1.7f, -1.7f, 0.0f, 1.0f);
8391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_fbo)
8411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, **m_fbo);
8421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.viewport(config.viewportPos.x(), config.viewportPos.y(), config.viewportSize.x(), config.viewportSize.y());
8441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
8451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clear(GL_COLOR_BUFFER_BIT);
8461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
8481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, (int)(VA_NUM_ATTRIB_VECS * sizeof(float[4])), (const float*)DE_NULL + 4 * VA_POS_VEC_NDX);
8491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.vertexAttribPointer(colLocation, 4, GL_FLOAT, GL_FALSE, (int)(VA_NUM_ATTRIB_VECS * sizeof(float[4])), (const float*)DE_NULL + 4 * VA_COL_VEC_NDX);
8501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enableVertexAttribArray(posLocation);
8511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enableVertexAttribArray(colLocation);
8521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.useProgram(m_program->getProgram());
8531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.uniform4f(posScaleLocation, config.patternPos.x(), config.patternPos.y(), config.patternSize.x(), config.patternSize.y());
8541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
8561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const glw::GLint bboxMinPos = gl.getUniformLocation(m_program->getProgram(), "u_primitiveBBoxMin");
8571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const glw::GLint bboxMaxPos = gl.getUniformLocation(m_program->getProgram(), "u_primitiveBBoxMax");
8581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform4f(bboxMinPos, config.bbox.min.x(), config.bbox.min.y(), config.bbox.min.z(), config.bbox.min.w());
8601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform4f(bboxMaxPos, config.bbox.max.x(), config.bbox.max.y(), config.bbox.max.z(), config.bbox.max.w());
8611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
8621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.uniform2i(gl.getUniformLocation(m_program->getProgram(), "u_viewportPos"), config.viewportPos.x(), config.viewportPos.y());
8641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.uniform2i(gl.getUniformLocation(m_program->getProgram(), "u_viewportSize"), config.viewportSize.x(), config.viewportSize.y());
8651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "setup");
8671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
8681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryconst char* BBoxRenderCase::genShaderFunction (ShaderFunction func) const
8701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
8711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	switch (func)
8721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
8731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		case SHADER_FUNC_MIRROR_X:
8741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return	"vec4 mirrorX(in highp vec4 p)\n"
8751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"{\n"
8761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	highp vec2 patternOffset = u_posScale.xy;\n"
8771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	highp vec2 patternScale = u_posScale.zw;\n"
8781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	highp vec2 patternCenter = patternOffset + patternScale * 0.5;\n"
8791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	return vec4(2.0 * patternCenter.x - p.x, p.y, p.z, p.w);\n"
8801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"}\n";
8811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		case SHADER_FUNC_MIRROR_Y:
8831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return	"vec4 mirrorY(in highp vec4 p)\n"
8841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"{\n"
8851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	highp vec2 patternOffset = u_posScale.xy;\n"
8861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	highp vec2 patternScale = u_posScale.zw;\n"
8871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	highp vec2 patternCenter = patternOffset + patternScale * 0.5;\n"
8881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	return vec4(p.x, 2.0 * patternCenter.y - p.y, p.z, p.w);\n"
8891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"}\n";
8901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
8911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		case SHADER_FUNC_INSIDE_BBOX:
8921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return	"uniform highp ivec2 u_viewportPos;\n"
8931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"uniform highp ivec2 u_viewportSize;\n"
8941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"flat in highp float v_bbox_expansionSize;\n"
8951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"flat in highp vec3 v_bbox_clipMin;\n"
8961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"flat in highp vec3 v_bbox_clipMax;\n"
8971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"\n"
8981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"bool fragmentInsideTheBBox(in highp float depth)\n"
8991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"{\n"
9001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	highp vec4 wc = vec4(floor((v_bbox_clipMin.x * 0.5 + 0.5) * float(u_viewportSize.x) - v_bbox_expansionSize/2.0),\n"
9011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	                     floor((v_bbox_clipMin.y * 0.5 + 0.5) * float(u_viewportSize.y) - v_bbox_expansionSize/2.0),\n"
9021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	                     ceil((v_bbox_clipMax.x * 0.5 + 0.5) * float(u_viewportSize.x) + v_bbox_expansionSize/2.0),\n"
9031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	                     ceil((v_bbox_clipMax.y * 0.5 + 0.5) * float(u_viewportSize.y) + v_bbox_expansionSize/2.0));\n"
9041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	if (gl_FragCoord.x < float(u_viewportPos.x) + wc.x || gl_FragCoord.x > float(u_viewportPos.x) + wc.z ||\n"
9051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	    gl_FragCoord.y < float(u_viewportPos.y) + wc.y || gl_FragCoord.y > float(u_viewportPos.y) + wc.w)\n"
9061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	    return false;\n"
90726e8fabf4c969e2dc11d638225e7bc81c27c46f7Jarkko Pöyry					"	const highp float dEpsilon = 0.001;\n"
90826e8fabf4c969e2dc11d638225e7bc81c27c46f7Jarkko Pöyry					"	if (depth*2.0-1.0 < v_bbox_clipMin.z - dEpsilon || depth*2.0-1.0 > v_bbox_clipMax.z + dEpsilon)\n"
9091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	    return false;\n"
9101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	return true;\n"
9111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"}\n";
9121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		default:
9131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			DE_ASSERT(false);
9141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return "";
9151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
9161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
9171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass GridRenderCase : public BBoxRenderCase
9191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
9201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
9211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					GridRenderCase					(Context& context, const char* name, const char* description, deUint32 flags);
9221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					~GridRenderCase					(void);
9231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
9251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void			init							(void);
9261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string		genVertexSource					(void) const;
9281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string		genFragmentSource				(void) const;
9291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string		genTessellationControlSource	(void) const;
9301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string		genTessellationEvaluationSource	(void) const;
9311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string		genGeometrySource				(void) const;
9321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterationConfig	generateConfig					(int iteration, const tcu::IVec2& renderTargetSize) const;
9341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void			getAttributeData				(std::vector<tcu::Vec4>& data) const;
9351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void			renderTestPattern				(const IterationConfig& config);
9361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void			verifyRenderResult				(const IterationConfig& config);
9371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int		m_gridSize;
9391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
9401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryGridRenderCase::GridRenderCase (Context& context, const char* name, const char* description, deUint32 flags)
9421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: BBoxRenderCase	(context, name, description, 12, flags)
9431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_gridSize		(24)
9441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
9451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
9461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryGridRenderCase::~GridRenderCase (void)
9481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
9491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
9501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid GridRenderCase::init (void)
9521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
9531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
9541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
9551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Rendering yellow-green grid to " << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
9561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Grid cells are in random order, varying grid size and location for each iteration.\n"
9571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated blue channel."
9581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
9591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	BBoxRenderCase::init();
9611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
9621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string GridRenderCase::genVertexSource (void) const
9641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
9651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
9661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
9681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 a_position;\n"
9691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 a_color;\n"
9701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 vtx_color;\n"
9711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
9721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n";
9731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_hasTessellationStage)
9741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
9751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DE_ASSERT(m_useGlobalState);
9761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
9771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"uniform highp vec4 u_primitiveBBoxMax;\n"
9781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"\n"
9791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
9801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
9811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
9821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"\n";
9831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
9841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"void main()\n"
9861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
9871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec2 patternOffset = u_posScale.xy;\n"
9881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec2 patternScale = u_posScale.zw;\n"
9891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
9901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	vtx_color = a_color;\n";
9911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
9921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_hasTessellationStage)
9931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
9941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DE_ASSERT(m_useGlobalState);
9951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
9961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = 0.0;\n"
9971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin =\n"
9981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	    min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMin.w,\n"
9991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	        vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMax.w);\n"
10001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax =\n"
10011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	    min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMin.w,\n"
10021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	        vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMax.w);\n";
10031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
10041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf<<	"}\n";
10061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
10081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
10091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string GridRenderCase::genFragmentSource (void) const
10111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
10121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const char* const	colorInputName = (m_hasGeometryStage) ? ("geo_color") : (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
10131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
10141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
10161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in mediump vec4 " << colorInputName << ";\n"
10171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(location = 0) out mediump vec4 o_color;\n"
10181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
10191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\n"
10201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
10211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
10221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	mediump vec4 baseColor = " << colorInputName << ";\n"
10231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	mediump float blueChannel;\n"
10241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
10251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		blueChannel = 0.0;\n"
10261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	else\n"
10271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		blueChannel = 1.0;\n"
10281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	o_color = vec4(baseColor.r, baseColor.g, blueChannel, baseColor.a);\n"
10291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
10301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
10321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
10331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string GridRenderCase::genTessellationControlSource (void) const
10351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
10361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
10371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
10391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
10401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_primitive_bounding_box : require\n"
10411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(vertices=3) out;\n"
10421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
10431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 vtx_color[];\n"
10441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 tess_ctrl_color[];\n"
10451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp float u_tessellationLevel;\n"
10461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n";
10471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_calcPerPrimitiveBBox)
10491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
10501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
10511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"uniform highp vec4 u_primitiveBBoxMax;\n";
10521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
10531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"patch out highp float vp_bbox_expansionSize;\n"
10551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch out highp vec3 vp_bbox_clipMin;\n"
10561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch out highp vec3 vp_bbox_clipMax;\n";
10571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_calcPerPrimitiveBBox)
10591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
10601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n";
10611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasGeometryStage)
10621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
10631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);
10641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"vec4 transformVec(in highp vec4 p)\n"
10661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"{\n"
10671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	return " << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)")) << ";\n"
10681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"}\n";
10691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
10701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"\n"
10721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
10731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
10741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// convert to nonsensical coordinates, just in case\n"
10751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
10761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
10771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
10781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[0] = u_tessellationLevel;\n"
10791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[1] = u_tessellationLevel;\n"
10801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[2] = u_tessellationLevel;\n"
10811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelInner[0] = u_tessellationLevel;\n";
10821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
10831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_calcPerPrimitiveBBox)
10841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
10851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
10861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMin = min(min(transformVec(gl_in[0].gl_Position),\n"
10871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	                             transformVec(gl_in[1].gl_Position)),\n"
10881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	                         transformVec(gl_in[2].gl_Position));\n"
10891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMax = max(max(transformVec(gl_in[0].gl_Position),\n"
10901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	                             transformVec(gl_in[1].gl_Position)),\n"
10911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	                         transformVec(gl_in[2].gl_Position));\n";
10921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
10931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
10941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
10951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
10961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMin = u_primitiveBBoxMin;\n"
10971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMax = u_primitiveBBoxMax;\n";
10981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
10991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
11001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_useGlobalState)
11011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
11021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[0] = bboxMin;\n"
11031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[1] = bboxMax;\n";
11041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
11051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"	vp_bbox_expansionSize = 0.0;\n"
11061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
11071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                      vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
11081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
11091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                      vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
11101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
11111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
11121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
11131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
11141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
11151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string GridRenderCase::genTessellationEvaluationSource (void) const
11161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
11171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
11181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
11191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
11201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
11211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_gpu_shader5 : require\n"
11221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(triangles) in;\n"
11231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
11241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 tess_ctrl_color[];\n"
11251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 tess_color;\n"
11261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
11271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch in highp float vp_bbox_expansionSize;\n"
11281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch in highp vec3 vp_bbox_clipMin;\n"
11291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch in highp vec3 vp_bbox_clipMax;\n"
11301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
11311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
11321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
11331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
11341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"precise gl_Position;\n"
11351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
11361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_MIRROR_Y)
11371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"void main()\n"
11381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
11391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
11401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = mirrorY(gl_TessCoord.x * gl_in[0].gl_Position.zwyx +\n"
11411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                      gl_TessCoord.y * gl_in[1].gl_Position.zwyx +\n"
11421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                      gl_TessCoord.z * gl_in[2].gl_Position.zwyx);\n"
11431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	tess_color = tess_ctrl_color[0];\n"
11441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = vp_bbox_expansionSize;\n"
11451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin = vp_bbox_clipMin;\n"
11461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax = vp_bbox_clipMax;\n"
11471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
11481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
11491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
11501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
11511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
11521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string GridRenderCase::genGeometrySource (void) const
11531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
11541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const char* const	colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
11551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
11561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
11571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
11581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_geometry_shader : require\n"
11591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(triangles) in;\n"
11601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(max_vertices=9, triangle_strip) out;\n"
11611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
11621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 " << colorInputName << "[3];\n"
11631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 geo_color;\n"
11641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
11651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
11661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat in highp float v_geo_bbox_expansionSize[3];\n"
11671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat in highp vec3 v_geo_bbox_clipMin[3];\n"
11681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat in highp vec3 v_geo_bbox_clipMax[3];\n"
11691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_bbox_clipMin;\n"
11701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_bbox_clipMax;\n"
11711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp float v_bbox_expansionSize;\n"
11721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_MIRROR_X)
11731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\n"
11741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void setVisualizationVaryings()\n"
11751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
11761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_bbox_expansionSize = v_geo_bbox_expansionSize[0];\n"
11771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
11781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
11791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n"
11801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
11811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
11821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
11831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
11841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 p1 = mirrorX(gl_in[1].gl_Position);\n"
11851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 p2 = mirrorX(gl_in[2].gl_Position);\n"
11861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 pCentroid = vec4((p0.xyz + p1.xyz + p2.xyz) / 3.0, 1.0);\n"
11871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 triangleColor = " << colorInputName << "[0];\n"
11881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
11891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = p0; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
11901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = p1; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
11911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
11921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	EndPrimitive();\n"
11931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
11941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = p1; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
11951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = p2; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
11961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
11971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	EndPrimitive();\n"
11981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
11991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = p2; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
12001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = p0; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
12011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
12021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	EndPrimitive();\n"
12031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
12041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
12061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
12071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryGridRenderCase::IterationConfig GridRenderCase::generateConfig (int iteration, const tcu::IVec2& renderTargetSize) const
12091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
12101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return generateRandomConfig(0xDEDEDEu * (deUint32)iteration, renderTargetSize);
12111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
12121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid GridRenderCase::getAttributeData (std::vector<tcu::Vec4>& data) const
12141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
12151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4		green				(0.0f, 1.0f, 0.0f, 1.0f);
12161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4		yellow				(1.0f, 1.0f, 0.0f, 1.0f);
12171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<int>	cellOrder			(m_gridSize * m_gridSize);
12181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random			rnd					(0xDE56789);
12191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// generate grid with cells in random order
12211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
12221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		cellOrder[ndx] = ndx;
12231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	rnd.shuffle(cellOrder.begin(), cellOrder.end());
12241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	data.resize(m_gridSize * m_gridSize * 6 * 2);
12261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
12271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
12281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellNdx		= cellOrder[ndx];
12291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellX		= cellNdx % m_gridSize;
12301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellY		= cellNdx / m_gridSize;
12311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::Vec4&	cellColor	= ((cellX+cellY)%2 == 0) ? (green) : (yellow);
12321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12337a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[(ndx * 6 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+0) / float(m_gridSize), float(cellY+0) / float(m_gridSize), 0.0f, 1.0f);
12341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		data[(ndx * 6 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
12357a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[(ndx * 6 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+1) / float(m_gridSize), float(cellY+1) / float(m_gridSize), 0.0f, 1.0f);
12361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		data[(ndx * 6 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
12377a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[(ndx * 6 + 2) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+0) / float(m_gridSize), float(cellY+1) / float(m_gridSize), 0.0f, 1.0f);
12381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		data[(ndx * 6 + 2) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
12397a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[(ndx * 6 + 3) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+0) / float(m_gridSize), float(cellY+0) / float(m_gridSize), 0.0f, 1.0f);
12401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		data[(ndx * 6 + 3) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
12417a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[(ndx * 6 + 4) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+1) / float(m_gridSize), float(cellY+0) / float(m_gridSize), 0.0f, 1.0f);
12421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		data[(ndx * 6 + 4) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
12437a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[(ndx * 6 + 5) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+1) / float(m_gridSize), float(cellY+1) / float(m_gridSize), 0.0f, 1.0f);
12441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		data[(ndx * 6 + 5) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
12451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
12461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
12471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid GridRenderCase::renderTestPattern (const IterationConfig& config)
12491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
12501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	setupRender(config);
12531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_hasTessellationStage)
12551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
12561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const glw::GLint	tessLevelPos	= gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
12571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const glw::GLfloat	tessLevel		= 2.8f; // will be rounded up
12581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TCU_CHECK(tessLevelPos != -1);
12601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel << tcu::TestLog::EndMessage;
12621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform1f(tessLevelPos, tessLevel);
12641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.patchParameteri(GL_PATCH_VERTICES, 3);
12651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
12661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
12671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog() << tcu::TestLog::Message << "Rendering grid." << tcu::TestLog::EndMessage;
12691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_TRIANGLES), 0, m_gridSize * m_gridSize * 6);
12711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
12721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
12731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid GridRenderCase::verifyRenderResult (const IterationConfig& config)
12751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
12761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
12771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const ProjectedBBox		projectedBBox			= projectBoundingBox(config.bbox);
12781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec4		viewportBBoxArea		= getViewportBoundingBoxArea(projectedBBox, config.viewportSize);
12791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec4		viewportGridOuterArea	= getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_OUTWARDS);
12801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec4		viewportGridInnerArea	= getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_INWARDS);
12811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface			viewportSurface			(config.viewportSize.x(), config.viewportSize.y());
12821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface			errorMask				(config.viewportSize.x(), config.viewportSize.y());
12831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					anyError				= false;
12841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
12851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_calcPerPrimitiveBBox)
12861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
12871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
12881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Projected bounding box: (clip space)\n"
12891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
12901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
12911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
12921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "In viewport coordinates:\n"
12931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
12941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
12951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Verifying render results within the bounding box.\n"
12961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
12971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
12981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
12991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
13001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Verifying render result."
13011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
13021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_fbo)
13041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
13051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(), viewportSurface.getAccess());
13061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::clear(errorMask.getAccess(), tcu::IVec4(0,0,0,255));
13081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = de::max(viewportBBoxArea.y(), 0); y < de::min(viewportBBoxArea.w(), config.viewportSize.y()); ++y)
13101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = de::max(viewportBBoxArea.x(), 0); x < de::min(viewportBBoxArea.z(), config.viewportSize.x()); ++x)
13111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
13121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::RGBA	pixel		= viewportSurface.getPixel(x, y);
13131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool		outsideGrid	= x < viewportGridOuterArea.x() ||
13141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									  y < viewportGridOuterArea.y() ||
13151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									  x > viewportGridOuterArea.z() ||
13161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									  y > viewportGridOuterArea.w();
13171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool		insideGrid	= x > viewportGridInnerArea.x() &&
13181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									  y > viewportGridInnerArea.y() &&
13191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									  x < viewportGridInnerArea.z() &&
13201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									  y < viewportGridInnerArea.w();
13211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		bool			error		= false;
13231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (outsideGrid)
13251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
13261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// expect black
13271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (pixel.getRed() != 0 || pixel.getGreen() != 0 || pixel.getBlue() != 0)
13281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				error = true;
13291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
13301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else if (insideGrid)
13321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
13331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// expect green, yellow or a combination of these
13341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (pixel.getGreen() != 255 || pixel.getBlue() != 0)
13351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				error = true;
13361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
13371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
13381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
13391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// boundary, allow anything
13401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
13411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (error)
13431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
1344c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			errorMask.setPixel(x, y, tcu::RGBA::red());
13451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			anyError = true;
13461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
13471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
13481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (anyError)
13501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
13511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
13521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
13531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image verification failed."
13541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
13551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
13561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
13571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
13581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
13591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
13611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
13621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
136330fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry	{
136430fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry		m_testCtx.getLog()
136530fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::Message
136630fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< "Result image ok."
136730fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndMessage
136830fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
136930fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
137030fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
137130fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry	}
13721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
13731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass LineRenderCase : public BBoxRenderCase
13751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
13761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
13771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
13781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
13791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		LINEFLAG_WIDE = 1u << FLAGBIT_USER_BIT,	//!< use wide lines
13801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
13811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					LineRenderCase					(Context& context, const char* name, const char* description, deUint32 flags);
13831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					~LineRenderCase					(void);
13841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
13861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
13871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
13881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GREEN_COMPONENT_NDX = 1,
13891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BLUE_COMPONENT_NDX = 2,
13901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		SCAN_ROW_COMPONENT_NDX = GREEN_COMPONENT_NDX, // \note: scans are orthogonal to the line
13921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		SCAN_COL_COMPONENT_NDX = BLUE_COMPONENT_NDX,
13931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
13941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
13951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum QueryDirection
13961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
13971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DIRECTION_HORIZONTAL = 0,
13981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DIRECTION_VERTICAL,
13991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
14001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1401f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	enum ScanResult
1402f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	{
1403f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		SCANRESULT_NUM_LINES_OK_BIT		= (1 << 0),
1404f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		SCANRESULT_LINE_WIDTH_OK_BIT	= (1 << 1),
1405f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	};
1406f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry
14071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void				init							(void);
14081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string			genVertexSource					(void) const;
14101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string			genFragmentSource				(void) const;
14111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string			genTessellationControlSource	(void) const;
14121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string			genTessellationEvaluationSource	(void) const;
14131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string			genGeometrySource				(void) const;
14141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterationConfig		generateConfig					(int iteration, const tcu::IVec2& renderTargetSize) const;
14161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void				getAttributeData				(std::vector<tcu::Vec4>& data) const;
14171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void				renderTestPattern				(const IterationConfig& config);
14181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void				verifyRenderResult				(const IterationConfig& config);
14191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::IVec2			getNumberOfLinesRange			(int queryAreaBegin, int queryAreaEnd, float patternStart, float patternSize, int viewportArea, QueryDirection queryDir) const;
1421f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	deUint8				scanRow							(const tcu::ConstPixelBufferAccess& access, int row, int rowBegin, int rowEnd, const tcu::IVec2& numLines, int& floodCounter) const;
1422f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	deUint8				scanColumn						(const tcu::ConstPixelBufferAccess& access, int column, int columnBegin, int columnEnd, const tcu::IVec2& numLines, int& floodCounter) const;
14231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool				checkAreaNumLines				(const tcu::ConstPixelBufferAccess& access, const tcu::IVec4& area, int& floodCounter, int componentNdx, const tcu::IVec2& numLines) const;
14241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::IVec2			getNumMinimaMaxima				(const tcu::ConstPixelBufferAccess& access, int componentNdx) const;
14251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool				checkLineWidths					(const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& floodCounter) const;
14261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void				printLineWidthError				(const tcu::IVec2& pos, int detectedLineWidth, const tcu::IVec2& lineWidthRange, bool isHorizontal, int& floodCounter) const;
14271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int			m_patternSide;
14291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool			m_isWideLineCase;
14301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int			m_wideLineLineWidth;
14311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
14321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryLineRenderCase::LineRenderCase (Context& context, const char* name, const char* description, deUint32 flags)
14341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: BBoxRenderCase		(context, name, description, 12, flags)
14351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_patternSide			(12)
14361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_isWideLineCase		((flags & LINEFLAG_WIDE) != 0)
14371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_wideLineLineWidth	(5)
14381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
14391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
14401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryLineRenderCase::~LineRenderCase (void)
14421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
14431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
14441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid LineRenderCase::init (void)
14461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
14471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
14481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
14491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Rendering line pattern to " << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
14501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Vertical lines are green, horizontal lines blue. Using additive blending.\n"
14511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Line segments are in random order, varying pattern size and location for each iteration.\n"
14521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated red channel."
14531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
14541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_isWideLineCase)
14561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
14571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		glw::GLfloat lineWidthRange[2] = {0.0f, 0.0f};
14581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);
14591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (lineWidthRange[1] < (float)m_wideLineLineWidth)
14611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			throw tcu::NotSupportedError("Test requires line width " + de::toString(m_wideLineLineWidth));
14621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
14631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	BBoxRenderCase::init();
14651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
14661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string LineRenderCase::genVertexSource (void) const
14681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
14691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
14701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
14711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
14721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 a_position;\n"
14731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 a_color;\n"
14741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 vtx_color;\n"
14751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
14761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp float u_lineWidth;\n"
14771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n";
14781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_hasTessellationStage)
14791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
14801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DE_ASSERT(m_useGlobalState);
14811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
14821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"uniform highp vec4 u_primitiveBBoxMax;\n"
14831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"\n"
14841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
14851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
14861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
14871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"\n";
14881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
14891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"void main()\n"
14901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
14911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec2 patternOffset = u_posScale.xy;\n"
14921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec2 patternScale = u_posScale.zw;\n"
14931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
14941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	vtx_color = a_color;\n";
14951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_hasTessellationStage)
14961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
14971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DE_ASSERT(m_useGlobalState);
14981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
14991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = u_lineWidth;\n"
15001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin =\n"
15011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	    min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMin.w,\n"
15021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	        vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMax.w);\n"
15031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax =\n"
15041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	    min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMin.w,\n"
15051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	        vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMax.w);\n";
15061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
15071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"}\n";
15081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
15101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
15111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string LineRenderCase::genFragmentSource (void) const
15131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
15141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const char* const	colorInputName = (m_hasGeometryStage) ? ("geo_color") : (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
15151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
15161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
15181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in mediump vec4 " << colorInputName << ";\n"
15191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(location = 0) out mediump vec4 o_color;\n"
15201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
15211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\n"
15221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
15231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
15241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	mediump vec4 baseColor = " << colorInputName << ";\n"
15251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	mediump float redChannel;\n"
15261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
15271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		redChannel = 0.0;\n"
15281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	else\n"
15291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		redChannel = 1.0;\n"
15301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	o_color = vec4(redChannel, baseColor.g, baseColor.b, baseColor.a);\n"
15311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
15321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
15341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
15351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string LineRenderCase::genTessellationControlSource (void) const
15371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
15381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
15391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
15411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
15421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_primitive_bounding_box : require\n"
15431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(vertices=2) out;"
15441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
15451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 vtx_color[];\n"
15461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 tess_ctrl_color[];\n"
15471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp float u_tessellationLevel;\n"
15481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
15491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp float u_lineWidth;\n";
15501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_calcPerPrimitiveBBox)
15521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
15531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
15541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"uniform highp vec4 u_primitiveBBoxMax;\n";
15551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
15561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"patch out highp float vp_bbox_expansionSize;\n"
15581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch out highp vec3 vp_bbox_clipMin;\n"
15591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch out highp vec3 vp_bbox_clipMax;\n";
15601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_calcPerPrimitiveBBox)
15621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
15631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n";
15641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasGeometryStage)
15651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
15661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);
15671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"vec4 transformVec(in highp vec4 p)\n"
15691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"{\n"
15701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	return " << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)")) << ";\n"
15711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"}\n";
15721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
15731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"\n"
15751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
15761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
15771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// convert to nonsensical coordinates, just in case\n"
15781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
15791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
15801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
15811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[0] = 0.8; // will be rounded up to 1\n"
15821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[1] = u_tessellationLevel;\n";
15831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_calcPerPrimitiveBBox)
15851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
15861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
15871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMin = min(transformVec(gl_in[0].gl_Position),\n"
15881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	                         transformVec(gl_in[1].gl_Position));\n"
15891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMax = max(transformVec(gl_in[0].gl_Position),\n"
15901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	                         transformVec(gl_in[1].gl_Position));\n";
15911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
15921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
15931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
15941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
15951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMin = u_primitiveBBoxMin;\n"
15961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMax = u_primitiveBBoxMax;\n";
15971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
15981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
15991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_useGlobalState)
16001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
16011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[0] = bboxMin;\n"
16021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[1] = bboxMax;\n";
16031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"	vp_bbox_expansionSize = u_lineWidth;\n"
16051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
16061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                      vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
16071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
16081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                      vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
16091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
16101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
16121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
16131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string LineRenderCase::genTessellationEvaluationSource (void) const
16151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
16161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
16171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
16191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
16201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(isolines) in;"
16211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
16221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 tess_ctrl_color[];\n"
16231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 tess_color;\n"
16241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
16251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
16261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch in highp float vp_bbox_expansionSize;\n"
16271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch in highp vec3 vp_bbox_clipMin;\n"
16281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch in highp vec3 vp_bbox_clipMax;\n"
16291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
16301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
16311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
16321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_MIRROR_Y)
16331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"void main()\n"
16341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
16351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
16361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = mirrorY(mix(gl_in[0].gl_Position.zwyx, gl_in[1].gl_Position.zwyx, gl_TessCoord.x));\n"
16371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	tess_color = tess_ctrl_color[0];\n"
16381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = vp_bbox_expansionSize;\n"
16391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin = vp_bbox_clipMin;\n"
16401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax = vp_bbox_clipMax;\n"
16411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
16421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
16441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
16451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string LineRenderCase::genGeometrySource (void) const
16471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
16481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const char* const	colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
16491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
16501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
16521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_geometry_shader : require\n"
16531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(lines) in;\n"
16541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(max_vertices=5, line_strip) out;\n"
16551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
16561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 " << colorInputName << "[2];\n"
16571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 geo_color;\n"
16581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
16591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
16601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
16611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat in highp float v_geo_bbox_expansionSize[2];\n"
16621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat in highp vec3 v_geo_bbox_clipMin[2];\n"
16631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat in highp vec3 v_geo_bbox_clipMax[2];\n"
16641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_bbox_clipMin;\n"
16651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_bbox_clipMax;\n"
16661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp float v_bbox_expansionSize;\n"
16671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_MIRROR_X)
16681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\n"
16691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void setVisualizationVaryings()\n"
16701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
16711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_bbox_expansionSize = v_geo_bbox_expansionSize[0];\n"
16721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
16731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
16741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n"
16751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
16761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
16771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
16781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
16791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 p1 = mirrorX(gl_in[1].gl_Position);\n"
16801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 lineColor = " << colorInputName << "[0];\n"
16811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
16821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// output two separate primitives, just in case\n"
16831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = mix(p0, p1, 0.00); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
16841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = mix(p0, p1, 0.33); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
16851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	EndPrimitive();\n"
16861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
16871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = mix(p0, p1, 0.33); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
16881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = mix(p0, p1, 0.67); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
16891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = mix(p0, p1, 1.00); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
16901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	EndPrimitive();\n"
16911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
16921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
16941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
16951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
16961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryLineRenderCase::IterationConfig LineRenderCase::generateConfig (int iteration, const tcu::IVec2& renderTargetSize) const
16971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
16981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int numMaxAttempts = 128;
16991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// Avoid too narrow viewports, lines could merge together. Require viewport is at least 2.5x the size of the line bodies.
17011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int attemptNdx = 0; attemptNdx < numMaxAttempts; ++attemptNdx)
17021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
17031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const IterationConfig& config = generateRandomConfig((0xDEDEDEu * (deUint32)iteration) ^ (0xABAB13 * attemptNdx), renderTargetSize);
17041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17057a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		if ((float)config.viewportSize.x() * (config.patternSize.x() * 0.5f) > 2.5f * (float)m_patternSide * (float)m_wideLineLineWidth &&
17067a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			(float)config.viewportSize.y() * (config.patternSize.y() * 0.5f) > 2.5f * (float)m_patternSide * (float)m_wideLineLineWidth)
17071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
17081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return config;
17091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
17101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
17111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(false);
17131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return IterationConfig();
17141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
17151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid LineRenderCase::getAttributeData (std::vector<tcu::Vec4>& data) const
17171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
17181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4		green		(0.0f, 1.0f, 0.0f, 1.0f);
17191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4		blue		(0.0f, 0.0f, 1.0f, 1.0f);
17201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<int>	cellOrder	(m_patternSide * m_patternSide * 2);
17211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random			rnd			(0xDE12345);
17221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// generate crosshatch pattern with segments in random order
17241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
17251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		cellOrder[ndx] = ndx;
17261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	rnd.shuffle(cellOrder.begin(), cellOrder.end());
17271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	data.resize(cellOrder.size() * 4);
17291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
17301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
17311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int segmentID		= cellOrder[ndx];
17321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int direction		= segmentID & 0x01;
17331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int majorCoord	= (segmentID >> 1) / m_patternSide;
17341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int minorCoord	= (segmentID >> 1) % m_patternSide;
17351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (direction)
17371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
17387a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(minorCoord) / float(m_patternSide), float(majorCoord) / float(m_patternSide), 0.0f, 1.0f);
17391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
17407a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(minorCoord) / float(m_patternSide), float(majorCoord + 1) / float(m_patternSide), 0.0f, 1.0f);
17411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
17421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
17431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
17441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
17457a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(majorCoord) / float(m_patternSide), float(minorCoord) / float(m_patternSide), 0.0f, 1.0f);
17461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
17477a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(majorCoord + 1) / float(m_patternSide), float(minorCoord) / float(m_patternSide), 0.0f, 1.0f);
17481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
17491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
17501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
17511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
17521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid LineRenderCase::renderTestPattern (const IterationConfig& config)
17541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
17551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
17561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	setupRender(config);
17581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_hasTessellationStage)
17601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
17611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const glw::GLint	tessLevelPos	= gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
17621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const glw::GLfloat	tessLevel		= 2.8f; // will be rounded up
17631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TCU_CHECK(tessLevelPos != -1);
17651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel << tcu::TestLog::EndMessage;
17671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform1f(tessLevelPos, tessLevel);
17691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.patchParameteri(GL_PATCH_VERTICES, 2);
17701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
17711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
17721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_isWideLineCase)
17741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.lineWidth((float)m_wideLineLineWidth);
17751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17767a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	gl.uniform1f(gl.getUniformLocation(m_program->getProgram(), "u_lineWidth"), (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f));
17771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog() << tcu::TestLog::Message << "Rendering pattern." << tcu::TestLog::EndMessage;
17791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enable(GL_BLEND);
17811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.blendFunc(GL_ONE, GL_ONE);
17821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.blendEquation(GL_FUNC_ADD);
17831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_LINES), 0, m_patternSide * m_patternSide * 2 * 2);
17851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
17861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
17871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
17881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid LineRenderCase::verifyRenderResult (const IterationConfig& config)
17891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
17901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
1791f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	const bool				isMsaa					= m_context.getRenderTarget().getNumSamples() > 1;
17921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const ProjectedBBox		projectedBBox			= projectBoundingBox(config.bbox);
17937a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	const float				lineWidth				= (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f);
17941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec4		viewportBBoxArea		= getViewportBoundingBoxArea(projectedBBox, config.viewportSize, lineWidth);
17951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec4		viewportPatternArea		= getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_INWARDS);
17961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2		expectedHorizontalLines	= getNumberOfLinesRange(viewportBBoxArea.y(), viewportBBoxArea.w(), config.patternPos.y(), config.patternSize.y(), config.viewportSize.y(), DIRECTION_VERTICAL);
17971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2		expectedVerticalLines	= getNumberOfLinesRange(viewportBBoxArea.x(), viewportBBoxArea.z(), config.patternPos.x(), config.patternSize.x(), config.viewportSize.x(), DIRECTION_HORIZONTAL);
17981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec4		verificationArea		= tcu::IVec4(de::max(viewportBBoxArea.x(), 0),
17991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																 de::max(viewportBBoxArea.y(), 0),
18001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																 de::min(viewportBBoxArea.z(), config.viewportSize.x()),
18011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																 de::min(viewportBBoxArea.w(), config.viewportSize.y()));
18021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
18031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface			viewportSurface			(config.viewportSize.x(), config.viewportSize.y());
18041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					anyError				= false;
1805f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	bool					msaaRelaxationRequired	= false;
18061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int						messageLimitCounter		= 8;
18071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
18081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_calcPerPrimitiveBBox)
18091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
18101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
18111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Projected bounding box: (clip space)\n"
18121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
18131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
18141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
18151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "In viewport coordinates:\n"
18161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
18171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
18181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Verifying render results within the bounding box:\n"
18191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
18201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
18211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
18221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
18231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Verifying render result:"
18241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
18251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
18261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
18271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
18281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\tCalculating number of horizontal and vertical lines within the bounding box, expecting:\n"
18291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\t[" << expectedHorizontalLines.x() << ", " << expectedHorizontalLines.y() << "] horizontal lines.\n"
18301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\t[" << expectedVerticalLines.x() << ", " << expectedVerticalLines.y() << "] vertical lines.\n"
18311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
18321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
18331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_fbo)
18341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
18351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(), viewportSurface.getAccess());
18361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
18371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// scan rows
18381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = de::max(verificationArea.y(), viewportPatternArea.y()); y < de::min(verificationArea.w(), viewportPatternArea.w()); ++y)
1839f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	{
184025ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry		const deUint8 result = scanRow(viewportSurface.getAccess(),
184125ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry									   y,
184225ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry									   verificationArea.x(),
184325ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry									   verificationArea.z(),
184425ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry									   expectedVerticalLines,
184525ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry									   messageLimitCounter);
1846f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry
1847f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		if ((result & SCANRESULT_NUM_LINES_OK_BIT) == 0)
1848f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			anyError = true;
1849f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		else if ((result & SCANRESULT_LINE_WIDTH_OK_BIT) == 0)
1850f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		{
1851f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			if (m_isWideLineCase && isMsaa)
1852f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			{
1853f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry				// multisampled wide lines might not be supported
1854f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry				msaaRelaxationRequired = true;
1855f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			}
1856f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			else
1857f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry				anyError = true;
1858f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		}
1859f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	}
18601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
18611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// scan columns
18621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = de::max(verificationArea.x(), viewportPatternArea.x()); x < de::min(verificationArea.z(), viewportPatternArea.z()); ++x)
1863f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	{
186425ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry		const deUint8 result = scanColumn(viewportSurface.getAccess(),
186525ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry										  x,
186625ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry										  verificationArea.y(),
186725ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry										  verificationArea.w(),
186825ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry										  expectedHorizontalLines,
186925ed53b938fad9545a74fbebc3b7eaf7136852faJarkko Pöyry										  messageLimitCounter);
1870f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry
1871f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		if ((result & SCANRESULT_NUM_LINES_OK_BIT) == 0)
1872f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			anyError = true;
1873f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		else if ((result & SCANRESULT_LINE_WIDTH_OK_BIT) == 0)
1874f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		{
1875f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			if (m_isWideLineCase && isMsaa)
1876f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			{
1877f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry				// multisampled wide lines might not be supported
1878f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry				msaaRelaxationRequired = true;
1879f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			}
1880f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			else
1881f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry				anyError = true;
1882f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		}
1883f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	}
18841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1885f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry	if (anyError || msaaRelaxationRequired)
18861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
18871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (messageLimitCounter < 0)
18881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (-messageLimitCounter) << " row/column error descriptions." << tcu::TestLog::EndMessage;
18891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
18901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
18911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
18921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image verification failed."
18931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
18941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
18951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
18961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
18971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1898f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		if (anyError)
1899f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
1900f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		else
1901f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		{
1902f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			// MSAA wide lines are optional
1903f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry			m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Multisampled wide line verification failed");
1904f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry		}
19051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
19061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
190730fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry	{
190830fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry		m_testCtx.getLog()
190930fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::Message
191030fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< "Result image ok."
191130fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndMessage
191230fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
191330fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
191430fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
191530fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry	}
19161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
19171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrytcu::IVec2 LineRenderCase::getNumberOfLinesRange (int queryAreaBegin, int queryAreaEnd, float patternStart, float patternSize, int viewportArea, QueryDirection queryDir) const
19191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
19201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// pattern is not symmetric due to mirroring
19211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int	patternStartNdx	= (queryDir == DIRECTION_HORIZONTAL) ? ((m_hasGeometryStage) ? (1) : (0)) : ((m_hasTessellationStage) ? (1) : (0));
19221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int	patternEndNdx	= patternStartNdx + m_patternSide;
19231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int			numLinesMin		= 0;
19251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int			numLinesMax		= 0;
19261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int lineNdx = patternStartNdx; lineNdx < patternEndNdx; ++lineNdx)
19281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
19297a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		const float linePos		= (patternStart + (float(lineNdx) / float(m_patternSide)) * patternSize) * 0.5f + 0.5f;
19307a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		const float lineWidth	= (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f);
19311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19327a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		if (linePos * (float)viewportArea > (float)queryAreaBegin + 1.0f &&
19337a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			linePos * (float)viewportArea < (float)queryAreaEnd   - 1.0f)
19341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
19351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// line center is within the area
19361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			++numLinesMin;
19371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			++numLinesMax;
19381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
19397a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		else if (linePos * (float)viewportArea > (float)queryAreaBegin - lineWidth*0.5f - 1.0f &&
19407a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		         linePos * (float)viewportArea < (float)queryAreaEnd   + lineWidth*0.5f + 1.0f)
19411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
19421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// line could leak into area
19431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			++numLinesMax;
19441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
19451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
19461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return tcu::IVec2(numLinesMin, numLinesMax);
19481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
19491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1950f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko PöyrydeUint8 LineRenderCase::scanRow (const tcu::ConstPixelBufferAccess& access, int row, int rowBegin, int rowEnd, const tcu::IVec2& numLines, int& messageLimitCounter) const
19511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
19521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool numLinesOk	= checkAreaNumLines(access, tcu::IVec4(rowBegin, row, rowEnd - rowBegin, 1), messageLimitCounter, SCAN_ROW_COMPONENT_NDX, numLines);
19531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool lineWidthOk	= checkLineWidths(access, tcu::IVec2(rowBegin, row), tcu::IVec2(rowEnd, row), SCAN_ROW_COMPONENT_NDX, messageLimitCounter);
1954f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry
19557a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	return	(deUint8)((numLinesOk	? (deUint8)SCANRESULT_NUM_LINES_OK_BIT	: 0u) |
19567a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry					  (lineWidthOk	? (deUint8)SCANRESULT_LINE_WIDTH_OK_BIT	: 0u));
19571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
19581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
1959f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko PöyrydeUint8 LineRenderCase::scanColumn (const tcu::ConstPixelBufferAccess& access, int column, int columnBegin, int columnEnd, const tcu::IVec2& numLines, int& messageLimitCounter) const
19601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
19611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool numLinesOk	= checkAreaNumLines(access, tcu::IVec4(column, columnBegin, 1, columnEnd - columnBegin), messageLimitCounter, SCAN_COL_COMPONENT_NDX, numLines);
19621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool lineWidthOk	= checkLineWidths(access, tcu::IVec2(column, columnBegin), tcu::IVec2(column, columnEnd), SCAN_COL_COMPONENT_NDX, messageLimitCounter);
1963f0ca13a370eeeff83ecf3c4d76a13d51dabf4297Jarkko Pöyry
19647a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	return	(deUint8)((numLinesOk	? (deUint8)SCANRESULT_NUM_LINES_OK_BIT	: 0u) |
19657a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry					  (lineWidthOk	? (deUint8)SCANRESULT_LINE_WIDTH_OK_BIT	: 0u));
19661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
19671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool LineRenderCase::checkAreaNumLines (const tcu::ConstPixelBufferAccess& access, const tcu::IVec4& area, int& messageLimitCounter, int componentNdx, const tcu::IVec2& numLines) const
19691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
19701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// Num maxima == num lines
19711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::ConstPixelBufferAccess	subAccess		= tcu::getSubregion(access, area.x(), area.y(), 0, area.z(), area.w(), 1);
19721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2					numMinimaMaxima	= getNumMinimaMaxima(subAccess, componentNdx);
19731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int							numMaxima		= numMinimaMaxima.y();
19741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// In valid range
19761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (numMaxima >= numLines.x() && numMaxima <= numLines.y())
19771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return true;
19781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (--messageLimitCounter < 0)
19801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return false;
19811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (area.z() == 1)
19831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
19841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
19851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "On column " << area.x() << ", y: [" << area.y() << "," << (area.y()+area.w()) << "):\n"
19861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tExpected [" << numLines.x() << ", " << numLines.y() << "] lines but the number of lines in the area is " << numMaxima
19871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
19881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
19891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
19901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
19911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "On row " << area.y() << ", x: [" << area.x() << "," << (area.x()+area.z()) << "):\n"
19921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tExpected [" << numLines.x() << ", " << numLines.y() << "] lines but the number of lines in the area is " << numMaxima
19931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
19941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return false;
19961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
19971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
19981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrytcu::IVec2 LineRenderCase::getNumMinimaMaxima (const tcu::ConstPixelBufferAccess& access, int componentNdx) const
19991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
20001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(access.getWidth() == 1 || access.getHeight() == 1);
20011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int previousValue	= -1;
20031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int previousSign	= 0;
20041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int numMinima		= 0;
20051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int numMaxima		= 0;
20061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = 0; y < access.getHeight(); ++y)
20081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = 0; x < access.getWidth(); ++x)
20091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
20101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int componentValue = access.getPixelInt(x, y)[componentNdx];
20111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (previousValue != -1)
20131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
20141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const int sign = (componentValue > previousValue) ? (+1) : (componentValue < previousValue) ? (-1) : (0);
20151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// local minima/maxima in sign changes (zero signless)
20171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (sign != 0 && sign == -previousSign)
20181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
20191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				previousSign = sign;
20201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (sign > 0)
20221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					++numMinima;
20231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				else
20241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					++numMaxima;
20251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
20261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			else if (sign != 0 && previousSign == 0)
20271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
20281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				previousSign = sign;
20291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				// local extreme at the start boundary
20311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (sign > 0)
20321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					++numMinima;
20331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				else
20341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					++numMaxima;
20351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
20361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
20371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		previousValue = componentValue;
20391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
20401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// local extreme at the end boundary
20421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (previousSign > 0)
20431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		++numMaxima;
20441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else if (previousSign < 0)
20451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		++numMinima;
20461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
20471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
20481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		++numMaxima;
20491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		++numMinima;
20501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
20511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return tcu::IVec2(numMinima, numMaxima);
20531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
20541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool LineRenderCase::checkLineWidths (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& messageLimitCounter) const
20561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
20571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool			multisample		= m_context.getRenderTarget().getNumSamples() > 1;
20587d6ad9e003b52cfc23626b216b7580babf423c8fPyry Haulos	const int			lineRenderWidth	= (m_isWideLineCase) ? (m_wideLineLineWidth) : 1;
20591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2	lineWidthRange	= (multisample)
20601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry											? (tcu::IVec2(lineRenderWidth, lineRenderWidth+1))	// multisampled "smooth" lines may spread to neighboring pixel
20611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry											: (tcu::IVec2(lineRenderWidth, lineRenderWidth));
20621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int					lineWidth		= 0;
20641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool				bboxLimitedLine	= false;
20651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool				anyError		= false;
20661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2	advance			= (begin.x() == end.x()) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));
20681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// fragments before begin?
20701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (access.getPixelInt(begin.x(), begin.y())[componentNdx] != 0)
20711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
20721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		bboxLimitedLine = true;
20731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (tcu::IVec2 cursor = begin - advance;; cursor -= advance)
20751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
20761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (cursor.x() < 0 || cursor.y() < 0)
20771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
20781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				break;
20791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
20801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			else if (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0)
20811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
20821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				++lineWidth;
20831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
20841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			else
20851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				break;
20861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
20871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
20881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (tcu::IVec2 cursor = begin; cursor != end; cursor += advance)
20901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
20911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool hit = (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0);
20921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
20931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (hit)
20941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			++lineWidth;
20951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else if (lineWidth)
20961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
20971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// Line is allowed to be be thinner if it borders the bbox boundary (since part of the line might have been discarded).
20981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const bool incorrectLineWidth = (lineWidth < lineWidthRange.x() && !bboxLimitedLine) || (lineWidth > lineWidthRange.y());
20991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (incorrectLineWidth)
21011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
21021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				anyError = true;
21031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
21041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
21051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			lineWidth = 0;
21071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxLimitedLine = false;
21081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
21091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
21101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// fragments after end?
21121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (lineWidth)
21131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
21141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (tcu::IVec2 cursor = end;; cursor += advance)
21151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
21161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (cursor.x() >= access.getWidth() || cursor.y() >= access.getHeight())
21171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
21181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (lineWidth > lineWidthRange.y())
21191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
21201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					anyError = true;
21211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
21221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
21231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				break;
21251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
21261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			else if (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0)
21271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
21281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				++lineWidth;
21291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
21301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			else if (lineWidth)
21311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
21321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				// only check that line width is not larger than expected. Line width may be smaller
21331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				// since the scanning 'cursor' is now outside the bounding box.
21341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const bool incorrectLineWidth = (lineWidth > lineWidthRange.y());
21351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (incorrectLineWidth)
21371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
21381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					anyError = true;
21391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
21401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
21411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				lineWidth = 0;
21431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
21441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
21451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
21461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return !anyError;
21481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
21491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid LineRenderCase::printLineWidthError (const tcu::IVec2& pos, int detectedLineWidth, const tcu::IVec2& lineWidthRange, bool isHorizontal, int& messageLimitCounter) const
21511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
21521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (--messageLimitCounter < 0)
21531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return;
21541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
21561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
21571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Found incorrect line width near " << pos << ": (" << ((isHorizontal) ? ("horizontal") : ("vertical")) << " line)\n"
21581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\tExpected line width in range [" << lineWidthRange.x() << ", " << lineWidthRange.y() << "] but found " << detectedLineWidth
21591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
21601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
21611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass PointRenderCase : public BBoxRenderCase
21631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
21641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
21651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
21661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
21671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		POINTFLAG_WIDE = 1u << FLAGBIT_USER_BIT,	//!< use wide points
21681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
21691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	struct GeneratedPoint
21701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
21711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec2	center;
21721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		int			size;
21731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		bool		even;
21741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
21751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							PointRenderCase					(Context& context, const char* name, const char* description, deUint32 flags);
21771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							~PointRenderCase				(void);
21781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
21801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum ResultPointType
21811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
21821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		POINT_FULL = 0,
21831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		POINT_PARTIAL
21841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
21851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void					init							(void);
21871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void					deinit							(void);
21881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string				genVertexSource					(void) const;
21901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string				genFragmentSource				(void) const;
21911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string				genTessellationControlSource	(void) const;
21921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string				genTessellationEvaluationSource	(void) const;
21931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string				genGeometrySource				(void) const;
21941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
21951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterationConfig			generateConfig					(int iteration, const tcu::IVec2& renderTargetSize) const;
21961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void					generateAttributeData			(void);
21971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void					getAttributeData				(std::vector<tcu::Vec4>& data) const;
21981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void					renderTestPattern				(const IterationConfig& config);
21991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void					verifyRenderResult				(const IterationConfig& config);
22001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void					genReferencePointData			(const IterationConfig& config, std::vector<GeneratedPoint>& data) const;
22021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					verifyNarrowPointPattern		(const tcu::Surface& viewport, const std::vector<GeneratedPoint>& refPoints, const ProjectedBBox& bbox, int& logFloodCounter);
22031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					verifyWidePointPattern			(const tcu::Surface& viewport, const std::vector<GeneratedPoint>& refPoints, const ProjectedBBox& bbox, int& logFloodCounter);
22041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					verifyWidePoint					(const tcu::Surface& viewport, const GeneratedPoint& refPoint, const ProjectedBBox& bbox, ResultPointType pointType, int& logFloodCounter);
22051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					verifyWidePointAt				(const tcu::IVec2& pointPos, const tcu::Surface& viewport, const GeneratedPoint& refPoint, const tcu::IVec4& bbox, ResultPointType pointType, int componentNdx, int& logFloodCounter);
22061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::IVec2				scanPointWidthAt				(const tcu::IVec2& pointPos, const tcu::Surface& viewport, int expectedPointSize, int componentNdx) const;
22071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int				m_numStripes;
22091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool				m_isWidePointCase;
22101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<tcu::Vec4>	m_attribData;
22111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
22121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryPointRenderCase::PointRenderCase (Context& context, const char* name, const char* description, deUint32 flags)
22141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: BBoxRenderCase	(context, name, description, 12, flags)
22151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_numStripes		(4)
22161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_isWidePointCase	((flags & POINTFLAG_WIDE) != 0)
22171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
22181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
22191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryPointRenderCase::~PointRenderCase (void)
22211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
22221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
22231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid PointRenderCase::init (void)
22251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
22261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_isWidePointCase)
22271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
22281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// extensions
22291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasGeometryStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_point_size"))
22301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			throw tcu::NotSupportedError("Test requires GL_EXT_geometry_point_size extension");
22311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasTessellationStage && !m_hasGeometryStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_point_size"))
22321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_point_size extension");
22331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// point size range
22351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
22361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			glw::GLfloat pointSizeRange[2] = {0.0f, 0.0f};
22371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
22381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (pointSizeRange[1] < 5.0f)
22401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				throw tcu::NotSupportedError("Test requires point size 5.0");
22411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
22421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
22431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
22451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
22461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Rendering point pattern to " << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
22471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Half of the points are green, half blue. Using additive blending.\n"
22481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Points are in random order, varying pattern size and location for each iteration.\n"
22491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated red channel."
22501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
22511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	generateAttributeData();
22531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	BBoxRenderCase::init();
22551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
22561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid PointRenderCase::deinit (void)
22581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
22591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// clear data
22601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_attribData = std::vector<tcu::Vec4>();
22611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// deinit parent
22631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	BBoxRenderCase::deinit();
22641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
22651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string PointRenderCase::genVertexSource (void) const
22671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
22681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
22691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
22711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 a_position;\n"
22721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 a_color;\n"
22731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 vtx_color;\n"
22741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
22751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n";
22761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_hasTessellationStage)
22771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
22781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DE_ASSERT(m_useGlobalState);
22791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
22801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"uniform highp vec4 u_primitiveBBoxMax;\n"
22811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"\n"
22821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
22831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
22841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
22851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"\n";
22861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
22871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"void main()\n"
22891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
22901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec2 patternOffset = u_posScale.xy;\n"
22911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec2 patternScale = u_posScale.zw;\n"
22921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp float pointSize = "
22931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< ((m_isWidePointCase && !m_hasTessellationStage && !m_hasGeometryStage) ? ("(a_color.g > 0.0) ? (5.0) : (3.0)") : ("1.0"))
22941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< ";\n"
22951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"	gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
22961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_PointSize = pointSize;\n"
22971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	vtx_color = a_color;\n";
22981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
22991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_hasTessellationStage)
23001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
23011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DE_ASSERT(m_useGlobalState);
23021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
23031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = pointSize;\n"
23041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin =\n"
23051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	    min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMin.w,\n"
23061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	        vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMax.w);\n"
23071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax =\n"
23081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	    min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMin.w,\n"
23091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	        vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMax.w);\n";
23101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
23111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"}\n";
23131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
23141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
23151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string PointRenderCase::genFragmentSource (void) const
23171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
23181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const char* const	colorInputName = (m_hasGeometryStage) ? ("geo_color") : (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
23191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
23201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
23221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in mediump vec4 " << colorInputName << ";\n"
23231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(location = 0) out mediump vec4 o_color;\n"
23241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
23251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\n"
23261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
23271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
23281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	mediump vec4 baseColor = " << colorInputName << ";\n"
23291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	mediump float redChannel;\n"
23301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
23311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		redChannel = 0.0;\n"
23321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	else\n"
23331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		redChannel = 1.0;\n"
23341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	o_color = vec4(redChannel, baseColor.g, baseColor.b, baseColor.a);\n"
23351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
23361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
23381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
23391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string PointRenderCase::genTessellationControlSource (void) const
23411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
23421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool			tessellationWidePoints = (m_isWidePointCase) && (!m_hasGeometryStage);
23431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
23441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
23461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
23471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_primitive_bounding_box : require\n"
23481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	((tessellationWidePoints) ? ("#extension GL_EXT_tessellation_point_size : require\n") : (""))
23491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"layout(vertices=1) out;"
23501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
23511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 vtx_color[];\n"
23521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 tess_ctrl_color[];\n"
23531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp float u_tessellationLevel;\n"
23541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n";
23551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_calcPerPrimitiveBBox)
23571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
23581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
23591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"uniform highp vec4 u_primitiveBBoxMax;\n";
23601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
23611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"patch out highp vec3 vp_bbox_clipMin;\n"
23631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch out highp vec3 vp_bbox_clipMax;\n";
23641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_calcPerPrimitiveBBox)
23661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
23671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n";
23681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasGeometryStage)
23691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
23701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);
23711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"vec4 transformVec(in highp vec4 p)\n"
23731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"{\n"
23741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	return " << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)")) << ";\n"
23751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"}\n";
23761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
23771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"\n"
23791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
23801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
23811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// convert to nonsensical coordinates, just in case\n"
23821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
23831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
23841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
23851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[0] = u_tessellationLevel;\n"
23861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[1] = u_tessellationLevel;\n"
23871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[2] = u_tessellationLevel;\n"
23881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[3] = u_tessellationLevel;\n"
23891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelInner[0] = 0.8; // will be rounded up to 1\n"
23901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelInner[1] = 0.8; // will be rounded up to 1\n";
23911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_calcPerPrimitiveBBox)
23931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
23941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n";
23951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
23961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasGeometryStage)
23971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			buf <<	"	const vec2 minExpansion = vec2(0.07 + 0.05, 0.07 + 0.02); // eval and geometry shader\n"
23981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	const vec2 maxExpansion = vec2(0.07 + 0.05, 0.07 + 0.03); // eval and geometry shader\n";
23991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
24001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			buf <<	"	const vec2 minExpansion = vec2(0.07, 0.07); // eval shader\n"
24011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					"	const vec2 maxExpansion = vec2(0.07, 0.07); // eval shader\n";
24021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"	highp vec2 patternScale = u_posScale.zw;\n"
24041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMin = transformVec(gl_in[0].gl_Position) - vec4(minExpansion * patternScale, 0.0, 0.0);\n"
24051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMax = transformVec(gl_in[0].gl_Position) + vec4(maxExpansion * patternScale, 0.0, 0.0);\n";
24061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
24071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
24081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
24091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
24101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMin = u_primitiveBBoxMin;\n"
24111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp vec4 bboxMax = u_primitiveBBoxMax;\n";
24121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
24131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_useGlobalState)
24141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
24151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[0] = bboxMin;\n"
24161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[1] = bboxMax;\n";
24171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"	vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
24191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                      vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
24201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
24211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                      vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
24221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
24231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
24251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
24261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string PointRenderCase::genTessellationEvaluationSource (void) const
24281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
24291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool			tessellationWidePoints = (m_isWidePointCase) && (!m_hasGeometryStage);
24301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
24311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
24331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
24341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	((tessellationWidePoints) ? ("#extension GL_EXT_tessellation_point_size : require\n") : (""))
24351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"layout(quads, point_mode) in;"
24361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
24371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 tess_ctrl_color[];\n"
24381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 tess_color;\n"
24391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
24401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
24411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch in highp vec3 vp_bbox_clipMin;\n"
24421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"patch in highp vec3 vp_bbox_clipMax;\n"
24431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	((!m_hasGeometryStage) ? ("flat out highp float v_bbox_expansionSize;\n") : (""))
24441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
24451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
24461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
24471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_MIRROR_Y)
24481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"void main()\n"
24491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
24501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
24511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec2 patternScale = u_posScale.zw;\n"
24521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 offset = vec4((gl_TessCoord.xy * 2.0 - vec2(1.0)) * 0.07 * patternScale, 0.0, 0.0);\n"
24531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp float pointSize = " << ((tessellationWidePoints) ? ("(tess_ctrl_color[0].g > 0.0) ? (5.0) : (3.0)") : ("1.0")) << ";\n"
24541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_Position = mirrorY(gl_in[0].gl_Position.zwyx + offset);\n";
24551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (tessellationWidePoints)
24571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << "	gl_PointSize = pointSize;\n";
24581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"	tess_color = tess_ctrl_color[0];\n"
24601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	((!m_hasGeometryStage) ? ("v_bbox_expansionSize = pointSize;\n") : (""))
24611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin = vp_bbox_clipMin;\n"
24621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax = vp_bbox_clipMax;\n"
24631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
24641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
24661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
24671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string PointRenderCase::genGeometrySource (void) const
24691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
24701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const char* const	colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
24711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
24721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
24731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
24741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_geometry_shader : require\n"
24751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	((m_isWidePointCase) ? ("#extension GL_EXT_geometry_point_size : require\n") : (""))
24761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"layout(points) in;\n"
24771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(max_vertices=3, points) out;\n"
24781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
24791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 " << colorInputName << "[1];\n"
24801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 geo_color;\n"
24811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_posScale;\n"
24821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
24831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat in highp vec3 v_geo_bbox_clipMin[1];\n"
24841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat in highp vec3 v_geo_bbox_clipMax[1];\n"
24851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_bbox_clipMin;\n"
24861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp vec3 v_bbox_clipMax;\n"
24871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"flat out highp float v_bbox_expansionSize;\n"
24881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
24891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	genShaderFunction(SHADER_FUNC_MIRROR_X)
24901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\n"
24911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
24921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
24931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
24941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
24951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 pointColor = " << colorInputName << "[0];\n"
24961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec2 patternScale = u_posScale.zw;\n"
24971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp float pointSize = "
24981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< (m_isWidePointCase ? ("(pointColor.g > 0.0) ? (5.0) : (3.0)") : ("1.0"))
24991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< ";\n"
25001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
25011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 offsets[3] =\n"
2502cdde9ab50faadb94feeb12eeaf26195af1d0bc67Jarkko Pöyry			"		vec4[3](\n"
2503cdde9ab50faadb94feeb12eeaf26195af1d0bc67Jarkko Pöyry			"			vec4( 0.05 * patternScale.x, 0.03 * patternScale.y, 0.0, 0.0),\n"
2504cdde9ab50faadb94feeb12eeaf26195af1d0bc67Jarkko Pöyry			"			vec4(-0.01 * patternScale.x,-0.02 * patternScale.y, 0.0, 0.0),\n"
2505cdde9ab50faadb94feeb12eeaf26195af1d0bc67Jarkko Pöyry			"			vec4(-0.05 * patternScale.x, 0.02 * patternScale.y, 0.0, 0.0)\n"
2506cdde9ab50faadb94feeb12eeaf26195af1d0bc67Jarkko Pöyry			"		);\n"
25071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	for (int ndx = 0; ndx < 3; ++ndx)\n"
25081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	{\n"
25091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		gl_Position = p0 + offsets[ndx];\n";
25101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_isWidePointCase)
25121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"		gl_PointSize = pointSize;\n";
25131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"		v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
25151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
25161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		v_bbox_expansionSize = pointSize;\n"
25171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		geo_color = pointColor;\n"
25181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"		EmitVertex();\n"
25191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	}\n"
25201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
25211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
25231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
25241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryPointRenderCase::IterationConfig PointRenderCase::generateConfig (int iteration, const tcu::IVec2& renderTargetSize) const
25261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
25271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterationConfig config = generateRandomConfig(0xDEDEDEu * (deUint32)iteration, renderTargetSize);
25281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// equal or larger -> expand according to shader expansion
25301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_bboxSize == BBOXSIZE_EQUAL || m_bboxSize == BBOXSIZE_LARGER)
25311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
25321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::Vec2 patternScale = config.patternSize;
25331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasTessellationStage)
25351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
25361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			config.bbox.min -= tcu::Vec4(0.07f * patternScale.x(), 0.07f * patternScale.y(), 0.0f, 0.0f);
25371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			config.bbox.max += tcu::Vec4(0.07f * patternScale.x(), 0.07f * patternScale.y(), 0.0f, 0.0f);
25381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
25391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_hasGeometryStage)
25401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
25411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			config.bbox.min -= tcu::Vec4(0.05f * patternScale.x(), 0.02f * patternScale.y(), 0.0f, 0.0f);
25421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			config.bbox.max += tcu::Vec4(0.05f * patternScale.x(), 0.03f * patternScale.y(), 0.0f, 0.0f);
25431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
25441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
25451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return config;
25471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
25481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid PointRenderCase::generateAttributeData (void)
25501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
25511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4		green		(0.0f, 1.0f, 0.0f, 1.0f);
25521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4		blue		(0.0f, 0.0f, 1.0f, 1.0f);
25531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<int>	cellOrder	(m_numStripes * m_numStripes * 2);
25541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random			rnd			(0xDE22446);
25551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
25571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		cellOrder[ndx] = ndx;
25581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	rnd.shuffle(cellOrder.begin(), cellOrder.end());
25591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_attribData.resize(cellOrder.size() * 2);
25611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
25621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
25631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int pointID		= cellOrder[ndx];
25641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int direction		= pointID & 0x01;
25651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int majorCoord	= (pointID >> 1) / m_numStripes;
25661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int minorCoord	= (pointID >> 1) % m_numStripes;
25671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (direction)
25691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
25707a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(minorCoord) / float(m_numStripes), float(majorCoord) / float(m_numStripes), 0.0f, 1.0f);
25711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
25721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
25731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
25741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
25757a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(((float)majorCoord + 0.5f) / float(m_numStripes), ((float)minorCoord + 0.5f) / float(m_numStripes), 0.0f, 1.0f);
25761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
25771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
25781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
25791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
25801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid PointRenderCase::getAttributeData (std::vector<tcu::Vec4>& data) const
25821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
25831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	data = m_attribData;
25841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
25851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid PointRenderCase::renderTestPattern (const IterationConfig& config)
25871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
25881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
25891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	setupRender(config);
25911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_hasTessellationStage)
25931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
25941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const glw::GLint	tessLevelPos	= gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
25951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const glw::GLfloat	tessLevel		= 0.8f; // will be rounded up
25961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TCU_CHECK(tessLevelPos != -1);
25981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
25991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel << tcu::TestLog::EndMessage;
26001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform1f(tessLevelPos, tessLevel);
26021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.patchParameteri(GL_PATCH_VERTICES, 1);
26031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
26041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
26051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog() << tcu::TestLog::Message << "Rendering pattern." << tcu::TestLog::EndMessage;
26071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enable(GL_BLEND);
26091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.blendFunc(GL_ONE, GL_ONE);
26101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.blendEquation(GL_FUNC_ADD);
26111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_POINTS), 0, m_numStripes * m_numStripes * 2);
26131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
26141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
26151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid PointRenderCase::verifyRenderResult (const IterationConfig& config)
26171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
26181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&		gl						= m_context.getRenderContext().getFunctions();
26191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const ProjectedBBox			projectedBBox			= projectBoundingBox(config.bbox);
26201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec4			viewportBBoxArea		= getViewportBoundingBoxArea(projectedBBox, config.viewportSize);
26211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface				viewportSurface			(config.viewportSize.x(), config.viewportSize.y());
26231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int							logFloodCounter			= 8;
26241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool						anyError;
26251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<GeneratedPoint>	refPoints;
26261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_calcPerPrimitiveBBox)
26281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
26291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
26301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Projected bounding box: (clip space)\n"
26311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
26321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
26331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
26341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "In viewport coordinates:\n"
26351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
26361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
26371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Verifying render results within the bounding box:\n"
26381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
26391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
26401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
26411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
26421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Verifying render result:"
26431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
26441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_fbo)
26461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
26471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(), viewportSurface.getAccess());
26481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	genReferencePointData(config, refPoints);
26501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_isWidePointCase)
26521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		anyError = verifyWidePointPattern(viewportSurface, refPoints, projectedBBox, logFloodCounter);
26531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
26541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		anyError = verifyNarrowPointPattern(viewportSurface, refPoints, projectedBBox, logFloodCounter);
26551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (anyError)
26571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
26581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (logFloodCounter < 0)
26591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (-logFloodCounter) << " error descriptions." << tcu::TestLog::EndMessage;
26601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
26621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
26631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image verification failed."
26641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
26651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
26661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
26671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
26681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
26701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
26711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
267230fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry	{
267330fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry		m_testCtx.getLog()
267430fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::Message
267530fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< "Result image ok."
267630fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndMessage
267730fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
267830fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
267930fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
268030fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry	}
26811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
26821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystruct PointSorter
26841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
26851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool operator() (const PointRenderCase::GeneratedPoint& a, const PointRenderCase::GeneratedPoint& b) const
26861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
26871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (a.center.y() < b.center.y())
26881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return true;
26891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else if (a.center.y() > b.center.y())
26901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return false;
26911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
26921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return (a.center.x() < b.center.x());
26931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
26941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
26951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
26961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid PointRenderCase::genReferencePointData (const IterationConfig& config, std::vector<GeneratedPoint>& data) const
26971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
26981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<GeneratedPoint> currentPoints;
26991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// vertex shader
27011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	currentPoints.resize(m_attribData.size() / 2);
27021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
27031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
27041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		currentPoints[ndx].center	= m_attribData[ndx*2].swizzle(0, 1);
27051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		currentPoints[ndx].even		= (m_attribData[ndx*2 + 1].y() == 1.0f); // is green
27067d6ad9e003b52cfc23626b216b7580babf423c8fPyry Haulos		currentPoints[ndx].size		= ((m_isWidePointCase) ? ((currentPoints[ndx].even) ? 5 : 3) : 1);
27071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
27081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// tessellation
27101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_hasTessellationStage)
27111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
27121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		std::vector<GeneratedPoint> tessellatedPoints;
27131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tessellatedPoints.resize(currentPoints.size() * 4);
27151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
27161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
27171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const tcu::Vec2 position = tcu::Vec2(currentPoints[ndx].center.x(), 1.0f - currentPoints[ndx].center.y()); // mirror Y
27181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 0].center	= position + tcu::Vec2(-0.07f, -0.07f);
27201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 0].size		= currentPoints[ndx].size;
27211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 0].even		= currentPoints[ndx].even;
27221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 1].center	= position + tcu::Vec2( 0.07f, -0.07f);
27241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 1].size		= currentPoints[ndx].size;
27251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 1].even		= currentPoints[ndx].even;
27261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 2].center	= position + tcu::Vec2( 0.07f,  0.07f);
27281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 2].size		= currentPoints[ndx].size;
27291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 2].even		= currentPoints[ndx].even;
27301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 3].center	= position + tcu::Vec2(-0.07f,  0.07f);
27321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 3].size		= currentPoints[ndx].size;
27331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tessellatedPoints[4 * ndx + 3].even		= currentPoints[ndx].even;
27341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
27351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		currentPoints.swap(tessellatedPoints);
27371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
27381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// geometry
27401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_hasGeometryStage)
27411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
27421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		std::vector<GeneratedPoint> geometryShadedPoints;
27431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		geometryShadedPoints.resize(currentPoints.size() * 3);
27451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
27461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
27471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const tcu::Vec2 position = tcu::Vec2(1.0f - currentPoints[ndx].center.x(), currentPoints[ndx].center.y()); // mirror X
27481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 0].center	= position + tcu::Vec2( 0.05f,  0.03f);
27501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 0].size		= currentPoints[ndx].size;
27511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 0].even		= currentPoints[ndx].even;
27521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 1].center	= position + tcu::Vec2(-0.01f, -0.02f);
27541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 1].size		= currentPoints[ndx].size;
27551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 1].even		= currentPoints[ndx].even;
27561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 2].center	= position + tcu::Vec2(-0.05f,  0.02f);
27581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 2].size		= currentPoints[ndx].size;
27591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			geometryShadedPoints[3 * ndx + 2].even		= currentPoints[ndx].even;
27601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
27611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		currentPoints.swap(geometryShadedPoints);
27631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
27641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// sort from left to right, top to bottom
27661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::sort(currentPoints.begin(), currentPoints.end(), PointSorter());
27671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// map to pattern space
27691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
27701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		currentPoints[ndx].center = currentPoints[ndx].center * config.patternSize + config.patternPos;
27711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	currentPoints.swap(data);
27731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
27741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool PointRenderCase::verifyNarrowPointPattern (const tcu::Surface& viewport, const std::vector<GeneratedPoint>& refPoints, const ProjectedBBox& bbox, int& logFloodCounter)
27761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
27771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool anyError = false;
27781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// check that there is something near each sample
27801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int pointNdx = 0; pointNdx < (int)refPoints.size(); ++pointNdx)
27811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
27821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const float				epsilon		= 1.0e-6f;
27831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const GeneratedPoint&	refPoint	= refPoints[pointNdx];
27841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// skip points not in the the bbox, treat boundary as "in"
27861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (refPoint.center.x() < bbox.min.x() - epsilon ||
27871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			refPoint.center.y() < bbox.min.y() - epsilon ||
27881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			refPoint.center.x() > bbox.max.x() + epsilon ||
27891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			refPoint.center.y() > bbox.max.y() + epsilon)
27901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			continue;
27911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
27921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
27931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// transform to viewport coords
27947a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			const tcu::IVec2 pixelCenter(deRoundFloatToInt32((refPoint.center.x() * 0.5f + 0.5f) * (float)viewport.getWidth()),
27957a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry										 deRoundFloatToInt32((refPoint.center.y() * 0.5f + 0.5f) * (float)viewport.getHeight()));
27961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
27971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// find rasterized point in the result
27981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (pixelCenter.x() < 1 || pixelCenter.y() < 1 || pixelCenter.x() >= viewport.getWidth()-1 || pixelCenter.y() >= viewport.getHeight()-1)
27991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
28001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				// viewport boundary, assume point is fine
28011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
28021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			else
28031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
28041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	componentNdx	= (refPoint.even) ? (1) : (2); // analyze either green or blue channel
28051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				bool		foundResult		= false;
28061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				// check neighborhood
28081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				for (int dy = -1; dy < 2 && !foundResult; ++dy)
28091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				for (int dx = -1; dx < 2 && !foundResult; ++dx)
28101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
28111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					const tcu::IVec2	testPos	(pixelCenter.x() + dx, pixelCenter.y() + dy);
28121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					const tcu::RGBA		color	= viewport.getPixel(testPos.x(), testPos.y());
28131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					if (color.toIVec()[componentNdx] > 0)
28151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						foundResult = true;
28161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
28171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if (!foundResult)
28191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
28201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					anyError = true;
28211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					if (--logFloodCounter >= 0)
28231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					{
28241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						m_testCtx.getLog()
28251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							<< tcu::TestLog::Message
28261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							<< "Missing point near " << pixelCenter << ", vertex coordinates=" << refPoint.center.swizzle(0, 1) << "."
28271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							<< tcu::TestLog::EndMessage;
28281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					}
28291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
28301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
28311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
28321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
28331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return anyError;
28351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
28361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool PointRenderCase::verifyWidePointPattern (const tcu::Surface& viewport, const std::vector<GeneratedPoint>& refPoints, const ProjectedBBox& bbox, int& logFloodCounter)
28381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
28391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool anyError = false;
28401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// check that there is something near each sample
28421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int pointNdx = 0; pointNdx < (int)refPoints.size(); ++pointNdx)
28431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
28441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const GeneratedPoint& refPoint = refPoints[pointNdx];
28451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (refPoint.center.x() >= bbox.min.x() &&
28471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			refPoint.center.y() >= bbox.min.y() &&
28481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			refPoint.center.x() <= bbox.max.x() &&
28491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			refPoint.center.y() <= bbox.max.y())
28501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
28511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// point fully in the bounding box
28521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			anyError |= !verifyWidePoint(viewport, refPoint, bbox, POINT_FULL, logFloodCounter);
28531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
28547a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		else if (refPoint.center.x() >= bbox.min.x() + (float)refPoint.size / 2.0f &&
28557a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry				 refPoint.center.y() >= bbox.min.y() - (float)refPoint.size / 2.0f &&
28567a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry				 refPoint.center.x() <= bbox.max.x() + (float)refPoint.size / 2.0f &&
28577a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry				 refPoint.center.y() <= bbox.max.y() - (float)refPoint.size / 2.0f)
28581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
28591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// point leaks into bounding box
28601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			anyError |= !verifyWidePoint(viewport, refPoint, bbox, POINT_PARTIAL, logFloodCounter);
28611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
28621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
28631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return anyError;
28651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
28661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool PointRenderCase::verifyWidePoint (const tcu::Surface& viewport, const GeneratedPoint& refPoint, const ProjectedBBox& bbox, ResultPointType pointType, int& logFloodCounter)
28681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
28691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int			componentNdx		= (refPoint.even) ? (1) : (2);
28701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int			halfPointSizeCeil	= (refPoint.size + 1) / 2;
28711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int			halfPointSizeFloor	= (refPoint.size + 1) / 2;
28727d6ad9e003b52cfc23626b216b7580babf423c8fPyry Haulos	const tcu::IVec4	viewportBBoxArea	= getViewportBoundingBoxArea(bbox, tcu::IVec2(viewport.getWidth(), viewport.getHeight()), (float)refPoint.size);
28731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec4	verificationArea	= tcu::IVec4(de::max(viewportBBoxArea.x(), 0),
28741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														 de::max(viewportBBoxArea.y(), 0),
28751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														 de::min(viewportBBoxArea.z(), viewport.getWidth()),
28761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														 de::min(viewportBBoxArea.w(), viewport.getHeight()));
28777a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	const tcu::IVec2	pointPos			= tcu::IVec2(deRoundFloatToInt32((refPoint.center.x()*0.5f + 0.5f) * (float)viewport.getWidth()),
28787a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry														 deRoundFloatToInt32((refPoint.center.y()*0.5f + 0.5f) * (float)viewport.getHeight()));
28791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// find any fragment within the point that is inside the bbox, start search at the center
28811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (pointPos.x() >= verificationArea.x() &&
28831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pointPos.y() >= verificationArea.y() &&
28841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pointPos.x() < verificationArea.z() &&
28851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pointPos.y() < verificationArea.w())
28861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
28871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (viewport.getPixel(pointPos.x(), pointPos.y()).toIVec()[componentNdx])
28881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return verifyWidePointAt(pointPos, viewport, refPoint, verificationArea, pointType, componentNdx, logFloodCounter);
28891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
28901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int dy = -halfPointSizeCeil; dy <= halfPointSizeCeil; ++dy)
28921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int dx = -halfPointSizeCeil; dx <= halfPointSizeCeil; ++dx)
28931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
28941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::IVec2 testPos = pointPos + tcu::IVec2(dx, dy);
28951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (dx == 0 && dy == 0)
28971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			continue;
28981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
28991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (testPos.x() >= verificationArea.x() &&
29001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			testPos.y() >= verificationArea.y() &&
29011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			testPos.x() < verificationArea.z() &&
29021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			testPos.y() < verificationArea.w())
29031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (viewport.getPixel(testPos.x(), testPos.y()).toIVec()[componentNdx])
29051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return verifyWidePointAt(testPos, viewport, refPoint, verificationArea, pointType, componentNdx, logFloodCounter);
29061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
29081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
29091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// could not find point, this is only ok near boundaries
29101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (pointPos.x() + halfPointSizeFloor <  verificationArea.x() - 1 ||
29111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pointPos.y() + halfPointSizeFloor <  verificationArea.y() - 1 ||
29121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pointPos.x() - halfPointSizeFloor >= verificationArea.z() - 1 ||
29131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		pointPos.y() - halfPointSizeFloor >= verificationArea.w() - 1)
29141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return true;
29151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
29161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (--logFloodCounter >= 0)
29171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
29181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
29191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
29201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Missing wide point near " << pointPos << ", vertex coordinates=" << refPoint.center.swizzle(0, 1) << "."
29211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
29221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
29231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
29241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return false;
29251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
29261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
29271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool PointRenderCase::verifyWidePointAt (const tcu::IVec2& pointPos, const tcu::Surface& viewport, const GeneratedPoint& refPoint, const tcu::IVec4& bbox, ResultPointType pointType, int componentNdx, int& logFloodCounter)
29281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
29291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int				expectedPointSize		= refPoint.size;
29301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					viewportClippedTop		= false;
29311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					viewportClippedBottom	= false;
29321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					primitiveClippedTop		= false;
29331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					primitiveClippedBottom	= false;
29341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<tcu::IVec2>	widthsUpwards;
29351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<tcu::IVec2>	widthsDownwards;
29361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<tcu::IVec2>	widths;
29371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
29381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// search upwards
29391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = pointPos.y();; --y)
29401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
29411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (y < bbox.y() || y < 0)
29421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (y < bbox.y())
29441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				primitiveClippedTop = true;
29451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (y < 0)
29461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				viewportClippedTop = true;
29471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
29481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else if (pointPos.y() - y > expectedPointSize)
29501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// no need to go further than point height
29521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
29531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else if (viewport.getPixel(pointPos.x(), y).toIVec()[componentNdx] == 0)
29551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
29571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
29591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			widthsUpwards.push_back(scanPointWidthAt(tcu::IVec2(pointPos.x(), y), viewport, expectedPointSize, componentNdx));
29611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
29631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
29641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// top is clipped
29651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if ((viewportClippedTop || (pointType == POINT_PARTIAL && primitiveClippedTop)) && !widthsUpwards.empty())
29661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
29671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::IVec2&	range			= widthsUpwards.back();
29681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool			squareFits		= (range.y() - range.x() + 1) >= expectedPointSize;
29691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool			widthClipped	= (pointType == POINT_PARTIAL) && (range.x() <= bbox.x() || range.y() >= bbox.z());
29701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
29711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (squareFits || widthClipped)
29721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return true;
29731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
29741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
29751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// and downwards
29761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = pointPos.y()+1;; ++y)
29771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
29781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (y >= bbox.w() || y >= viewport.getHeight())
29791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (y >= bbox.w())
29811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				primitiveClippedBottom = true;
29821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (y >= viewport.getHeight())
29831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				viewportClippedBottom = true;
29841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
29851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else if (y - pointPos.y() > expectedPointSize)
29871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// no need to go further than point height
29891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
29901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else if (viewport.getPixel(pointPos.x(), y).toIVec()[componentNdx] == 0)
29921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
29941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
29961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
29971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			widthsDownwards.push_back(scanPointWidthAt(tcu::IVec2(pointPos.x(), y), viewport, expectedPointSize, componentNdx));
29981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
29991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
30001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// bottom is clipped
30021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if ((viewportClippedBottom || (pointType == POINT_PARTIAL && primitiveClippedBottom)) && !(widthsDownwards.empty() && widthsUpwards.empty()))
30031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
30041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::IVec2&	range			= (widthsDownwards.empty()) ? (widthsUpwards.front()) : (widthsDownwards.back());
30051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool			squareFits		= (range.y() - range.x() + 1) >= expectedPointSize;
30061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool			bboxClipped		= (pointType == POINT_PARTIAL) && (range.x() <= bbox.x() || range.y() >= bbox.z()-1);
30071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool			viewportClipped	= range.x() <= 0 || range.y() >= viewport.getWidth()-1;
30081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (squareFits || bboxClipped || viewportClipped)
30101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			return true;
30111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
30121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// would square point would fit into the rasterized area
30141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)widthsUpwards.size(); ++ndx)
30161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		widths.push_back(widthsUpwards[(int)widthsUpwards.size() - ndx - 1]);
30171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)widthsDownwards.size(); ++ndx)
30181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		widths.push_back(widthsDownwards[ndx]);
30191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(!widths.empty());
30201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = 0; y < (int)widths.size() - expectedPointSize + 1; ++y)
30221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
30231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::IVec2 unionRange = widths[y];
30241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int dy = 1; dy < expectedPointSize; ++dy)
30261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
30271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			unionRange.x() = de::max(unionRange.x(), widths[y+dy].x());
30281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			unionRange.y() = de::min(unionRange.y(), widths[y+dy].y());
30291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
30301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// would a N x N block fit here?
30321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
30331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const bool squareFits		= (unionRange.y() - unionRange.x() + 1) >= expectedPointSize;
30341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const bool bboxClipped		= (pointType == POINT_PARTIAL) && (unionRange.x() <= bbox.x() || unionRange.y() >= bbox.z()-1);
30351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const bool viewportClipped	= unionRange.x() <= 0 || unionRange.y() >= viewport.getWidth()-1;
30361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (squareFits || bboxClipped || viewportClipped)
30381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				return true;
30391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
30401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
30411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (--logFloodCounter >= 0)
30431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
30441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
30451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
30461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Missing " << expectedPointSize << "x" << expectedPointSize << " point near " << pointPos << ", vertex coordinates=" << refPoint.center.swizzle(0, 1) << "."
30471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
30481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
30491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return false;
30501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
30511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrytcu::IVec2 PointRenderCase::scanPointWidthAt (const tcu::IVec2& pointPos, const tcu::Surface& viewport, int expectedPointSize, int componentNdx) const
30531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
30541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int minX = pointPos.x();
30551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int maxX = pointPos.x();
30561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// search horizontally for a point edges
30581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = pointPos.x()-1; x >= 0; --x)
30591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
30601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (viewport.getPixel(x, pointPos.y()).toIVec()[componentNdx] == 0)
30611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
30621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// no need to go further than point width
30641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (pointPos.x() - x > expectedPointSize)
30651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
30661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		minX = x;
30681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
30691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = pointPos.x()+1; x < viewport.getWidth(); ++x)
30701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
30711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (viewport.getPixel(x, pointPos.y()).toIVec()[componentNdx] == 0)
30721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
30731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// no need to go further than point width
30751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (x - pointPos.x() > expectedPointSize)
30761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			break;
30771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		maxX = x;
30791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
30801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return tcu::IVec2(minX, maxX);
30821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
30831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass BlitFboCase : public TestCase
30851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
30861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
30871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum RenderTarget
30881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
30891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TARGET_DEFAULT = 0,
30901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TARGET_FBO,
30911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TARGET_LAST
30931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
30941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							BlitFboCase						(Context& context, const char* name, const char* description, RenderTarget src, RenderTarget dst);
30961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							~BlitFboCase					(void);
30971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
30981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
30991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
31001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
31011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FBO_SIZE = 256,
31021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
31031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	struct BlitArgs
31051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
31061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::IVec4	src;
31071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::IVec4	dst;
31081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec4	bboxMin;
31091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec4	bboxMax;
31101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		bool		linear;
31111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
31121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							init					(void);
31141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							deinit					(void);
31151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterateResult					iterate					(void);
31161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							fillSourceWithPattern	(void);
31181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool							verifyImage				(const BlitArgs& args);
31191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const RenderTarget				m_src;
31211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const RenderTarget				m_dst;
31221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<BlitArgs>			m_iterations;
31241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int								m_iteration;
31251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Framebuffer>	m_srcFbo;
31261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Framebuffer>	m_dstFbo;
31271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Renderbuffer>	m_srcRbo;
31281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Renderbuffer>	m_dstRbo;
31291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::ShaderProgram>	m_program;
31301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Buffer>		m_vbo;
31311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
31321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryBlitFboCase::BlitFboCase (Context& context, const char* name, const char* description, RenderTarget src, RenderTarget dst)
31341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: TestCase		(context, name, description)
31351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_src			(src)
31361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_dst			(dst)
31371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_iteration	(0)
31381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
31391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(src < TARGET_LAST);
31401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(dst < TARGET_LAST);
31411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
31421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryBlitFboCase::~BlitFboCase (void)
31441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
31451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	deinit();
31461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
31471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid BlitFboCase::init (void)
31491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
31501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int				numIterations			= 12;
31511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool				defaultFBMultisampled	= (m_context.getRenderTarget().getNumSamples() > 1);
31521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
31531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random				rnd						(0xABC123);
31541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
31561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
31571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Using BlitFramebuffer to blit area from "
31581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_src == TARGET_DEFAULT) ? ("default fb") : ("fbo"))
31591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< " to "
31601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_dst == TARGET_DEFAULT) ? ("default fb") : ("fbo"))
31611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ".\n"
31621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Varying blit arguments and primitive bounding box between iterations.\n"
31631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Expecting bounding box to have no effect on blitting.\n"
31641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Source framebuffer is filled with green-yellow grid.\n"
31651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
31661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"))
31681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
31691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_dst == TARGET_DEFAULT && defaultFBMultisampled)
31701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires non-multisampled default framebuffer");
31711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// resources
31731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_src == TARGET_FBO)
31751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
31761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_srcRbo = de::MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(m_context.getRenderContext()));
31771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindRenderbuffer(GL_RENDERBUFFER, **m_srcRbo);
31781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, FBO_SIZE, FBO_SIZE);
31791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "src rbo");
31801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_srcFbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
31821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindFramebuffer(GL_FRAMEBUFFER, **m_srcFbo);
31831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **m_srcRbo);
31841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "src fbo");
31851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
31861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_dst == TARGET_FBO)
31881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
31891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_dstRbo = de::MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(m_context.getRenderContext()));
31901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindRenderbuffer(GL_RENDERBUFFER, **m_dstRbo);
31911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, FBO_SIZE, FBO_SIZE);
31921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "dst rbo");
31931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
31941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_dstFbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
31951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindFramebuffer(GL_FRAMEBUFFER, **m_dstFbo);
31961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **m_dstRbo);
31971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "dst fbo");
31981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
31991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
32011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		static const char* const s_vertexSource =	"#version 310 es\n"
32021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"in highp vec4 a_position;\n"
32031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"out highp vec4 v_position;\n"
32041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"void main()\n"
32051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"{\n"
32061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"	gl_Position = a_position;\n"
32071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"	v_position = a_position;\n"
32081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"}\n";
32091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		static const char* const s_fragmentSource =	"#version 310 es\n"
32101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"in mediump vec4 v_position;\n"
32111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"layout(location=0) out mediump vec4 dEQP_FragColor;\n"
32121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"void main()\n"
32131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"{\n"
32141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"	const mediump vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
32151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"	const mediump vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
32161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"	dEQP_FragColor = (step(0.1, mod(v_position.x, 0.2)) == step(0.1, mod(v_position.y, 0.2))) ? (green) : (yellow);\n"
32171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry													"}\n";
32181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_vertexSource) << glu::FragmentSource(s_fragmentSource)));
32201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (!m_program->isOk())
32221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
32231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog() << *m_program;
32241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			throw tcu::TestError("failed to build program");
32251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
32261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
32271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
32291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		static const tcu::Vec4 s_quadCoords[] =
32301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
32311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
32321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
32331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
32341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
32351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		};
32361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
32381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
32401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bufferData(GL_ARRAY_BUFFER, sizeof(s_quadCoords), s_quadCoords, GL_STATIC_DRAW);
32411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "set buf");
32421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
32431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// gen iterations
32451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
32471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::IVec2 srcSize = (m_src == TARGET_DEFAULT) ? (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) : (tcu::IVec2(FBO_SIZE, FBO_SIZE));
32481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::IVec2 dstSize = (m_dst == TARGET_DEFAULT) ? (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) : (tcu::IVec2(FBO_SIZE, FBO_SIZE));
32491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
32511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
32521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "srcSize = " << srcSize << "\n"
32531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "dstSize = " << dstSize << "\n"
32541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage;
32551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int ndx = 0; ndx < numIterations; ++ndx)
32571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
32581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BlitArgs args;
32591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (m_src == TARGET_DEFAULT && defaultFBMultisampled)
32611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
32621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const tcu::IVec2	unionSize	= tcu::IVec2(de::min(srcSize.x(), dstSize.x()), de::min(srcSize.y(), dstSize.y()));
32631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int			srcWidth	= rnd.getInt(1, unionSize.x());
32641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int			srcHeight	= rnd.getInt(1, unionSize.y());
32651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int			srcX		= rnd.getInt(0, unionSize.x() - srcWidth);
32661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int			srcY		= rnd.getInt(0, unionSize.y() - srcHeight);
32671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.src.x() = srcX;
32691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.src.y() = srcY;
32701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.src.z() = srcX + srcWidth;
32711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.src.w() = srcY + srcHeight;
32721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.dst = args.src;
32741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
32751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			else
32761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
32771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	srcWidth	= rnd.getInt(1, srcSize.x());
32781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	srcHeight	= rnd.getInt(1, srcSize.y());
32791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	srcX		= rnd.getInt(0, srcSize.x() - srcWidth);
32801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	srcY		= rnd.getInt(0, srcSize.y() - srcHeight);
32811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	dstWidth	= rnd.getInt(1, dstSize.x());
32821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	dstHeight	= rnd.getInt(1, dstSize.y());
32831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	dstX		= rnd.getInt(-(dstWidth / 2), dstSize.x() - (dstWidth+1) / 2);		// allow dst go out of bounds
32841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				const int	dstY		= rnd.getInt(-(dstHeight / 2), dstSize.y() - (dstHeight+1)  / 2);
32851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.src.x() = srcX;
32871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.src.y() = srcY;
32881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.src.z() = srcX + srcWidth;
32891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.src.w() = srcY + srcHeight;
32901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.dst.x() = dstX;
32911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.dst.y() = dstY;
32921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.dst.z() = dstX + dstWidth;
32931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				args.dst.w() = dstY + dstHeight;
32941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
32951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
32961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.bboxMin.x() = rnd.getFloat(-1.1f, 1.1f);
32971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.bboxMin.y() = rnd.getFloat(-1.1f, 1.1f);
32981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.bboxMin.z() = rnd.getFloat(-1.1f, 1.1f);
32991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.bboxMin.w() = rnd.getFloat( 0.9f, 1.1f);
33001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.bboxMax.x() = rnd.getFloat(-1.1f, 1.1f);
33021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.bboxMax.y() = rnd.getFloat(-1.1f, 1.1f);
33031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.bboxMax.z() = rnd.getFloat(-1.1f, 1.1f);
33041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.bboxMax.w() = rnd.getFloat( 0.9f, 1.1f);
33051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (args.bboxMin.x() / args.bboxMin.w() > args.bboxMax.x() / args.bboxMax.w())
33071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				std::swap(args.bboxMin.x(), args.bboxMax.x());
33081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (args.bboxMin.y() / args.bboxMin.w() > args.bboxMax.y() / args.bboxMax.w())
33091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				std::swap(args.bboxMin.y(), args.bboxMax.y());
33101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (args.bboxMin.z() / args.bboxMin.w() > args.bboxMax.z() / args.bboxMax.w())
33111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				std::swap(args.bboxMin.z(), args.bboxMax.z());
33121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			args.linear = rnd.getBool();
33141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_iterations.push_back(args);
33161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
33171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
33181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
33191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid BlitFboCase::deinit (void)
33211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
33221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_srcFbo.clear();
33231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_srcRbo.clear();
33241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_dstFbo.clear();
33251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_dstRbo.clear();
33261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_program.clear();
33271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_vbo.clear();
33281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
33291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryBlitFboCase::IterateResult BlitFboCase::iterate (void)
33311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
33321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Iteration" + de::toString(m_iteration), "Iteration " + de::toString(m_iteration+1) + " / " + de::toString((int)m_iterations.size()));
33331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const BlitArgs&				blitCfg		= m_iterations[m_iteration];
33341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
33351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_iteration == 0)
33371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
33381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// fill source with test pattern. Default fb must be filled for each iteration because contents might not survive the swap
33401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_src == TARGET_DEFAULT || m_iteration == 0)
33411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		fillSourceWithPattern();
33421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
33441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
33451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Set bounding box:\n"
33461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "\tmin:" << blitCfg.bboxMin << "\n"
33471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "\tmax:" << blitCfg.bboxMax << "\n"
33481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Blit:\n"
33491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\tsrc: " << blitCfg.src << "\n"
33501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\tdst: " << blitCfg.dst << "\n"
33511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<<	"\tfilter: " << ((blitCfg.linear) ? ("linear") : ("nearest"))
33521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
33531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3354485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe	gl.primitiveBoundingBox(blitCfg.bboxMin.x(), blitCfg.bboxMin.y(), blitCfg.bboxMin.z(), blitCfg.bboxMin.w(),
3355485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe							blitCfg.bboxMax.x(), blitCfg.bboxMax.y(), blitCfg.bboxMax.z(), blitCfg.bboxMax.w());
33561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, (m_dst == TARGET_FBO) ? (**m_dstFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
33581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
33591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clear(GL_COLOR_BUFFER_BIT);
33601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, (m_src == TARGET_FBO) ? (**m_srcFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
33621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.blitFramebuffer(blitCfg.src.x(), blitCfg.src.y(), blitCfg.src.z(), blitCfg.src.w(),
33631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					   blitCfg.dst.x(), blitCfg.dst.y(), blitCfg.dst.z(), blitCfg.dst.w(),
33641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					   GL_COLOR_BUFFER_BIT,
33651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					   ((blitCfg.linear) ? (GL_LINEAR) : (GL_NEAREST)));
33661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "blit");
33671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!verifyImage(blitCfg))
33691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected blit result");
33701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return (++m_iteration == (int)m_iterations.size()) ? (STOP) : (CONTINUE);
33721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
33731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool BlitFboCase::verifyImage (const BlitArgs& args)
33751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
33761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int				colorThreshold	= 4; //!< this test case is not about how color is preserved, allow almost anything
33771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2		dstSize			= (m_dst == TARGET_DEFAULT) ? (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) : (tcu::IVec2(FBO_SIZE, FBO_SIZE));
33781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
33791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface			viewport		(dstSize.x(), dstSize.y());
33801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface			errorMask		(dstSize.x(), dstSize.y());
33811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool					anyError		= false;
33821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
33841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
33851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Verifying blit result"
33861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
33871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, (m_dst == TARGET_FBO) ? (**m_dstFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
33891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::readPixels(m_context.getRenderContext(), 0, 0, viewport.getAccess());
33901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::clear(errorMask.getAccess(), tcu::IVec4(0, 0, 0, 255));
33921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
33931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = 0; y < dstSize.y(); ++y)
33941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = 0; x < dstSize.x(); ++x)
33951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
33961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::RGBA color	= viewport.getPixel(x, y);
33971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool		inside	= (x >= args.dst.x() && x < args.dst.z() && y >= args.dst.y() && y < args.dst.w());
33981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool		error	= (inside) ? (color.getGreen() < 255 - colorThreshold || color.getBlue() > colorThreshold)
33991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry										   : (color.getRed() > colorThreshold || color.getGreen() > colorThreshold || color.getBlue() > colorThreshold);
34001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (error)
34021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
34031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			anyError = true;
3404c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			errorMask.setPixel(x, y, tcu::RGBA::red());
34051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
34061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
34071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (anyError)
34091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
34101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
34111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
34121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image verification failed."
34131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
34141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
34151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
34161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
34171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
34181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return false;
34191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
34201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
34211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
34221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
34231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
34241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Result image ok."
342530fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndMessage
342630fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
342730fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
342830fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
34291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		return true;
34301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
34311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
34321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid BlitFboCase::fillSourceWithPattern (void)
34341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
34351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
34361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2		srcSize		= (m_src == TARGET_DEFAULT) ? (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) : (tcu::IVec2(FBO_SIZE, FBO_SIZE));
34371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int				posLocation	= gl.getAttribLocation(m_program->getProgram(), "a_position");
34381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, (m_src == TARGET_FBO) ? (**m_srcFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
34401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.viewport(0, 0, srcSize.x(), srcSize.y());
34411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.useProgram(m_program->getProgram());
34421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clearColor(0.0f, 0.0f, 1.0f, 1.0f);
34441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clear(GL_COLOR_BUFFER_BIT);
34451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enableVertexAttribArray(posLocation);
34471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 4 * (int)sizeof(float), NULL);
34481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
34491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
34501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
34511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass DepthDrawCase : public TestCase
34531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
34541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
34551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum DepthType
34561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
34571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DEPTH_BUILTIN = 0,
34581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DEPTH_USER_DEFINED,
34591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DEPTH_LAST
34611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
34621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum BBoxState
34631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
34641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		STATE_GLOBAL = 0,
34651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		STATE_PER_PRIMITIVE,
34661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		STATE_LAST
34681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
34691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum BBoxSize
34701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
34711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BBOX_EQUAL = 0,
34721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BBOX_LARGER,
34731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BBOX_LAST
34751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
34761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									DepthDrawCase					(Context& context, const char* name, const char* description, DepthType depthType, BBoxState state, BBoxSize bboxSize);
34781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									~DepthDrawCase					(void);
34791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
34811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							init							(void);
34821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							deinit							(void);
34831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterateResult					iterate							(void);
34841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genVertexSource					(void) const;
34861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genFragmentSource				(void) const;
34871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genTessellationControlSource	(void) const;
34881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genTessellationEvaluationSource	(void) const;
34891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							generateAttributeData			(std::vector<tcu::Vec4>& data) const;
34901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool							verifyImage						(const tcu::Surface& viewport) const;
34911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
34931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
34941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		RENDER_AREA_SIZE = 256,
34951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
34961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
34971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	struct LayerInfo
34981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
34991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		float		zOffset;
35001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		float		zScale;
35011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec4	color1;
35021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec4	color2;
35031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
35041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int						m_numLayers;
35061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int						m_gridSize;
35071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const DepthType					m_depthType;
35091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const BBoxState					m_state;
35101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const BBoxSize					m_bboxSize;
35111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::ShaderProgram>	m_program;
35131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Buffer>		m_vbo;
35141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<LayerInfo>			m_layers;
35151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
35161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryDepthDrawCase::DepthDrawCase (Context& context, const char* name, const char* description, DepthType depthType, BBoxState state, BBoxSize bboxSize)
35181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: TestCase		(context, name, description)
35191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_numLayers	(14)
35201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_gridSize	(24)
35211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_depthType	(depthType)
35221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_state		(state)
35231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_bboxSize	(bboxSize)
35241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
35251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(depthType < DEPTH_LAST);
35261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(state < STATE_LAST);
35271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(bboxSize < BBOX_LAST);
35281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
35291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryDepthDrawCase::~DepthDrawCase (void)
35311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
35321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	deinit();
35331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
35341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid DepthDrawCase::init (void)
35361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
35371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
35381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// requirements
35401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"))
35421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
35431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_state == STATE_PER_PRIMITIVE && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
35441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
35451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_context.getRenderTarget().getDepthBits() == 0)
35461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires depth buffer");
35471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_context.getRenderTarget().getWidth() < RENDER_AREA_SIZE || m_context.getRenderTarget().getHeight() < RENDER_AREA_SIZE)
35481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_AREA_SIZE) + "x" + de::toString<int>(RENDER_AREA_SIZE) + " viewport");
35491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// log
35511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
35521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
35531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Rendering multiple triangle grids with with different z coordinates.\n"
35541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Topmost grid is green-yellow, other grids are blue-red.\n"
35551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Expecting only the green-yellow grid to be visible.\n"
35561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Setting primitive bounding box "
35571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_bboxSize == BBOX_EQUAL) ? ("to exactly cover") : ("to cover"))
35581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_state == STATE_GLOBAL) ? (" each grid") : (" each triangle"))
35591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_bboxSize == BBOX_EQUAL) ? (".") : (" and include some padding."))
35601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\n"
35611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Set bounding box using "
35621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_state == STATE_GLOBAL) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") : ("gl_BoundingBoxEXT output"))
35631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "\n"
35641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< ((m_depthType == DEPTH_USER_DEFINED) ? ("Fragment depth is set in the fragment shader") : (""))
35651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
35661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// resources
35681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
35701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		glu::ProgramSources sources;
35711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		sources << glu::VertexSource(genVertexSource());
35721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		sources << glu::FragmentSource(genFragmentSource());
35731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_state == STATE_PER_PRIMITIVE)
35751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			sources << glu::TessellationControlSource(genTessellationControlSource())
35761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					<< glu::TessellationEvaluationSource(genTessellationEvaluationSource());
35771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), sources));
35791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "build program");
35801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
35821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const tcu::ScopedLogSection section(m_testCtx.getLog(), "ShaderProgram", "Shader program");
35831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog() << *m_program;
35841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
35851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (!m_program->isOk())
35871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			throw tcu::TestError("failed to build program");
35881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
35891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
35911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		std::vector<tcu::Vec4> data;
35921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		generateAttributeData(data);
35941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
35951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
35961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
35971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bufferData(GL_ARRAY_BUFFER, (int)(sizeof(tcu::Vec4) * data.size()), &data[0], GL_STATIC_DRAW);
35981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		GLU_EXPECT_NO_ERROR(gl.getError(), "buf upload");
35991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
36001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// gen layers
36021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
36031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		de::Random rnd(0x12345);
36041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_layers.resize(m_numLayers);
36061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx)
36071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
36087a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			m_layers[layerNdx].zOffset	= ((float)layerNdx / (float)m_numLayers) * 2.0f - 1.0f;
36097a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			m_layers[layerNdx].zScale	= (2.0f / (float)m_numLayers);
36101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_layers[layerNdx].color1	= (layerNdx == 0) ? (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) : (tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
36111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_layers[layerNdx].color2	= (layerNdx == 0) ? (tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f)) : (tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
36121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
36131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		rnd.shuffle(m_layers.begin(), m_layers.end());
36141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
36151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
36161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid DepthDrawCase::deinit (void)
36181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
36191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_program.clear();
36201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_vbo.clear();
36211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
36221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryDepthDrawCase::IterateResult DepthDrawCase::iterate (void)
36241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
36251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool				hasTessellation		= (m_state == STATE_PER_PRIMITIVE);
36261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
36271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		posLocation			= gl.getAttribLocation(m_program->getProgram(), "a_position");
36281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		colLocation			= gl.getAttribLocation(m_program->getProgram(), "a_colorMix");
36291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		depthBiasLocation	= gl.getUniformLocation(m_program->getProgram(), "u_depthBias");
36301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		depthScaleLocation	= gl.getUniformLocation(m_program->getProgram(), "u_depthScale");
36311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		color1Location		= gl.getUniformLocation(m_program->getProgram(), "u_color1");
36321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		color2Location		= gl.getUniformLocation(m_program->getProgram(), "u_color2");
36331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface			viewport			(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
36351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random				rnd					(0x213237);
36361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(posLocation != -1);
36381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(colLocation != -1);
36391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(depthBiasLocation != -1);
36401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(depthScaleLocation != -1);
36411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(color1Location != -1);
36421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	TCU_CHECK(color2Location != -1);
36431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.viewport(0, 0, RENDER_AREA_SIZE, RENDER_AREA_SIZE);
36451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
36461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clearDepthf(1.0f);
36471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.depthFunc(GL_LESS);
36481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enable(GL_DEPTH_TEST);
36491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
36501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "setup viewport");
36511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
36531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, (int)(8 * sizeof(float)), (const float*)DE_NULL);
36541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.vertexAttribPointer(colLocation, 4, GL_FLOAT, GL_FALSE, (int)(8 * sizeof(float)), (const float*)DE_NULL + 4);
36551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enableVertexAttribArray(posLocation);
36561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enableVertexAttribArray(colLocation);
36571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.useProgram(m_program->getProgram());
36581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "setup va");
36591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (hasTessellation)
36611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.patchParameteri(GL_PATCH_VERTICES, 3);
36621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx)
36641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
36651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform1f(depthBiasLocation, m_layers[layerNdx].zOffset);
36661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform1f(depthScaleLocation, m_layers[layerNdx].zScale);
36671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform4fv(color1Location, 1, m_layers[layerNdx].color1.getPtr());
36681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.uniform4fv(color2Location, 1, m_layers[layerNdx].color2.getPtr());
36691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_state == STATE_GLOBAL)
36711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
36721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const float negPadding = (m_bboxSize == BBOX_EQUAL) ? (0.0f) : (rnd.getFloat() * 0.3f);
36731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const float posPadding = (m_bboxSize == BBOX_EQUAL) ? (0.0f) : (rnd.getFloat() * 0.3f);
36741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
3675485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe			gl.primitiveBoundingBox(-1.0f, -1.0f, m_layers[layerNdx].zOffset - negPadding, 1.0f,
3676485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe									1.0f,  1.0f, (m_layers[layerNdx].zOffset + m_layers[layerNdx].zScale + posPadding), 1.0f);
36771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
36781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.drawArrays((hasTessellation) ? (GL_PATCHES) : (GL_TRIANGLES), 0, m_gridSize * m_gridSize * 6);
36801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
36811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::readPixels(m_context.getRenderContext(), 0, 0, viewport.getAccess());
36831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "render and read");
36841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (verifyImage(viewport))
36861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
36871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
36881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
36891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return STOP;
36911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
36921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string DepthDrawCase::genVertexSource (void) const
36941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
36951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool			hasTessellation	= (m_state == STATE_PER_PRIMITIVE);
36961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
36971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
36981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
36991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 a_position;\n"
37001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 a_colorMix;\n"
37011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 vtx_colorMix;\n";
37021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!hasTessellation && m_depthType == DEPTH_USER_DEFINED)
37041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << "out highp float v_fragDepth;\n";
37051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!hasTessellation)
37071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"uniform highp float u_depthBias;\n"
37081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"uniform highp float u_depthScale;\n";
37091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"\n"
37111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
37121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n";
37131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (hasTessellation)
37151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << "	gl_Position = a_position;\n";
37161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else if (m_depthType == DEPTH_USER_DEFINED)
37171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"	highp float dummyZ = a_position.z;\n"
37181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp float writtenZ = a_position.w;\n"
37191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_Position = vec4(a_position.xy, dummyZ, 1.0);\n"
37201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_fragDepth = writtenZ * u_depthScale + u_depthBias;\n";
37211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
37221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"	highp float writtenZ = a_position.w;\n"
37231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_Position = vec4(a_position.xy, writtenZ * u_depthScale + u_depthBias, 1.0);\n";
37241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"	vtx_colorMix = a_colorMix;\n"
37261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
37271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
37291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
37301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string DepthDrawCase::genFragmentSource (void) const
37321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
37331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool			hasTessellation	= (m_state == STATE_PER_PRIMITIVE);
37341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const char* const	colorMixName	= (hasTessellation) ? ("tess_eval_colorMix") : ("vtx_colorMix");
37351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
37361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
37381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in mediump vec4 " << colorMixName << ";\n";
37391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_depthType == DEPTH_USER_DEFINED)
37411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << "in mediump float v_fragDepth;\n";
37421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"layout(location = 0) out mediump vec4 o_color;\n"
37441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_color1;\n"
37451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp vec4 u_color2;\n"
37461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
37471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
37481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
37491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	o_color = mix(u_color1, u_color2, " << colorMixName << ");\n";
37501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_depthType == DEPTH_USER_DEFINED)
37521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << "	gl_FragDepth = v_fragDepth * 0.5 + 0.5;\n";
37531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"}\n";
37551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
37571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
37581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string DepthDrawCase::genTessellationControlSource (void) const
37601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
37611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
37621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
37641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
37651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_primitive_bounding_box : require\n"
37661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(vertices=3) out;\n"
37671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
37681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp float u_depthBias;\n"
37691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp float u_depthScale;\n"
37701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
37711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 vtx_colorMix[];\n"
37721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 tess_ctrl_colorMix[];\n"
37731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
37741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
37751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
37761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
37771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	tess_ctrl_colorMix[gl_InvocationID] = vtx_colorMix[0];\n"
37781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
37791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[0] = 2.8;\n"
37801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[1] = 2.8;\n"
37811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[2] = 2.8;\n"
37821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelInner[0] = 2.8;\n"
37831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
37841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	// real Z stored in w component\n"
37851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 minBound = vec4(min(min(vec3(gl_in[0].gl_Position.xy, gl_in[0].gl_Position.w * u_depthScale + u_depthBias),\n"
37861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                                   vec3(gl_in[1].gl_Position.xy, gl_in[1].gl_Position.w * u_depthScale + u_depthBias)),\n"
37871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                               vec3(gl_in[2].gl_Position.xy, gl_in[2].gl_Position.w * u_depthScale + u_depthBias)), 1.0);\n"
37881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 maxBound = vec4(max(max(vec3(gl_in[0].gl_Position.xy, gl_in[0].gl_Position.w * u_depthScale + u_depthBias),\n"
37891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                                   vec3(gl_in[1].gl_Position.xy, gl_in[1].gl_Position.w * u_depthScale + u_depthBias)),\n"
37901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	                               vec3(gl_in[2].gl_Position.xy, gl_in[2].gl_Position.w * u_depthScale + u_depthBias)), 1.0);\n";
37911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
37921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_bboxSize == BBOX_EQUAL)
37931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"	gl_BoundingBoxEXT[0] = minBound;\n"
37941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[1] = maxBound;\n";
37951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
37961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"	highp float nedPadding = mod(gl_in[0].gl_Position.z, 0.3);\n"
37971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp float posPadding = mod(gl_in[1].gl_Position.z, 0.3);\n"
37981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[0] = minBound - vec4(0.0, 0.0, nedPadding, 0.0);\n"
37991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_BoundingBoxEXT[1] = maxBound + vec4(0.0, 0.0, posPadding, 0.0);\n";
38001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"}\n";
38021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
38041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
38051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string DepthDrawCase::genTessellationEvaluationSource (void) const
38071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
38081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream	buf;
38091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
38111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
38121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_gpu_shader5 : require\n"
38131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(triangles) in;\n"
38141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
38151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 tess_ctrl_colorMix[];\n"
38161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 tess_eval_colorMix;\n";
38171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_depthType == DEPTH_USER_DEFINED)
38191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << "out highp float v_fragDepth;\n";
38201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"uniform highp float u_depthBias;\n"
38221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"uniform highp float u_depthScale;\n"
38231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
38241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"precise gl_Position;\n"
38251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"\n"
38261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
38271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
38281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	highp vec4 tessellatedPos = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n";
38291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_depthType == DEPTH_USER_DEFINED)
38311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"	highp float dummyZ = tessellatedPos.z;\n"
38321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	highp float writtenZ = tessellatedPos.w;\n"
38331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_Position = vec4(tessellatedPos.xy, dummyZ, 1.0);\n"
38341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	v_fragDepth = writtenZ * u_depthScale + u_depthBias;\n";
38351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
38361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"	highp float writtenZ = tessellatedPos.w;\n"
38371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"	gl_Position = vec4(tessellatedPos.xy, writtenZ * u_depthScale + u_depthBias, 1.0);\n";
38381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"	tess_eval_colorMix = tess_ctrl_colorMix[0];\n"
38401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
38411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
38431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
38441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid DepthDrawCase::generateAttributeData (std::vector<tcu::Vec4>& data) const
38461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
38471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4		color1				(0.0f, 0.0f, 0.0f, 0.0f); // mix weights
38481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4		color2				(1.0f, 1.0f, 1.0f, 1.0f);
38491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<int>	cellOrder			(m_gridSize * m_gridSize);
38501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random			rnd					(0xAB54321);
38511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// generate grid with cells in random order
38531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
38541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		cellOrder[ndx] = ndx;
38551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	rnd.shuffle(cellOrder.begin(), cellOrder.end());
38561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	data.resize(m_gridSize * m_gridSize * 6 * 2);
38581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
38591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
38601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellNdx		= cellOrder[ndx];
38611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellX		= cellNdx % m_gridSize;
38621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellY		= cellNdx / m_gridSize;
38631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::Vec4&	cellColor	= ((cellX+cellY)%2 == 0) ? (color1) : (color2);
38641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38657a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[ndx * 6 * 2 +  0] = tcu::Vec4(float(cellX+0) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  1] = cellColor;
38667a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[ndx * 6 * 2 +  2] = tcu::Vec4(float(cellX+1) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  3] = cellColor;
38677a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[ndx * 6 * 2 +  4] = tcu::Vec4(float(cellX+0) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  5] = cellColor;
38687a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[ndx * 6 * 2 +  6] = tcu::Vec4(float(cellX+0) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  7] = cellColor;
38697a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[ndx * 6 * 2 +  8] = tcu::Vec4(float(cellX+1) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  9] = cellColor;
38707a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry		data[ndx * 6 * 2 + 10] = tcu::Vec4(float(cellX+1) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 + 11] = cellColor;
38711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// Fill Z with random values (fake Z)
38731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int vtxNdx = 0; vtxNdx < 6; ++vtxNdx)
38741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			data[ndx * 6 * 2 + 2*vtxNdx].z() = rnd.getFloat(0.0f, 1.0);
38751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// Fill W with other random values (written Z)
38771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int vtxNdx = 0; vtxNdx < 6; ++vtxNdx)
38781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			data[ndx * 6 * 2 + 2*vtxNdx].w() = rnd.getFloat(0.0f, 1.0);
38791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
38801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
38811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool DepthDrawCase::verifyImage (const tcu::Surface& viewport) const
38831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
38841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface	errorMask	(viewport.getWidth(), viewport.getHeight());
38851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool			anyError	= false;
38861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::clear(errorMask.getAccess(), tcu::IVec4(0,0,0,255));
38881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = 0; y < viewport.getHeight(); ++y)
38901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = 0; x < viewport.getWidth(); ++x)
38911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
38921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::RGBA	pixel		= viewport.getPixel(x, y);
38931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		bool			error		= false;
38941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// expect green, yellow or a combination of these
38961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (pixel.getGreen() != 255 || pixel.getBlue() != 0)
38971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			error = true;
38981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
38991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (error)
39001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
3901c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			errorMask.setPixel(x, y, tcu::RGBA::red());
39021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			anyError = true;
39031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
39041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
39051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (anyError)
39071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
39081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
39091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image verification failed."
39101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
39111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
39121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
39131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
39141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
39151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
39161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
39171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
39181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Result image ok."
391930fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndMessage
392030fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
392130fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
392230fde0c3faee7af43a958bd572d8b6c584333a15Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
39231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return !anyError;
39251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
39261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass ClearCase : public TestCase
39281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
39291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
39301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum
39311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
39321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		SCISSOR_CLEAR_BIT		= 1 << 0,
39331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DRAW_TRIANGLE_BIT		= 1 << 1,
39341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		PER_PRIMITIVE_BBOX_BIT	= 1 << 2,
39351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		FULLSCREEN_SCISSOR_BIT	= 1 << 3,
39361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
39371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									ClearCase						(Context& context, const char* name, const char* description, deUint32 flags);
39391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									~ClearCase						(void);
39401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
39421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	struct DrawObject
39431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
39441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		int firstNdx;
39451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		int numVertices;
39461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
39471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							init							(void);
39491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							deinit							(void);
39501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterateResult					iterate							(void);
39511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							createVbo						(void);
39531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							createProgram					(void);
39541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							renderTo						(tcu::Surface& dst, bool useBBox);
39551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool							verifyImagesEqual				(const tcu::PixelBufferAccess& withoutBBox, const tcu::PixelBufferAccess& withBBox);
39561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool							verifyImageResultValid			(const tcu::PixelBufferAccess& result);
39571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genVertexSource					(void) const;
39591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genFragmentSource				(void) const;
39601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genTessellationControlSource	(bool setBBox) const;
39611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genTessellationEvaluationSource	(void) const;
39621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool						m_scissoredClear;
39641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool						m_fullscreenScissor;
39651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool						m_drawTriangles;
39661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const bool						m_useGlobalState;
39671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Buffer>		m_vbo;
39691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::ShaderProgram>	m_perPrimitiveProgram;
39701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::ShaderProgram>	m_basicProgram;
39711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<DrawObject>			m_drawObjects;
39721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<tcu::Vec4>			m_objectVertices;
39731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
39741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryClearCase::ClearCase (Context& context, const char* name, const char* description, deUint32 flags)
39761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: TestCase				(context, name, description)
39771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_scissoredClear		((flags & SCISSOR_CLEAR_BIT) != 0)
39781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_fullscreenScissor	((flags & FULLSCREEN_SCISSOR_BIT) != 0)
39791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_drawTriangles		((flags & DRAW_TRIANGLE_BIT) != 0)
39801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_useGlobalState		((flags & PER_PRIMITIVE_BBOX_BIT) == 0)
39811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
39821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(m_useGlobalState || m_drawTriangles); // per-triangle bbox requires triangles
39831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(!m_fullscreenScissor || m_scissoredClear); // fullscreenScissor requires scissoredClear
39841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
39851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryClearCase::~ClearCase (void)
39871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
39881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	deinit();
39891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
39901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ClearCase::init (void)
39921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
39931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"))
39941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
39951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_drawTriangles && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
39961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
39971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
39981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
39991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
40001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Doing multiple"
40011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_scissoredClear) ? (" scissored") : (""))
40021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< " color buffer clears"
40031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_drawTriangles) ? (" and drawing some geometry between them") : (""))
40041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ".\n"
40051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< ((m_scissoredClear && m_fullscreenScissor) ? ("Setting scissor area to cover entire viewport.\n") : (""))
40061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Rendering with and without setting the bounding box.\n"
40071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Expecting bounding box to have no effect on clears (i.e. results are constant).\n"
40081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Set bounding box using "
40091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_useGlobalState) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") : ("gl_BoundingBoxEXT output"))
40101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ".\n"
40111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Clear color is green with yellowish shades.\n"
40121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< ((m_drawTriangles) ? ("Primitive color is yellow with greenish shades.\n") : (""))
40131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
40141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_drawTriangles)
40161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
40171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		createVbo();
40181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		createProgram();
40191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
40201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
40211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ClearCase::deinit (void)
40231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
40241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_vbo.clear();
40251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_perPrimitiveProgram.clear();
40261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_basicProgram.clear();
40271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_drawObjects = std::vector<DrawObject>();
40281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_objectVertices = std::vector<tcu::Vec4>();
40291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
40301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryClearCase::IterateResult ClearCase::iterate (void)
40321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
40331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2	renderTargetSize	(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
40341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface		resultWithoutBBox	(renderTargetSize.x(), renderTargetSize.y());
40351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface		resultWithBBox		(renderTargetSize.x(), renderTargetSize.y());
40361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// render with and without bbox set
40381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int passNdx = 0; passNdx < 2; ++passNdx)
40391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
40401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool		useBBox			= (passNdx == 1);
40411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Surface&	destination		= (useBBox) ? (resultWithBBox) : (resultWithoutBBox);
40421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		renderTo(destination, useBBox);
40441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
40451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// Verify images are equal and that the image does not contain (trivially detectable) garbage
40471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!verifyImagesEqual(resultWithoutBBox.getAccess(), resultWithBBox.getAccess()))
40491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
40501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// verifyImagesEqual will print out the image and error mask
40511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
40521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
40531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else if (!verifyImageResultValid(resultWithBBox.getAccess()))
40541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
40551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// verifyImageResultValid will print out the image and error mask
40561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
40571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
40581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
40591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
40601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
40611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
40621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image comparison passed."
40631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
40641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
40651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("Result", "Result", resultWithBBox.getAccess())
40661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
40671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
40691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
40701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return STOP;
40721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
40731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ClearCase::createVbo (void)
40751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
40761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int				numObjects	= 16;
40771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
40781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random				rnd			(deStringHash(getName()));
40791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
40811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int objectNdx = 0; objectNdx < numObjects; ++objectNdx)
40831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
40841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int	numTriangles	= rnd.getInt(1, 4);
40851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const float	minX			= rnd.getFloat(-1.2f, 0.8f);
40861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const float	minY			= rnd.getFloat(-1.2f, 0.8f);
40871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const float	maxX			= minX + rnd.getFloat(0.2f, 1.0f);
40881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const float	maxY			= minY + rnd.getFloat(0.2f, 1.0f);
40891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		DrawObject	drawObject;
40911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		drawObject.firstNdx = (int)m_objectVertices.size();
40921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		drawObject.numVertices = numTriangles * 3;
40931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_drawObjects.push_back(drawObject);
40951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
40961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int triangleNdx = 0; triangleNdx < numTriangles; ++triangleNdx)
40971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
40981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
40991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const float posX = rnd.getFloat(minX, maxX);
41001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const float posY = rnd.getFloat(minY, maxY);
41011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const float posZ = rnd.getFloat(-0.7f, 0.7f);
41021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const float posW = rnd.getFloat(0.9f, 1.1f);
41031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_objectVertices.push_back(tcu::Vec4(posX, posY, posZ, posW));
41051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
41061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
41071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
41091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bufferData(GL_ARRAY_BUFFER, (int)(m_objectVertices.size() * sizeof(tcu::Vec4)), &m_objectVertices[0], GL_STATIC_DRAW);
41101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "buffer upload");
41111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
41121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ClearCase::createProgram (void)
41141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
41151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_basicProgram = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(),
41161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																			glu::ProgramSources()
41171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																				<< glu::VertexSource(genVertexSource())
41181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																				<< glu::FragmentSource(genFragmentSource())
41191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																				<< glu::TessellationControlSource(genTessellationControlSource(false))
41201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																				<< glu::TessellationEvaluationSource(genTessellationEvaluationSource())));
41211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
41231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Section("Program", "Shader program")
41241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< *m_basicProgram
41251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndSection;
41261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_basicProgram->isOk())
41281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::TestError("shader build failed");
41291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_useGlobalState)
41311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
41321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_perPrimitiveProgram = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(),
41331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																					   glu::ProgramSources()
41341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																							<< glu::VertexSource(genVertexSource())
41351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																							<< glu::FragmentSource(genFragmentSource())
41361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																							<< glu::TessellationControlSource(genTessellationControlSource(true))
41371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																							<< glu::TessellationEvaluationSource(genTessellationEvaluationSource())));
41381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
41401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Section("PerPrimitiveProgram", "Shader program that sets the bounding box")
41411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< *m_perPrimitiveProgram
41421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndSection;
41431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (!m_perPrimitiveProgram->isOk())
41451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			throw tcu::TestError("shader build failed");
41461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
41471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
41481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ClearCase::renderTo (tcu::Surface& dst, bool useBBox)
41501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
41511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int				numOps				= 45;
41521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4			yellow				(1.0f, 1.0f, 0.0f, 1.0f);
41531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::Vec4			green				(0.0f, 1.0f, 0.0f, 1.0f);
41541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2		renderTargetSize	(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
41551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
41561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random				rnd					(deStringHash(getName()));
41571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::VertexArray		vao					(m_context.getRenderContext());
41581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// always do the initial clear
41601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.disable(GL_SCISSOR_TEST);
41611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.viewport(0, 0, renderTargetSize.x(), renderTargetSize.y());
41621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clearColor(yellow.x(), yellow.y(), yellow.z(), yellow.w());
41631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clear(GL_COLOR_BUFFER_BIT);
41641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.finish();
41651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// prepare draw
41671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_scissoredClear)
41681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.enable(GL_SCISSOR_TEST);
41691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (m_drawTriangles)
41711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
41721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const deUint32	programHandle		= (m_useGlobalState || !useBBox) ? (m_basicProgram->getProgram()) : (m_perPrimitiveProgram->getProgram());
41731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int		positionAttribLoc	= gl.getAttribLocation(programHandle, "a_position");
41741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TCU_CHECK(positionAttribLoc != -1);
41761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.useProgram(programHandle);
41781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.bindVertexArray(*vao);
41791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.enableVertexAttribArray(positionAttribLoc);
41801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.vertexAttribPointer(positionAttribLoc, 4, GL_FLOAT, GL_FALSE, (int)sizeof(tcu::Vec4), DE_NULL);
41811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		gl.patchParameteri(GL_PATCH_VERTICES, 3);
41821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
41831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// do random scissor/clearldraw operations
41851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int opNdx = 0; opNdx < numOps; ++opNdx)
41861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
41871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int	drawObjNdx				= (m_drawTriangles) ? (rnd.getInt(0, (int)m_drawObjects.size() - 1)) : (0);
41881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int	objectVertexStartNdx	= (m_drawTriangles) ? (m_drawObjects[drawObjNdx].firstNdx) : (0);
41891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int	objectVertexLength		= (m_drawTriangles) ? (m_drawObjects[drawObjNdx].numVertices) : (0);
41901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec4	bboxMin;
41911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::Vec4	bboxMax;
41921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_drawTriangles)
41941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
41951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMin = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
41961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMax = tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f);
41971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
41981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// calc bbox
41991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			for (int vertexNdx = objectVertexStartNdx; vertexNdx < objectVertexStartNdx + objectVertexLength; ++vertexNdx)
42001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			for (int componentNdx = 0; componentNdx < 4; ++componentNdx)
42011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
42021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				bboxMin[componentNdx] = de::min(bboxMin[componentNdx], m_objectVertices[vertexNdx][componentNdx]);
42031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				bboxMax[componentNdx] = de::max(bboxMax[componentNdx], m_objectVertices[vertexNdx][componentNdx]);
42041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
42051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
42061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
42071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
42081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			// no geometry, just random something
42091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMin.x() = rnd.getFloat(-1.2f, 1.0f);
42101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMin.y() = rnd.getFloat(-1.2f, 1.0f);
42111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMin.z() = rnd.getFloat(-1.2f, 1.0f);
42121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMin.w() = 1.0f;
42131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMax.x() = bboxMin.x() + rnd.getFloat(0.2f, 1.0f);
42141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMax.y() = bboxMin.y() + rnd.getFloat(0.2f, 1.0f);
42151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMax.z() = bboxMin.z() + rnd.getFloat(0.2f, 1.0f);
42161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			bboxMax.w() = 1.0f;
42171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
42181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_scissoredClear)
42201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
42211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const int scissorX = (m_fullscreenScissor) ? (0)					: rnd.getInt(0, renderTargetSize.x()-1);
42221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const int scissorY = (m_fullscreenScissor) ? (0)					: rnd.getInt(0, renderTargetSize.y()-1);
42231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const int scissorW = (m_fullscreenScissor) ? (renderTargetSize.x())	: rnd.getInt(0, renderTargetSize.x()-scissorX);
42241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const int scissorH = (m_fullscreenScissor) ? (renderTargetSize.y())	: rnd.getInt(0, renderTargetSize.y()-scissorY);
42251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.scissor(scissorX, scissorY, scissorW, scissorH);
42271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
42281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
42301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const tcu::Vec4 color = tcu::mix(green, yellow, rnd.getFloat() * 0.4f); // greenish
42311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.clearColor(color.x(), color.y(), color.z(), color.w());
42321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.clear(GL_COLOR_BUFFER_BIT);
42331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
42341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (useBBox)
42361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
42371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			DE_ASSERT(m_useGlobalState || m_drawTriangles); // !m_useGlobalState -> m_drawTriangles
42381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			if (m_useGlobalState)
4239485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe				gl.primitiveBoundingBox(bboxMin.x(), bboxMin.y(), bboxMin.z(), bboxMin.w(),
4240485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe										bboxMax.x(), bboxMax.y(), bboxMax.z(), bboxMax.w());
42411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
42421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (m_drawTriangles)
42441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.drawArrays(GL_PATCHES, objectVertexStartNdx, objectVertexLength);
42451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
42461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "post draw");
42481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
42491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
42501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool ClearCase::verifyImagesEqual (const tcu::PixelBufferAccess& withoutBBox, const tcu::PixelBufferAccess& withBBox)
42521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
42531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(withoutBBox.getWidth() == withBBox.getWidth());
425426e8fabf4c969e2dc11d638225e7bc81c27c46f7Jarkko Pöyry	DE_ASSERT(withoutBBox.getHeight() == withBBox.getHeight());
42551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface	errorMask	(withoutBBox.getWidth(), withoutBBox.getHeight());
42571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool			anyError	= false;
42581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4259c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
42601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = 0; y < withoutBBox.getHeight(); ++y)
42621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = 0; x < withoutBBox.getWidth(); ++x)
42631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
42641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (withoutBBox.getPixelInt(x, y) != withBBox.getPixelInt(x, y))
42651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
4266c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			errorMask.setPixel(x, y, tcu::RGBA::red());
42671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			anyError = true;
42681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
42691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
42701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (anyError)
42721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
42731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
42741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
42751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image comparison failed."
42761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
42771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image comparison")
42781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("WithoutBBox", "Result with bounding box not set", withoutBBox)
42791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("WithBBox", "Result with bounding box set", withBBox)
42801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
42811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
42821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
42831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return !anyError;
42851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
42861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool ClearCase::verifyImageResultValid (const tcu::PixelBufferAccess& result)
42881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
42891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface	errorMask	(result.getWidth(), result.getHeight());
42901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool			anyError	= false;
42911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4292c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
42931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = 0; y < result.getHeight(); ++y)
42951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = 0; x < result.getWidth(); ++x)
42961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
42971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::IVec4 pixel = result.getPixelInt(x, y);
42981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
42991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// allow green, yellow and any shade between
43001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (pixel[1] != 255 || pixel[2] != 0)
43011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
4302c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			errorMask.setPixel(x, y, tcu::RGBA::red());
43031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			anyError = true;
43041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
43051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
43061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (anyError)
43081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
43091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
43101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
43111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image verification failed."
43121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
43131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
43141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("ResultImage", "Result image", result)
43151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
43161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
43171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
43181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return !anyError;
43201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
43211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystatic const char* const s_yellowishPosOnlyVertexSource =	"#version 310 es\n"
43231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"in highp vec4 a_position;\n"
43241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"out highp vec4 v_vertex_color;\n"
43251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"void main()\n"
43261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"{\n"
43271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"	gl_Position = a_position;\n"
43281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"	// yellowish shade\n"
43291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"	highp float redComponent = 0.5 + float(gl_VertexID % 5) / 8.0;\n"
43301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"	v_vertex_color = vec4(redComponent, 1.0, 0.0, 1.0);\n"
43311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry															"}\n";
43321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystatic const char* const s_basicColorFragmentSource =	"#version 310 es\n"
43341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"in mediump vec4 v_color;\n"
43351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"layout(location = 0) out mediump vec4 o_color;\n"
43361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"void main()\n"
43371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"{\n"
43381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"	o_color = v_color;\n"
43391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"}\n";
43401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystatic const char* const s_basicColorTessEvalSource =	"#version 310 es\n"
43431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"#extension GL_EXT_tessellation_shader : require\n"
43441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"#extension GL_EXT_gpu_shader5 : require\n"
43451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"layout(triangles) in;\n"
43461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"in highp vec4 v_tess_eval_color[];\n"
43471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"out highp vec4 v_color;\n"
43481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"precise gl_Position;\n"
43491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"void main()\n"
43501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"{\n"
43511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"	gl_Position = gl_TessCoord.x * gl_in[0].gl_Position\n"
43521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"	            + gl_TessCoord.y * gl_in[1].gl_Position\n"
43531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"	            + gl_TessCoord.z * gl_in[2].gl_Position;\n"
43541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"	v_color = gl_TessCoord.x * v_tess_eval_color[0]\n"
43551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"	        + gl_TessCoord.y * v_tess_eval_color[1]\n"
43561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"	        + gl_TessCoord.z * v_tess_eval_color[2];\n"
43571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry														"}\n";
43581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string ClearCase::genVertexSource (void) const
43601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
43611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return	s_yellowishPosOnlyVertexSource;
43621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
43631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string ClearCase::genFragmentSource (void) const
43651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
43661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return s_basicColorFragmentSource;
43671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
43681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string ClearCase::genTessellationControlSource (bool setBBox) const
43701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
43711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::ostringstream buf;
43721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"#version 310 es\n"
43741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n";
43751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (setBBox)
43771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf << "#extension GL_EXT_primitive_bounding_box : require\n";
43781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf <<	"layout(vertices=3) out;\n"
43801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 v_vertex_color[];\n"
43811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 v_tess_eval_color[];\n"
43821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
43831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
43841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
43851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_tess_eval_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
43861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[0] = 2.8;\n"
43871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[1] = 2.8;\n"
43881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[2] = 2.8;\n"
43891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelInner[0] = 2.8;\n";
43901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
43911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (setBBox)
43921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
43931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		buf <<	"\n"
43941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		"	gl_BoundingBoxEXT[0] = min(min(gl_in[0].gl_Position,\n"
43951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		"	                               gl_in[1].gl_Position),\n"
43961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		"	                           gl_in[2].gl_Position);\n"
43971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		"	gl_BoundingBoxEXT[1] = max(max(gl_in[0].gl_Position,\n"
43981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		"	                               gl_in[1].gl_Position),\n"
43991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		"	                           gl_in[2].gl_Position);\n";
44001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
44011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	buf << "}\n";
44031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return buf.str();
44041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
44051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string ClearCase::genTessellationEvaluationSource (void) const
44071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
44081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return s_basicColorTessEvalSource;
44091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
44101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryclass ViewportCallOrderCase : public TestCase
44121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
44131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrypublic:
44141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum CallOrder
44151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
44161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		VIEWPORT_FIRST = 0,
44171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		BBOX_FIRST,
44181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		ORDER_LAST
44201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
44211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									ViewportCallOrderCase			(Context& context, const char* name, const char* description, CallOrder callOrder);
44231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry									~ViewportCallOrderCase			(void);
44241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryprivate:
44261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							init							(void);
44271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							deinit							(void);
44281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	IterateResult					iterate							(void);
44291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							genVbo							(void);
44311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	void							genProgram						(void);
44321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool							verifyImage						(const tcu::PixelBufferAccess& result);
44331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genVertexSource					(void) const;
44351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genFragmentSource				(void) const;
44361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genTessellationControlSource	(void) const;
44371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::string						genTessellationEvaluationSource	(void) const;
44381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const CallOrder					m_callOrder;
44401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::Buffer>		m_vbo;
44421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::MovePtr<glu::ShaderProgram>	m_program;
44431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	int								m_numVertices;
44441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry};
44451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryViewportCallOrderCase::ViewportCallOrderCase (Context& context, const char* name, const char* description, CallOrder callOrder)
44471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: TestCase		(context, name, description)
44481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_callOrder	(callOrder)
44491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	, m_numVertices	(-1)
44501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
44511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	DE_ASSERT(m_callOrder < ORDER_LAST);
44521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
44531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryViewportCallOrderCase::~ViewportCallOrderCase (void)
44551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
44561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	deinit();
44571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
44581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ViewportCallOrderCase::init (void)
44601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
44611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"))
44621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
44631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4464c22e16e65c11afffe24ad5c07f255a9f38b11231Mika Isojärvi	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
4465c22e16e65c11afffe24ad5c07f255a9f38b11231Mika Isojärvi		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
4466c22e16e65c11afffe24ad5c07f255a9f38b11231Mika Isojärvi
44671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
44681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
44691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Testing call order of state setting functions have no effect on the rendering.\n"
44701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Setting viewport and bounding box in the following order:\n"
44711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_callOrder == VIEWPORT_FIRST)
44721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				? ("\tFirst viewport with glViewport function.\n")
44731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				: ("\tFirst bounding box with glPrimitiveBoundingBoxEXT function.\n"))
44741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< ((m_callOrder == VIEWPORT_FIRST)
44751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				? ("\tThen bounding box with glPrimitiveBoundingBoxEXT function.\n")
44761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				: ("\tThen viewport with glViewport function.\n"))
44771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Verifying rendering result."
44781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
44791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// resources
44811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	genVbo();
44821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	genProgram();
44831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
44841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ViewportCallOrderCase::deinit (void)
44861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
44871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_vbo.clear();
44881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_program.clear();
44891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
44901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryViewportCallOrderCase::IterateResult ViewportCallOrderCase::iterate (void)
44921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
44931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
44941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const tcu::IVec2		viewportSize	= tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
44951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::GLint		posLocation		= gl.getAttribLocation(m_program->getProgram(), "a_position");
44961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface			resultSurface	(viewportSize.x(), viewportSize.y());
44971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
44981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
44991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.clear(GL_COLOR_BUFFER_BIT);
45001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// set state
45021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int orderNdx = 0; orderNdx < 2; ++orderNdx)
45031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
45041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if ((orderNdx == 0 && m_callOrder == VIEWPORT_FIRST) ||
45051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			(orderNdx == 1 && m_callOrder == BBOX_FIRST))
45061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
45071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog()
45081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< tcu::TestLog::Message
45091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "Setting viewport to cover the left half of the render target.\n"
45101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\t(0, 0, " << (viewportSize.x()/2) << ", " << viewportSize.y() << ")"
45111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< tcu::TestLog::EndMessage;
45121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			gl.viewport(0, 0, viewportSize.x()/2, viewportSize.y());
45141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
45151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
45161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
45171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			m_testCtx.getLog()
45181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< tcu::TestLog::Message
45191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "Setting bounding box to cover the right half of the clip space.\n"
45201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< "\t(0.0, -1.0, -1.0, 1.0) .. (1.0, 1.0, 1.0f, 1.0)"
45211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				<< tcu::TestLog::EndMessage;
45221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4523485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe			gl.primitiveBoundingBox(0.0f, -1.0f, -1.0f, 1.0f,
4524485a2d1c89e689e6b8523fc3b9c146c63e92bfd7Daniel Andrade Groppe									1.0f,  1.0f,  1.0f, 1.0f);
45251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
45261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
45271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
45291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
45301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Rendering mesh covering the right half of the clip space."
45311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
45321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
45341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, sizeof(float[4]), (const float*)DE_NULL);
45351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.enableVertexAttribArray(posLocation);
45361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.useProgram(m_program->getProgram());
45371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.patchParameteri(GL_PATCH_VERTICES, 3);
45381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.drawArrays(GL_PATCHES, 0, m_numVertices);
45391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "post-draw");
45401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
45421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Message
45431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< "Verifying image"
45441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndMessage;
45451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
45461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!verifyImage(resultSurface.getAccess()))
45481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
45491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	else
45501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
45511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
45521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
45531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Result ok."
45541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
45551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
45561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("Result", "Result", resultSurface.getAccess())
45571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
45581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
45601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
45611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return STOP;
45621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
45631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ViewportCallOrderCase::genVbo (void)
45651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
45661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const int				gridSize	= 6;
45671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
45681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<tcu::Vec4>	data		(gridSize * gridSize * 2 * 3);
45691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	std::vector<int>		cellOrder	(gridSize * gridSize * 2);
45701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	de::Random				rnd			(0x55443322);
45711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// generate grid with triangles in random order
45731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
45741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		cellOrder[ndx] = ndx;
45751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	rnd.shuffle(cellOrder.begin(), cellOrder.end());
45761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// generate grid filling the right half of the clip space: (x: 0.0, y: -1.0) .. (x: 1.0, y: 1.0)
45781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
45791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
45801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellNdx		= cellOrder[ndx];
45811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool			cellSide	= ((cellNdx % 2) == 0);
45821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellX		= (cellNdx / 2) % gridSize;
45831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const int			cellY		= (cellNdx / 2) / gridSize;
45841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if (cellSide)
45861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
45877a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[ndx * 3 + 0] = tcu::Vec4(float(cellX+0) / float(gridSize), (float(cellY+0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
45887a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[ndx * 3 + 1] = tcu::Vec4(float(cellX+1) / float(gridSize), (float(cellY+1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
45897a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[ndx * 3 + 2] = tcu::Vec4(float(cellX+0) / float(gridSize), (float(cellY+1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
45901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
45911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		else
45921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
45937a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[ndx * 3 + 0] = tcu::Vec4(float(cellX+0) / float(gridSize), (float(cellY+0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
45947a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[ndx * 3 + 1] = tcu::Vec4(float(cellX+1) / float(gridSize), (float(cellY+0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
45957a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry			data[ndx * 3 + 2] = tcu::Vec4(float(cellX+1) / float(gridSize), (float(cellY+1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
45961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
45971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
45981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
45991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
46001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
46011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	gl.bufferData(GL_ARRAY_BUFFER, (int)(data.size() * sizeof(tcu::Vec4)), &data[0], GL_STATIC_DRAW);
46021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	GLU_EXPECT_NO_ERROR(gl.getError(), "create vbo");
46031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_numVertices = (int)data.size();
46051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
46061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid ViewportCallOrderCase::genProgram (void)
46081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
46091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(),
46101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																	   glu::ProgramSources()
46111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																			<< glu::VertexSource(genVertexSource())
46121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																			<< glu::FragmentSource(genFragmentSource())
46131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																			<< glu::TessellationControlSource(genTessellationControlSource())
46141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry																			<< glu::TessellationEvaluationSource(genTessellationEvaluationSource())));
46151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	m_testCtx.getLog()
46171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::Section("Program", "Shader program")
46181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< *m_program
46191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		<< tcu::TestLog::EndSection;
46201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (!m_program->isOk())
46221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		throw tcu::TestError("shader build failed");
46231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
46241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrybool ViewportCallOrderCase::verifyImage (const tcu::PixelBufferAccess& result)
46261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
46277a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	const tcu::IVec2	insideBorder	(deCeilFloatToInt32(0.25f * (float)result.getWidth()) + 1, deFloorFloatToInt32(0.5f * (float)result.getWidth()) - 1);
46287a161d243743d8d12e12669d7464c360de1b5e97Jarkko Pöyry	const tcu::IVec2	outsideBorder	(deFloorFloatToInt32(0.25f * (float)result.getWidth()) - 1, deCeilFloatToInt32(0.5f * (float)result.getWidth()) + 1);
46291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	tcu::Surface		errorMask		(result.getWidth(), result.getHeight());
46301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	bool				anyError		= false;
46311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
4632c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski	tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
46331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int y = 0; y < result.getHeight(); ++y)
46351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int x = 0; x < result.getWidth(); ++x)
46361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
46371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const tcu::IVec4	pixel			= result.getPixelInt(x, y);
46381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool			insideMeshArea	= x >= insideBorder.x() && x <= insideBorder.x();
46391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const bool			outsideMeshArea = x <= outsideBorder.x() && x >= outsideBorder.x();
46401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// inside mesh, allow green, yellow and any shade between
46421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// outside mesh, allow background (black) only
46431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// in the border area, allow anything
46441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		if ((insideMeshArea && (pixel[1] != 255 || pixel[2] != 0)) ||
46451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			(outsideMeshArea && (pixel[0] != 0 || pixel[1] != 0 || pixel[2] != 0)))
46461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
4647c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			errorMask.setPixel(x, y, tcu::RGBA::red());
46481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			anyError = true;
46491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
46501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
46511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	if (anyError)
46531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
46541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		m_testCtx.getLog()
46551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Message
46561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< "Image verification failed."
46571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndMessage
46581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::ImageSet("Images", "Image verification")
46591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("ResultImage", "Result image", result)
46601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
46611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			<< tcu::TestLog::EndImageSet;
46621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
46631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return !anyError;
46651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
46661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string ViewportCallOrderCase::genVertexSource (void) const
46681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
46691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return	s_yellowishPosOnlyVertexSource;
46701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
46711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string ViewportCallOrderCase::genFragmentSource (void) const
46731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
46741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return s_basicColorFragmentSource;
46751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
46761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string ViewportCallOrderCase::genTessellationControlSource (void) const
46781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
46791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return	"#version 310 es\n"
46801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"#extension GL_EXT_tessellation_shader : require\n"
46811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"layout(vertices=3) out;\n"
46821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"in highp vec4 v_vertex_color[];\n"
46831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"out highp vec4 v_tess_eval_color[];\n"
46841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"void main()\n"
46851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"{\n"
46861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
46871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	v_tess_eval_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
46881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[0] = 2.8;\n"
46891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[1] = 2.8;\n"
46901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelOuter[2] = 2.8;\n"
46911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"	gl_TessLevelInner[0] = 2.8;\n"
46921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"}\n";
46931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
46941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
46951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyrystd::string ViewportCallOrderCase::genTessellationEvaluationSource (void) const
46961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
46971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	return s_basicColorTessEvalSource;
46981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
46991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
47001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry} // anonymous
47011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
47021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryPrimitiveBoundingBoxTests::PrimitiveBoundingBoxTests (Context& context)
47031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	: TestCaseGroup(context, "primitive_bounding_box", "Tests for EXT_primitive_bounding_box")
47041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
47051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
47061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
47071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko PöyryPrimitiveBoundingBoxTests::~PrimitiveBoundingBoxTests (void)
47081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
47091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
47101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
47111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyryvoid PrimitiveBoundingBoxTests::init (void)
47121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry{
47131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	static const struct
47141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
47151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const char*	name;
47161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const char*	description;
47171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		deUint32	methodFlags;
47181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	} stateSetMethods[] =
47191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
47201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"global_state",
47221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Set bounding box using PRIMITIVE_BOUNDING_BOX_EXT state",
47231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_SET_BBOX_STATE,
47241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"tessellation_set_per_draw",
47271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Set bounding box using gl_BoundingBoxEXT, use same value for all primitives",
47281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_SET_BBOX_OUTPUT,
47291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"tessellation_set_per_primitive",
47321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Set bounding box using gl_BoundingBoxEXT, use per-primitive bounding box",
47331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_SET_BBOX_OUTPUT | BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
47341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
47361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	static const struct
47371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
47381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const char*	name;
47391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const char*	description;
47401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		deUint32	stageFlags;
47411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	} pipelineConfigs[] =
47421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
47431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"vertex_fragment",
47451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render with vertex-fragment program",
47461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0u
47471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"vertex_tessellation_fragment",
47501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render with vertex-tessellation{ctrl,eval}-fragment program",
47511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_TESSELLATION
47521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"vertex_geometry_fragment",
47551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render with vertex-tessellation{ctrl,eval}-geometry-fragment program",
47561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_GEOMETRY
47571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"vertex_tessellation_geometry_fragment",
47601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render with vertex-geometry-fragment program",
47611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_TESSELLATION | BBoxRenderCase::FLAG_GEOMETRY
47621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
47641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	static const struct
47651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
47661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const char*	name;
47671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const char*	description;
47681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		deUint32	flags;
47691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		deUint32	invalidFlags;
47701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		deUint32	requiredFlags;
47711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	} usageConfigs[] =
47721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
47731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"default_framebuffer_bbox_equal",
47751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render to default framebuffer, set tight bounding box",
47761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
47771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
47781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
47791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"default_framebuffer_bbox_larger",
47821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render to default framebuffer, set padded bounding box",
47831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_LARGER,
47841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
47851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
47861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"default_framebuffer_bbox_smaller",
47891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render to default framebuffer, set too small bounding box",
47901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_SMALLER,
47911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
47921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
47931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
47941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
47951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"fbo_bbox_equal",
47961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render to texture, set tight bounding box",
47971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
47981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
47991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
48001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"fbo_bbox_larger",
48031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render to texture, set padded bounding box",
48041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_LARGER,
48051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
48061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
48071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"fbo_bbox_smaller",
48101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render to texture, set too small bounding box",
48111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_SMALLER,
48121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
48131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
48141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"default_framebuffer",
48171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render to default framebuffer, set tight bounding box",
48181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
48191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0,
48201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX
48211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"fbo",
48241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Render to texture, set tight bounding box",
48251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
48261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0,
48271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX
48281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
48301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	enum PrimitiveRenderType
48311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
48321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TYPE_TRIANGLE,
48331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TYPE_LINE,
48341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		TYPE_POINT,
48351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
48361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	const struct
48371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
48381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const char*			name;
48391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		const char*			description;
48401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		PrimitiveRenderType	type;
48411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		deUint32			flags;
48421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	} primitiveTypes[] =
48431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
48441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"triangles",
48461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Triangle render tests",
48471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			TYPE_TRIANGLE,
48481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
48491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"lines",
48521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Line render tests",
48531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			TYPE_LINE,
48541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
48551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"points",
48581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Point render tests",
48591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			TYPE_POINT,
48601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			0
48611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"wide_lines",
48641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Wide line render tests",
48651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			TYPE_LINE,
48661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			LineRenderCase::LINEFLAG_WIDE
48671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"wide_points",
48701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			"Wide point render tests",
48711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			TYPE_POINT,
48721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			PointRenderCase::POINTFLAG_WIDE
48731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		},
48741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	};
48751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
48761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// .state_query
48771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
48781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::TestCaseGroup* const stateQueryGroup = new tcu::TestCaseGroup(m_testCtx, "state_query", "State queries");
48791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		addChild(stateQueryGroup);
48801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
48811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		stateQueryGroup->addChild(new InitialValueCase	(m_context,	"initial_value",	"Initial value case"));
48821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		stateQueryGroup->addChild(new QueryCase			(m_context,	"getfloat",			"getFloatv",			QueryCase::QUERY_FLOAT));
48831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		stateQueryGroup->addChild(new QueryCase			(m_context,	"getboolean",		"getBooleanv",			QueryCase::QUERY_BOOLEAN));
48841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		stateQueryGroup->addChild(new QueryCase			(m_context,	"getinteger",		"getIntegerv",			QueryCase::QUERY_INT));
48851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		stateQueryGroup->addChild(new QueryCase			(m_context,	"getinteger64",		"getInteger64v",		QueryCase::QUERY_INT64));
48861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
48871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
48881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// .triangles
48891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// .(wide_)lines
48901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// .(wide_)points
48911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
48921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
48931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(m_testCtx, primitiveTypes[primitiveTypeNdx].name, primitiveTypes[primitiveTypeNdx].description);
48941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		addChild(primitiveGroup);
48951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
48961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int stateSetMethodNdx = 0; stateSetMethodNdx < DE_LENGTH_OF_ARRAY(stateSetMethods); ++stateSetMethodNdx)
48971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
48981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tcu::TestCaseGroup* const methodGroup = new tcu::TestCaseGroup(m_testCtx, stateSetMethods[stateSetMethodNdx].name, stateSetMethods[stateSetMethodNdx].description);
48991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			primitiveGroup->addChild(methodGroup);
49001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
49011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			for (int pipelineConfigNdx = 0; pipelineConfigNdx < DE_LENGTH_OF_ARRAY(pipelineConfigs); ++pipelineConfigNdx)
49021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
49031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				if ((stateSetMethods[stateSetMethodNdx].methodFlags & BBoxRenderCase::FLAG_SET_BBOX_OUTPUT) != 0 &&
49041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					(pipelineConfigs[pipelineConfigNdx].stageFlags  & BBoxRenderCase::FLAG_TESSELLATION)    == 0)
49051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
49061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					// invalid config combination
49071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
49081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				else
49091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				{
49101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					tcu::TestCaseGroup* const pipelineGroup = new tcu::TestCaseGroup(m_testCtx, pipelineConfigs[pipelineConfigNdx].name, pipelineConfigs[pipelineConfigNdx].description);
49111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					methodGroup->addChild(pipelineGroup);
49121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
49131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageConfigs); ++usageNdx)
49141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					{
49151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						const deUint32 flags = primitiveTypes[primitiveTypeNdx].flags         |
49161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry											   stateSetMethods[stateSetMethodNdx].methodFlags |
49171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry											   pipelineConfigs[pipelineConfigNdx].stageFlags  |
49181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry											   usageConfigs[usageNdx].flags;
49191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
49201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						if (usageConfigs[usageNdx].invalidFlags && (flags & usageConfigs[usageNdx].invalidFlags) != 0)
49211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							continue;
49221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						if (usageConfigs[usageNdx].requiredFlags && (flags & usageConfigs[usageNdx].requiredFlags) == 0)
49231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							continue;
49241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
49251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						switch (primitiveTypes[primitiveTypeNdx].type)
49261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						{
49271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							case TYPE_TRIANGLE:
49281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry								pipelineGroup->addChild(new GridRenderCase(m_context, usageConfigs[usageNdx].name, usageConfigs[usageNdx].description, flags));
49291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry								break;
49301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							case TYPE_LINE:
49311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry								pipelineGroup->addChild(new LineRenderCase(m_context, usageConfigs[usageNdx].name, usageConfigs[usageNdx].description, flags));
49321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry								break;
49331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							case TYPE_POINT:
49341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry								pipelineGroup->addChild(new PointRenderCase(m_context, usageConfigs[usageNdx].name, usageConfigs[usageNdx].description, flags));
49351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry								break;
49361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry							default:
49371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry								DE_ASSERT(false);
49381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry						}
49391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry					}
49401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				}
49411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			}
49421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
49431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
49441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
49451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// .depth
49461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
49471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		static const struct
49481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
49491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const char*					name;
49501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const char*					description;
49511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			DepthDrawCase::DepthType	depthMethod;
49521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		} depthMethods[] =
49531f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
49541f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
49551f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"builtin_depth",
49561f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"Fragment depth not modified in fragment shader",
49571f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::DEPTH_BUILTIN
49581f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			},
49591f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
49601f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"user_defined_depth",
49611f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"Fragment depth is defined in the fragment shader",
49621f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::DEPTH_USER_DEFINED
49631f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			},
49641f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		};
49651f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		static const struct
49661f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
49671f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const char*					name;
49681f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			const char*					description;
49691f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			DepthDrawCase::BBoxState	bboxState;
49701f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			DepthDrawCase::BBoxSize		bboxSize;
49711f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		} depthCases[] =
49721f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
49731f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
49741f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"global_state_bbox_equal",
49751f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"Test tight bounding box with global bbox state",
49761f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::STATE_GLOBAL,
49771f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::BBOX_EQUAL,
49781f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			},
49791f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
49801f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"global_state_bbox_larger",
49811f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"Test padded bounding box with global bbox state",
49821f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::STATE_GLOBAL,
49831f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::BBOX_LARGER,
49841f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			},
49851f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
49861f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"per_primitive_bbox_equal",
49871f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"Test tight bounding box with tessellation output bbox",
49881f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::STATE_PER_PRIMITIVE,
49891f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::BBOX_EQUAL,
49901f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			},
49911f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			{
49921f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"per_primitive_bbox_larger",
49931f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				"Test padded bounding box with tessellation output bbox",
49941f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::STATE_PER_PRIMITIVE,
49951f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				DepthDrawCase::BBOX_LARGER,
49961f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			},
49971f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		};
49981f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
49991f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::TestCaseGroup* const depthGroup = new tcu::TestCaseGroup(m_testCtx, "depth", "Test bounding box depth component");
50001f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		addChild(depthGroup);
50011f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50021f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// .builtin_depth
50031f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		// .user_defined_depth
50041f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		for (int depthNdx = 0; depthNdx < DE_LENGTH_OF_ARRAY(depthMethods); ++depthNdx)
50051f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		{
50061f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, depthMethods[depthNdx].name, depthMethods[depthNdx].description);
50071f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			depthGroup->addChild(group);
50081f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50091f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(depthCases); ++caseNdx)
50101f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry				group->addChild(new DepthDrawCase(m_context, depthCases[caseNdx].name, depthCases[caseNdx].description, depthMethods[depthNdx].depthMethod, depthCases[caseNdx].bboxState, depthCases[caseNdx].bboxSize));
50111f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		}
50121f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
50131f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50141f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// .blit_fbo
50151f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
50161f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::TestCaseGroup* const blitFboGroup = new tcu::TestCaseGroup(m_testCtx, "blit_fbo", "Test bounding box does not affect blitting");
50171f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		addChild(blitFboGroup);
50181f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50191f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		blitFboGroup->addChild(new BlitFboCase(m_context, "blit_default_to_fbo", "Blit from default fb to fbo", BlitFboCase::TARGET_DEFAULT, BlitFboCase::TARGET_FBO));
50201f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		blitFboGroup->addChild(new BlitFboCase(m_context, "blit_fbo_to_default", "Blit from fbo to default fb", BlitFboCase::TARGET_FBO,     BlitFboCase::TARGET_DEFAULT));
50211f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		blitFboGroup->addChild(new BlitFboCase(m_context, "blit_fbo_to_fbo",     "Blit from fbo to fbo",        BlitFboCase::TARGET_FBO,     BlitFboCase::TARGET_FBO));
50221f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
50231f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50241f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// .clear
50251f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
50261f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::TestCaseGroup* const clearGroup = new tcu::TestCaseGroup(m_testCtx, "clear", "Test bounding box does not clears");
50271f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		addChild(clearGroup);
50281f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50291f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "full_clear",                                             "Do full clears",                                               0));
50301f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "full_clear_with_triangles",                              "Do full clears and render some geometry",                      ClearCase::DRAW_TRIANGLE_BIT));
50311f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "full_clear_with_triangles_per_primitive_bbox",           "Do full clears and render some geometry",                      ClearCase::DRAW_TRIANGLE_BIT | ClearCase::PER_PRIMITIVE_BBOX_BIT));
50321f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "scissored_clear",                                        "Do scissored clears",                                          ClearCase::SCISSOR_CLEAR_BIT));
50331f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "scissored_clear_with_triangles",                         "Do scissored clears and render some geometry",                 ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT));
50341f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "scissored_clear_with_triangles_per_primitive_bbox",      "Do scissored clears and render some geometry",                 ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT | ClearCase::PER_PRIMITIVE_BBOX_BIT));
50351f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear",                                   "Do full clears with enabled scissor",                          ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT));
50361f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear_with_triangles",                    "Do full clears with enabled scissor and render some geometry", ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT));
50371f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear_with_triangles_per_primitive_bbox", "Do full clears with enabled scissor and render some geometry", ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT | ClearCase::PER_PRIMITIVE_BBOX_BIT));
50381f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
50391f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50401f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	// .call_order (Khronos bug #13262)
50411f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	{
50421f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		tcu::TestCaseGroup* const callOrderGroup = new tcu::TestCaseGroup(m_testCtx, "call_order", "Test viewport and bounding box calls have no effect");
50431f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		addChild(callOrderGroup);
50441f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50451f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		callOrderGroup->addChild(new ViewportCallOrderCase(m_context, "viewport_first_bbox_second", "Set up viewport first and bbox after", ViewportCallOrderCase::VIEWPORT_FIRST));
50461f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry		callOrderGroup->addChild(new ViewportCallOrderCase(m_context, "bbox_first_viewport_second", "Set up bbox first and viewport after", ViewportCallOrderCase::BBOX_FIRST));
50471f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry	}
50481f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry}
50491f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry
50501f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry} // Functional
50511f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry} // gles31
50521f99d6991ce9a27d32ec0543d95646fe4e7bf001Jarkko Pöyry} // deqp
5053