13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 2.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Polygon offset tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2fPolygonOffsetTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwDefs.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestContext.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrRenderer.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrFragmentOperations.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sglrReferenceContext.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw; // GLint and other GL types
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* s_shaderSourceVertex	= "attribute highp vec4 a_position;\n"
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "attribute highp vec4 a_color;\n"
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "varying mediump vec4 v_color;\n"
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "void main (void)\n"
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "{\n"
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "	gl_Position = a_position;\n"
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "	v_color = a_color;\n"
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "}\n";
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* s_shaderSourceFragment	= "varying mediump vec4 v_color;\n"
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "void main (void)\n"
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "{\n"
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "	gl_FragColor = v_color;\n"
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "}\n";
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const tcu::Vec4	MASK_COLOR_OK	= tcu::Vec4(0.0f, 0.1f, 0.0f, 1.0f);
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const tcu::Vec4	MASK_COLOR_DEV	= tcu::Vec4(0.8f, 0.5f, 0.0f, 1.0f);
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const tcu::Vec4	MASK_COLOR_FAIL	= tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool compareThreshold (const tcu::IVec4& a, const tcu::IVec4& b, const tcu::IVec4& threshold)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::boolAll(tcu::lessThanEqual(tcu::abs(a - b), threshold));
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry* \brief Pixelwise comparison of two images.
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry* \note copied & modified from glsRasterizationTests
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry*
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry* Kernel radius defines maximum allowed distance. If radius is 0, only
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry* perfect match is allowed. Radius of 1 gives a 3x3 kernel.
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry*
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry* Return values: -1 = Perfect match
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry* 0 = Deviation within kernel
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry* >0 = Number of faulty pixels
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry*//*--------------------------------------------------------------------*/
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint compareImages (tcu::TestLog& log, glu::RenderContext& renderCtx, const tcu::ConstPixelBufferAccess& test, const tcu::ConstPixelBufferAccess& ref, const tcu::PixelBufferAccess& diffMask, int radius)
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			height			= test.getHeight();
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			width			= test.getWidth();
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			colorThreshold	= 128;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		formatThreshold	= renderCtx.getRenderTarget().getPixelFormat().getColorThreshold();
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec4	threshold		= tcu::IVec4(colorThreshold, colorThreshold, colorThreshold, formatThreshold.getAlpha() > 0 ? colorThreshold : 0)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										+ tcu::IVec4(formatThreshold.getRed(), formatThreshold.getGreen(), formatThreshold.getBlue(), formatThreshold.getAlpha());
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			deviatingPixels = 0;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			faultyPixels	= 0;
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			compareFailed	= -1;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(diffMask, MASK_COLOR_OK);
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < height; y++)
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < width; x++)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::IVec4 cRef = ref.getPixelInt(x, y);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Pixelwise match, no deviation or fault
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::IVec4 cTest = test.getPixelInt(x, y);
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (compareThreshold(cRef, cTest, threshold))
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// If not, search within kernel radius
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int kYmin = deMax32(y - radius, 0);
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int kYmax = deMin32(y + radius, height-1);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int kXmin = deMax32(x - radius, 0);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int kXmax = deMin32(x + radius, width-1);
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool found = false;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int kY = kYmin; kY <= kYmax; kY++)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int kX = kXmin; kX <= kXmax; kX++)
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::IVec4 cTest = test.getPixelInt(kX, kY);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (compareThreshold(cRef, cTest, threshold))
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						found = true;
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (found)	// The pixel is deviating if the color is found inside the kernel
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					diffMask.setPixel(MASK_COLOR_DEV, x, y);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (compareFailed == -1)
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						compareFailed = 0;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deviatingPixels++;
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			diffMask.setPixel(MASK_COLOR_FAIL, x, y);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			faultyPixels++;										// The pixel is faulty if the color is not found
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			compareFailed = 1;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << tcu::TestLog::Message << faultyPixels << " faulty pixel(s) found." << tcu::TestLog::EndMessage;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (compareFailed == 1 ? faultyPixels : compareFailed);
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid verifyImages (tcu::TestLog& log, tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const tcu::ConstPixelBufferAccess& testImage, const tcu::ConstPixelBufferAccess& referenceImage)
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			kernelRadius		= 1;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			faultyPixelLimit	= 20;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					faultyPixels;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		diffMask			(testImage.getWidth(), testImage.getHeight());
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	faultyPixels = compareImages(log, renderCtx, referenceImage, testImage, diffMask.getAccess(), kernelRadius);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (faultyPixels > faultyPixelLimit)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::ImageSet("Images", "Image comparison");
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("Test image", "Test image", testImage);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("Reference image", "Reference image", referenceImage);
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("Difference mask", "Difference mask", diffMask.getAccess());
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::EndImageSet;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid verifyError (tcu::TestContext& testCtx, const glw::Functions& gl, GLenum expected)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 got = gl.getError();
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (got != expected)
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		testCtx.getLog() << tcu::TestLog::Message << "// ERROR: expected " << glu::getErrorStr(expected) << "; got " << glu::getErrorStr(got) << tcu::TestLog::EndMessage;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid error");
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid checkCanvasSize (int width, int height, int minWidth, int minHeight)
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (width < minWidth || height < minHeight)
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError(std::string("Render context size must be at least ") + de::toString(minWidth) + "x" + de::toString(minWidth));
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PositionColorShader : public sglr::ShaderProgram
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VARYINGLOC_COLOR = 0
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PositionColorShader (void);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	shadeVertices		(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	shadeFragments		(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPositionColorShader::PositionColorShader (void)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexSource(s_shaderSourceVertex)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::FragmentSource(s_shaderSourceFragment))
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PositionColorShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int positionAttrLoc = 0;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int colorAttrLoc = 1;
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::VertexPacket& packet = *packets[packetNdx];
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Transform to position
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packet.position = rr::readVertexAttribFloat(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx);
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Pass color to FS
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packet.outputs[VARYINGLOC_COLOR] = rr::readVertexAttribFloat(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx);
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PositionColorShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::FragmentPacket& packet = packets[packetNdx];
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readTriangleVarying<float>(packet, context, VARYINGLOC_COLOR, fragNdx));
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// PolygonOffsetTestCase
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PolygonOffsetTestCase : public TestCase
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					PolygonOffsetTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName, int canvasSize);
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void	testPolygonOffset		(void) = DE_NULL;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate					(void);
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLenum	m_internalFormat;
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		m_internalFormatName;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		m_targetSize;
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPolygonOffsetTestCase::PolygonOffsetTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName, int canvasSize)
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat		(internalFormat)
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormatName	(internalFormatName)
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_targetSize			(canvasSize)
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPolygonOffsetTestCase::IterateResult PolygonOffsetTestCase::iterate (void)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Testing PolygonOffset with " << m_internalFormatName << " depth buffer." << tcu::TestLog::EndMessage;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_internalFormat == 0)
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// default framebuffer
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int width		= m_context.getRenderTarget().getWidth();
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int height	= m_context.getRenderTarget().getHeight();
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		checkCanvasSize(width, height, m_targetSize, m_targetSize);
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_context.getRenderTarget().getDepthBits() == 0)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("polygon offset tests require depth buffer");
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		testPolygonOffset();
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// framebuffer object
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLuint	colorRboId	= 0;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLuint	depthRboId	= 0;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLuint	fboId		= 0;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	fboComplete;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genRenderbuffers(1, &colorRboId);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, colorRboId);
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, m_targetSize, m_targetSize);
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyError(m_testCtx, gl, GL_NO_ERROR);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genRenderbuffers(1, &depthRboId);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, depthRboId);
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.renderbufferStorage(GL_RENDERBUFFER, m_internalFormat, m_targetSize, m_targetSize);
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyError(m_testCtx, gl, GL_NO_ERROR);
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genFramebuffers(1, &fboId);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRboId);
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,	GL_RENDERBUFFER, depthRboId);
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyError(m_testCtx, gl, GL_NO_ERROR);
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fboComplete = gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (fboComplete)
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testPolygonOffset();
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteFramebuffers(1, &fboId);
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteRenderbuffers(1, &depthRboId);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteRenderbuffers(1, &colorRboId);
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!fboComplete)
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("could not create fbo for testing.");
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// UsageTestCase
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UsageTestCase : public PolygonOffsetTestCase
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UsageTestCase		(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	testPolygonOffset	(void);
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUsageTestCase::UsageTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UsageTestCase::testPolygonOffset (void)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangle[] =
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1,  1,  0,  1),
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1,  1,  0,  1),
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1, -1,  0,  1),
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&		log				= m_testCtx.getLog();
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		testImage		(m_targetSize, m_targetSize);
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render test image
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << program;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Shader compile failed.");
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor				(0, 0, 0, 1);
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearDepthf				(1.0f);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport					(0, 0, m_targetSize, m_targetSize);
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(program.getProgram());
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_DEPTH_TEST);
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.depthFunc				(GL_LEQUAL);	// make test pass if polygon offset doesn't do anything. It has its own test case. This test is only for to detect always-on cases.
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "DepthFunc = GL_LEQUAL" << TestLog::EndMessage;
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray	(positionLoc);
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle);
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//draw back (offset disabled)
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Draw bottom-right. Color = White.\tState: PolygonOffset(0, -2), POLYGON_OFFSET_FILL disabled." << TestLog::EndMessage;
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.polygonOffset			(0, -2);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disable					(GL_POLYGON_OFFSET_FILL);
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawArrays				(GL_TRIANGLES, 0, 3);
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//draw front
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Draw bottom-right. Color = Red.\tState: PolygonOffset(0, -1), POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.polygonOffset			(0, -1);
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_POLYGON_OFFSET_FILL);
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttrib4f			(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawArrays				(GL_TRIANGLES, 0, 3);
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray	(positionLoc);
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(0);
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish					();
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render reference image
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::Renderer		referenceRenderer;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::VertexAttrib	attribs[2];
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::RenderState		state((rr::ViewportState)(rr::WindowRectangle(0, 0, m_targetSize, m_targetSize)));
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PositionColorShader program;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].type				= rr::VERTEXATTRIBTYPE_FLOAT;
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].size				= 4;
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].stride			= 0;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].instanceDivisor	= 0;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].pointer			= triangle;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[1].type				= rr::VERTEXATTRIBTYPE_DONT_CARE;
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[1].generic			= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Expecting: Bottom-right = Red." << TestLog::EndMessage;
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		referenceRenderer.draw(
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::DrawCommand(
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state,
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())),
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::Program(program.getVertexShader(), program.getFragmentShader()),
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				2,
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				attribs,
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0)));
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compare
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// UsageDisplacementTestCase
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UsageDisplacementTestCase : public PolygonOffsetTestCase
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				UsageDisplacementTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4	genRandomVec4				(de::Random& rnd) const;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void		testPolygonOffset			(void);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUsageDisplacementTestCase::UsageDisplacementTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 UsageDisplacementTestCase::genRandomVec4 (de::Random& rnd) const
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// generater triangle endpoint with following properties
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//	1) it will not be clipped
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//	2) it is not near either far or near plane to prevent possible problems related to depth clamping
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// => w >= 1.0 and z in (-0.9, 0.9) range
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4 retVal;
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal.x() = rnd.getFloat(-1, 1);
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal.y() = rnd.getFloat(-1, 1);
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal.z() = rnd.getFloat(-0.9f, 0.9f);
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal.w() = 1.0f + rnd.getFloat();
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UsageDisplacementTestCase::testPolygonOffset (void)
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random			rnd				(0xdec0de);
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&		log				= m_testCtx.getLog();
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		testImage		(m_targetSize, m_targetSize);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render test image
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					positionLoc		= gl.getAttribLocation(program.getProgram(), "a_position");
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					colorLoc		= gl.getAttribLocation(program.getProgram(), "a_color");
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					numIterations	= 40;
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << program;
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Shader compile failed.");
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor				(0, 0, 0, 1);
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearDepthf				(1.0f);
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport					(0, 0, m_targetSize, m_targetSize);
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(program.getProgram());
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_DEPTH_TEST);
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_POLYGON_OFFSET_FILL);
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray	(positionLoc);
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttrib4f			(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Framebuffer cleared, clear color = Black." << TestLog::EndMessage;
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// draw colorless (mask = 0,0,0) triangle at random* location, set offset and render green triangle with depthfunc = equal
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// *) w >= 1.0 and z in (-1, 1) range
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int iterationNdx = 0; iterationNdx < numIterations; ++iterationNdx)
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		offsetDirection = rnd.getBool();
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		offset = offsetDirection ? -1.0f : 1.0f;
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4		triangle[3];
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int vertexNdx = 0; vertexNdx < DE_LENGTH_OF_ARRAY(triangle); ++vertexNdx)
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				triangle[vertexNdx] = genRandomVec4(rnd);
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle);
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Setup triangle with random coordinates:" << TestLog::EndMessage;
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangle); ++ndx)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "\tx=" << triangle[ndx].x()
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "\ty=" << triangle[ndx].y()
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "\tz=" << triangle[ndx].z()
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "\tw=" << triangle[ndx].w()
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndMessage;
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw colorless triangle.\tState: DepthFunc = GL_ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage;
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_ALWAYS);
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 0);
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.colorMask				(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// all fragments should have different Z => DepthFunc == GL_EQUAL fails with every fragment
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw green triangle.\tState: DepthFunc = GL_EQUAL, PolygonOffset(0, " << offset << ")." << TestLog::EndMessage;
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_EQUAL);
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, offset);
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.colorMask				(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << TestLog::EndMessage; // empty line for clarity
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray	(positionLoc);
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(0);
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish					();
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render reference image
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Expecting black framebuffer." << TestLog::EndMessage;
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compare
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// UsagePositiveNegativeTestCase
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UsagePositiveNegativeTestCase : public PolygonOffsetTestCase
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UsagePositiveNegativeTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	testPolygonOffset				(void);
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUsagePositiveNegativeTestCase::UsagePositiveNegativeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UsagePositiveNegativeTestCase::testPolygonOffset (void)
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangleBottomRight[] =
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1,  1,  0,  1),
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1,  1,  0,  1),
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1, -1,  0,  1),
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangleTopLeft[] =
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1, -1,  0,  1),
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1,  1,  0,  1),
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1, -1,  0,  1),
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&		log				= m_testCtx.getLog();
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		testImage		(m_targetSize, m_targetSize);
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render test image
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					positionLoc		= gl.getAttribLocation(program.getProgram(), "a_position");
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					colorLoc		= gl.getAttribLocation(program.getProgram(), "a_color");
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << program;
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Shader compile failed.");
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor				(0, 0, 0, 1);
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearDepthf				(1.0f);
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport					(0, 0, m_targetSize, m_targetSize);
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.depthFunc				(GL_LESS);
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(program.getProgram());
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_DEPTH_TEST);
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_POLYGON_OFFSET_FILL);
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray	(positionLoc);
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "DepthFunc = GL_LESS." << TestLog::EndMessage;
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//draw top left (negative offset test)
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw top-left. Color = White.\tState: PolygonOffset(0, 0)." << TestLog::EndMessage;
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 0);
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw top-left. Color = Green.\tState: PolygonOffset(0, -1)." << TestLog::EndMessage;
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, -1);
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//draw bottom right (positive offset test)
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight);
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw bottom-right. Color = White.\tState: PolygonOffset(0, 1)." << TestLog::EndMessage;
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 1);
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw bottom-right. Color = Yellow.\tState: PolygonOffset(0, 0)." << TestLog::EndMessage;
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 0);
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 0.0f, 1.0f);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray	(positionLoc);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(0);
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish					();
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render reference image
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::Renderer		referenceRenderer;
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::VertexAttrib	attribs[2];
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::RenderState		state((rr::ViewportState)(rr::WindowRectangle(0, 0, m_targetSize, m_targetSize)));
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PositionColorShader program;
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].type				= rr::VERTEXATTRIBTYPE_FLOAT;
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].size				= 4;
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].stride			= 0;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].instanceDivisor	= 0;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].pointer			= triangleTopLeft;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[1].type				= rr::VERTEXATTRIBTYPE_DONT_CARE;
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[1].generic			= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Expecting: Top-left = Green, Bottom-right = Yellow." << TestLog::EndMessage;
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		referenceRenderer.draw(
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::DrawCommand(
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state,
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())),
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::Program(program.getVertexShader(), program.getFragmentShader()),
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				2,
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				attribs,
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0)));
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[0].pointer = triangleBottomRight;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[1].generic = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		referenceRenderer.draw(
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::DrawCommand(
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state,
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())),
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::Program(program.getVertexShader(), program.getFragmentShader()),
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				2,
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				attribs,
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0)));
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compare
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ResultClampingTestCase
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ResultClampingTestCase : public PolygonOffsetTestCase
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ResultClampingTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	testPolygonOffset		(void);
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryResultClampingTestCase::ResultClampingTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ResultClampingTestCase::testPolygonOffset (void)
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangleBottomRight[] =
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1,  1,  1,  1),
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1,  1,  1,  1),
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1, -1,  1,  1),
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangleTopLeft[] =
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1, -1, -1,  1),
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1,  1, -1,  1),
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1, -1, -1,  1),
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&		log				= m_testCtx.getLog();
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		testImage		(m_targetSize, m_targetSize);
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render test image
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << program;
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Shader compile failed.");
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor				(0, 0, 0, 1);
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearDepthf				(1.0f);
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport					(0, 0, m_targetSize, m_targetSize);
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(program.getProgram());
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_DEPTH_TEST);
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_POLYGON_OFFSET_FILL);
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray	(positionLoc);
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//draw bottom right (far)
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight);
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw bottom-right. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 8), Polygon Z = 1.0. (Result depth should clamp to 1.0)." << TestLog::EndMessage;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_ALWAYS);
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 8);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw bottom-right. Color = Red.\tState: DepthFunc = GREATER, PolygonOffset(0, 9), Polygon Z = 1.0. (Result depth should clamp to 1.0 too)" << TestLog::EndMessage;
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_GREATER);
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 9);
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//draw top left (near)
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft);
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw top-left. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, -8), Polygon Z = -1.0. (Result depth should clamp to -1.0)" << TestLog::EndMessage;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_ALWAYS);
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, -8);
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw top-left. Color = Yellow.\tState: DepthFunc = LESS, PolygonOffset(0, -9), Polygon Z = -1.0. (Result depth should clamp to -1.0 too)." << TestLog::EndMessage;
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_LESS);
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, -9);
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 0.0f, 1.0f);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray	(positionLoc);
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(0);
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish					();
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render reference image
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Expecting: Top-left = White, Bottom-right = White." << TestLog::EndMessage;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(referenceImage.getAccess(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compare
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// UsageSlopeTestCase
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UsageSlopeTestCase  : public PolygonOffsetTestCase
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UsageSlopeTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	testPolygonOffset	(void);
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUsageSlopeTestCase::UsageSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UsageSlopeTestCase::testPolygonOffset (void)
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangleBottomRight[] =
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1,  1,  0.0f,  1),
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1,  1,  0.9f,  1),
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1, -1,  0.9f,  1),
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangleTopLeft[] =
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1, -1,  -0.9f,  1),
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1,  1,   0.9f,  1),
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1, -1,   0.0f,  1),
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&		log				= m_testCtx.getLog();
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		testImage		(m_targetSize, m_targetSize);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render test image
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << program;
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Shader compile failed.");
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor				(0, 0, 0, 1);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearDepthf				(1.0f);
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport					(0, 0, m_targetSize, m_targetSize);
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(program.getProgram());
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_DEPTH_TEST);
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_POLYGON_OFFSET_FILL);
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray	(positionLoc);
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//draw top left (negative offset test)
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft);
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw top-left. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage;
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_ALWAYS);
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 0);
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw top-left. Color = Green.\tState: DepthFunc = LESS, PolygonOffset(-1, 0)." << TestLog::EndMessage;
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_LESS);
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(-1, 0);
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//draw bottom right (positive offset test)
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight);
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw bottom-right. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage;
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_ALWAYS);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 0);
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw bottom-right. Color = Green.\tState: DepthFunc = GREATER, PolygonOffset(1, 0)." << TestLog::EndMessage;
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_GREATER);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(1, 0);
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray	(positionLoc);
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(0);
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish					();
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render reference image
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Expecting: Top-left = Green, Bottom-right = Green." << TestLog::EndMessage;
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compare
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ZeroSlopeTestCase
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ZeroSlopeTestCase : public PolygonOffsetTestCase
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ZeroSlopeTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	testPolygonOffset	(void);
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryZeroSlopeTestCase::ZeroSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ZeroSlopeTestCase::testPolygonOffset (void)
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangle[] =
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-0.4f,  0.4f, 0.0f, 1.0f),
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-0.8f, -0.5f, 0.0f, 1.0f),
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 0.7f,  0.2f, 0.0f, 1.0f),
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&		log				= m_testCtx.getLog();
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		testImage		(m_targetSize, m_targetSize);
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// log the triangle
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Setup triangle with coordinates:" << TestLog::EndMessage;
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangle); ++ndx)
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tx=" << triangle[ndx].x()
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\ty=" << triangle[ndx].y()
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tz=" << triangle[ndx].z()
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tw=" << triangle[ndx].w()
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::EndMessage;
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render test image
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << program;
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Shader compile failed.");
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor				(0, 0, 0, 1);
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearDepthf				(1.0f);
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport					(0, 0, m_targetSize, m_targetSize);
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(program.getProgram());
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_DEPTH_TEST);
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_POLYGON_OFFSET_FILL);
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray	(positionLoc);
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle);
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw triangle. Color = Red.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage;
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_ALWAYS);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(0, 0);
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw triangle. Color = Black.\tState: DepthFunc = EQUAL, PolygonOffset(4, 0)." << TestLog::EndMessage;
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc				(GL_EQUAL);
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset			(4, 0);	// triangle slope == 0
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f			(colorLoc, 0.0f, 0.0f, 0.0f, 1.0f);
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays				(GL_TRIANGLES, 0, 3);
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray	(positionLoc);
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(0);
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish					();
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render reference image
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Expecting black triangle." << TestLog::EndMessage;
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compare
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// OneSlopeTestCase
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass OneSlopeTestCase : public PolygonOffsetTestCase
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			OneSlopeTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	testPolygonOffset	(void);
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryOneSlopeTestCase::OneSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid OneSlopeTestCase::testPolygonOffset (void)
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/*
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		* setup vertices subject to following properties
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*   dz_w / dx_w == 1
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*   dz_w / dy_w == 0
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		* or
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*   dz_w / dx_w == 0
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*   dz_w / dy_w == 1
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		* ==> m == 1
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*/
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float cornerDepth = float(m_targetSize);
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 triangles[2][3] =
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4(-1, -1, -cornerDepth, 1),
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4(-1,  1, -cornerDepth, 1),
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4( 1, -1,  cornerDepth, 1),
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4(-1,  1,  cornerDepth, 1),
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4( 1,  1,  cornerDepth, 1),
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4( 1, -1, -cornerDepth, 1),
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&		log				= m_testCtx.getLog();
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		testImage		(m_targetSize, m_targetSize);
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// log triangle info
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Setup triangle0 coordinates: (slope in window coordinates = 1.0)" << TestLog::EndMessage;
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangles[0]); ++ndx)
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tx=" << triangles[0][ndx].x()
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\ty=" << triangles[0][ndx].y()
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tz=" << triangles[0][ndx].z()
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tw=" << triangles[0][ndx].w()
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::EndMessage;
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Setup triangle1 coordinates: (slope in window coordinates = 1.0)" << TestLog::EndMessage;
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangles[1]); ++ndx)
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tx=" << triangles[1][ndx].x()
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\ty=" << triangles[1][ndx].y()
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tz=" << triangles[1][ndx].z()
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tw=" << triangles[1][ndx].w()
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::EndMessage;
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render test image
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << program;
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Shader compile failed.");
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor				(0, 0, 0, 1);
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear					(GL_COLOR_BUFFER_BIT);
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport					(0, 0, m_targetSize, m_targetSize);
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(program.getProgram());
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_DEPTH_TEST);
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable					(GL_POLYGON_OFFSET_FILL);
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray	(positionLoc);
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Framebuffer cleared, clear color = Black." << TestLog::EndMessage;
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// top left (positive offset)
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Clear depth to 1.0." << TestLog::EndMessage;
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clearDepthf			(1.0f); // far
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clear				(GL_DEPTH_BUFFER_BIT);
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer	(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangles[0]);
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw triangle0. Color = Red.\tState: DepthFunc = NOTEQUAL, PolygonOffset(10, 0). (Result depth should clamp to 1.0)." << TestLog::EndMessage;
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset		(10, 0);		// clamps any depth on the triangle to 1
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc			(GL_NOTEQUAL);
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f		(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays			(GL_TRIANGLES, 0, 3);
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// bottom right (negative offset)
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Clear depth to 0.0." << TestLog::EndMessage;
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clearDepthf			(0.0f); // far
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clear				(GL_DEPTH_BUFFER_BIT);
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer	(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangles[1]);
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Draw triangle1. Color = Green.\tState: DepthFunc = NOTEQUAL, PolygonOffset(-10, 0). (Result depth should clamp to 0.0)." << TestLog::EndMessage;
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.polygonOffset		(-10, 0); // clamps depth to 0
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.depthFunc			(GL_NOTEQUAL);
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttrib4f		(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays			(GL_TRIANGLES, 0, 3);
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray	(positionLoc);
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram				(0);
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish					();
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render reference image
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Expecting black framebuffer." << TestLog::EndMessage;
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compare
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPolygonOffsetTests::PolygonOffsetTests (Context& context)
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "polygon_offset", "Polygon offset tests")
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPolygonOffsetTests::~PolygonOffsetTests (void)
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PolygonOffsetTests::init (void)
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const struct DepthBufferFormat
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		enum BufferType
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FIXED_POINT,
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOATING_POINT,
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_UNKNOWN
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum		internalFormat;
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			bits;
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BufferType	floatingPoint;
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* name;
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} depthFormats[]=
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 0,						0,		DepthBufferFormat::TYPE_UNKNOWN,		"default" },
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_DEPTH_COMPONENT16,		16,		DepthBufferFormat::TYPE_FIXED_POINT,	"fixed16" },
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthFormats); ++ndx)
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const DepthBufferFormat& format = depthFormats[ndx];
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// enable works?
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new UsageTestCase(m_context, (std::string(format.name) + "_enable").c_str(), "test enable GL_POLYGON_OFFSET_FILL", format.internalFormat, format.name));
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Really moves the polygons ?
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new UsageDisplacementTestCase(m_context, (std::string(format.name) + "_displacement_with_units").c_str(), "test polygon offset", format.internalFormat, format.name));
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Really moves the polygons to right direction ?
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new UsagePositiveNegativeTestCase(m_context, (std::string(format.name) + "_render_with_units").c_str(), "test polygon offset", format.internalFormat, format.name));
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Is total result clamped to [0,1] like promised?
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new ResultClampingTestCase(m_context, (std::string(format.name) + "_result_depth_clamp").c_str(), "test polygon offset clamping", format.internalFormat, format.name));
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Slope really moves the polygon?
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new UsageSlopeTestCase(m_context, (std::string(format.name) + "_render_with_factor").c_str(), "test polygon offset factor", format.internalFormat, format.name));
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Factor with zero slope
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new ZeroSlopeTestCase(m_context, (std::string(format.name) + "_factor_0_slope").c_str(), "test polygon offset factor", format.internalFormat, format.name));
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Factor with 1.0 slope
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new OneSlopeTestCase(m_context, (std::string(format.name) + "_factor_1_slope").c_str(), "test polygon offset factor", format.internalFormat, format.name));
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1248