13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.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 Special float stress tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3sSpecialFloatTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Stress
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int		TEST_CANVAS_SIZE		= 256;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int		TEST_TEXTURE_SIZE		= 128;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int		TEST_TEXTURE_CUBE_SIZE	= 32;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const deUint32	s_specialFloats[]		=
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x00000000,	//          zero
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x80000000,	// negative zero
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x3F800000,	//          one
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0xBF800000,	// negative one
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x00800000,	// minimum positive normalized value
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x80800000,	// maximum negative normalized value
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x00000001,	// minimum positive denorm value
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x80000001,	// maximum negative denorm value
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x7F7FFFFF,	// maximum finite value.
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0xFF7FFFFF,	// minimum finite value.
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x7F800000,	//  inf
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0xFF800000,	// -inf
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x34000000,	//          epsilon
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0xB4000000,	// negative epsilon
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x7FC00000,	//          quiet_NaN
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0xFFC00000,	// negative quiet_NaN
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x7FC00001,	//          signaling_NaN
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0xFFC00001,	// negative signaling_NaN
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x7FEAAAAA,	//          quiet payloaded NaN		(payload of repeated pattern of 101010...)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0xFFEAAAAA,	// negative quiet payloaded NaN		( .. )
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0x7FAAAAAA,	//          signaling payloaded NaN	( .. )
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0xFFAAAAAA,	// negative signaling payloaded NaN	( .. )
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_colorPassthroughFragmentShaderSource	=	"#version 300 es\n"
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"layout(location = 0) out mediump vec4 fragColor;\n"
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"in mediump vec4 v_out;\n"
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"void main ()\n"
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"{\n"
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"	fragColor = v_out;\n"
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"}\n";
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_attrPassthroughVertexShaderSource	=	"#version 300 es\n"
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"in highp vec4 a_pos;\n"
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"in highp vec4 a_attr;\n"
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"out highp vec4 v_attr;\n"
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"void main ()\n"
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"{\n"
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"	v_attr = a_attr;\n"
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"	gl_Position = a_pos;\n"
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	"}\n";
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RenderCase : public TestCase
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum RenderTargetType
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RENDERTARGETTYPE_SCREEN,
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RENDERTARGETTYPE_FBO
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								RenderCase			(Context& context, const char* name, const char* desc, RenderTargetType renderTargetType = RENDERTARGETTYPE_SCREEN);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~RenderCase			(void);
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				init				(void);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				deinit				(void);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						checkResultImage	(const tcu::Surface& result);
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						drawTestPattern		(bool useTexture);
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual std::string			genVertexSource		(void) const = 0;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual std::string			genFragmentSource	(void) const = 0;
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram*	m_program;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RenderTargetType		m_renderTargetType;
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderCase::RenderCase (Context& context, const char* name, const char* desc, RenderTargetType renderTargetType)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, desc)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program				(DE_NULL)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderTargetType	(renderTargetType)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderCase::~RenderCase (void)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RenderCase::init (void)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width	 = m_context.getRenderTarget().getWidth();
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int height = m_context.getRenderTarget().getHeight();
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// check target size
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_renderTargetType == RENDERTARGETTYPE_SCREEN)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (width < TEST_CANVAS_SIZE || height < TEST_CANVAS_SIZE)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(std::string("Render target size must be at least ") + de::toString(TEST_CANVAS_SIZE) + "x" + de::toString(TEST_CANVAS_SIZE));
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_renderTargetType == RENDERTARGETTYPE_FBO)
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint maxTexSize = 0;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (maxTexSize < TEST_CANVAS_SIZE)
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") + de::toString(TEST_CANVAS_SIZE));
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// gen shader
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shader." << tcu::TestLog::EndMessage;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource()) << glu::FragmentSource(genFragmentSource()));
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << *m_program;
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_program->isOk())
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("shader compile failed");
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RenderCase::deinit (void)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_program)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_program;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = DE_NULL;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool RenderCase::checkResultImage (const tcu::Surface& result)
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	errorMask	(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			error		= false;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image." << tcu::TestLog::EndMessage;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < TEST_CANVAS_SIZE; ++y)
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < TEST_CANVAS_SIZE; ++x)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA col = result.getPixel(x, y);
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (col.getGreen() == 255)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			errorMask.setPixel(x, y, tcu::RGBA::green);
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			errorMask.setPixel(x, y, tcu::RGBA::red);
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			error = true;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (error)
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Result image has missing or invalid pixels" << tcu::TestLog::EndMessage;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog()
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::ImageSet("Results", "Result verification")
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Image("Result",		"Result",		result)
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Image("Error mask",	"Error mask",	errorMask)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::EndImageSet;
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog()
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::ImageSet("Results", "Result verification")
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Image("Result", "Result", result)
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::EndImageSet;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return !error;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool RenderCase::drawTestPattern (bool useTexture)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const tcu::Vec4 fullscreenQuad[4] =
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const	vertexSource		=	"#version 300 es\n"
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"in highp vec4 a_pos;\n"
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"out mediump vec4 v_position;\n"
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"void main ()\n"
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"{\n"
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"	v_position = a_pos;\n"
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"	gl_Position = a_pos;\n"
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"}\n";
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const	fragmentSourceNoTex	=	"#version 300 es\n"
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"layout(location = 0) out mediump vec4 fragColor;\n"
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"in mediump vec4 v_position;\n"
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"void main ()\n"
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"{\n"
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"	fragColor = vec4((v_position.x + 1.0) * 0.5, 1.0, 1.0, 1.0);\n"
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"}\n";
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const	fragmentSourceTex	=	"#version 300 es\n"
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"layout(location = 0) out mediump vec4 fragColor;\n"
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"uniform mediump sampler2D u_sampler;\n"
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"in mediump vec4 v_position;\n"
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"void main ()\n"
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"{\n"
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"	fragColor = texture(u_sampler, v_position.xy);\n"
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												"}\n";
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const	fragmentSource		=	(useTexture) ? (fragmentSourceTex) : (fragmentSourceNoTex);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		formatThreshold		= m_context.getRenderTarget().getPixelFormat().getColorThreshold();
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		resultImage			(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		errorMask			(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				error				=	false;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a test pattern to detect " << ((useTexture) ? ("texture sampling") : ("")) << " side-effects." << tcu::TestLog::EndMessage;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// draw pattern
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram	patternProgram	(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vertexSource) << glu::FragmentSource(fragmentSource));
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint					positionLoc		= gl.getAttribLocation(patternProgram.getProgram(), "a_pos");
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLuint						textureID		= 0;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (useTexture)
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int textureSize = 32;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<tcu::Vector<deUint8, 4> > buffer(textureSize*textureSize);
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < textureSize; ++x)
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < textureSize; ++y)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// sum of two axis aligned gradients. Each gradient is 127 at the edges and 0 at the center.
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// pattern is symmetric (x and y) => no discontinuity near boundary => no need to worry of results with LINEAR filtering near boundaries
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint8 redComponent = (deUint8)de::clamp(de::abs((float)x / (float)textureSize - 0.5f) * 255.0f + de::abs((float)y / (float)textureSize - 0.5f) * 255.0f, 0.0f, 255.0f);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				buffer[x * textureSize + y] = tcu::Vector<deUint8, 4>(redComponent, 255, 255, 255);
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genTextures(1, &textureID);
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(GL_TEXTURE_2D, textureID);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureSize, textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer[0].getPtr());
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(patternProgram.getProgram());
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (useTexture)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1i(gl.getUniformLocation(patternProgram.getProgram(), "u_sampler"), 0);
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &fullscreenQuad[0]);
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(positionLoc);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(positionLoc);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(0);
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish();
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "RenderCase::drawTestPattern");
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (textureID)
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.deleteTextures(1, &textureID);
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify pattern
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < TEST_CANVAS_SIZE; ++y)
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < TEST_CANVAS_SIZE; ++x)
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			texGradientPosX = deFloatFrac((float)x * 2.0f / (float)TEST_CANVAS_SIZE);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			texGradientPosY = deFloatFrac((float)y * 2.0f / (float)TEST_CANVAS_SIZE);
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint8		texRedComponent = (deUint8)de::clamp(de::abs(texGradientPosX - 0.5f) * 255.0f + de::abs(texGradientPosY - 0.5f) * 255.0f, 0.0f, 255.0f);
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA		refColTexture	= tcu::RGBA(texRedComponent, 255, 255, 255);
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA		refColGradient	= tcu::RGBA((int)((float)x / (float)TEST_CANVAS_SIZE * 255.0f), 255, 255, 255);
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA&	refCol			= (useTexture) ? (refColTexture) : (refColGradient);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			colorThreshold	= 10;
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA		col				= resultImage.getPixel(x, y);
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec4	colorDiff		= tcu::abs(col.toIVec() - refCol.toIVec());
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (colorDiff.x() > formatThreshold.getRed()   + colorThreshold ||
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			colorDiff.y() > formatThreshold.getGreen() + colorThreshold ||
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			colorDiff.z() > formatThreshold.getBlue()  + colorThreshold)
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			errorMask.setPixel(x, y, tcu::RGBA::red);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			error = true;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			errorMask.setPixel(x, y, tcu::RGBA::green);
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// report error
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (error)
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Test pattern has missing/invalid pixels" << tcu::TestLog::EndMessage;
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog()
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::ImageSet("Results", "Result verification")
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Image("Result",		"Result",		resultImage)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Image("Error mask",	"Error mask",	errorMask)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::EndImageSet;
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "No side-effects found." << tcu::TestLog::EndMessage;
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return !error;
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FramebufferRenderCase : public RenderCase
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum FrameBufferType
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_DEFAULT = 0,
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_RGBA4,
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_RGB5_A1,
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_RGB565,
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_RGBA8,
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_RGB10_A2,
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_RGBA_FLOAT16,
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_RGBA_FLOAT32,
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FBO_LAST
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							FramebufferRenderCase	(Context& context, const char* name, const char* desc, FrameBufferType fboType);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual					~FramebufferRenderCase	(void);
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			init					(void);
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			deinit					(void);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate					(void);
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			testFBO					(void) = DE_NULL;
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FrameBufferType	m_fboType;
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint					m_texID;
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint					m_fboID;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFramebufferRenderCase::FramebufferRenderCase (Context& context, const char* name, const char* desc, FrameBufferType fboType)
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: RenderCase	(context, name, desc, (fboType == FBO_DEFAULT) ? (RENDERTARGETTYPE_SCREEN) : (RENDERTARGETTYPE_FBO))
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fboType		(fboType)
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texID		(0)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fboID		(0)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_fboType < FBO_LAST);
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFramebufferRenderCase::~FramebufferRenderCase (void)
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FramebufferRenderCase::init (void)
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// check requirements
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fboType == FBO_RGBA_FLOAT16)
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_half_float") &&
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			!m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_float"))
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Color renderable half float texture required.");
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_fboType == FBO_RGBA_FLOAT32)
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_float"))
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Color renderable float texture required.");
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// gen shader
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::init();
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// create render target
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fboType == FBO_DEFAULT)
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Using default framebuffer." << tcu::TestLog::EndMessage;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLuint internalFormat	= 0;
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLuint format			= 0;
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLuint type				= 0;
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_fboType)
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case FBO_RGBA4:			internalFormat = GL_RGBA4;		format = GL_RGBA;	type = GL_UNSIGNED_SHORT_4_4_4_4;		break;
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case FBO_RGB5_A1:		internalFormat = GL_RGB5_A1;	format = GL_RGBA;	type = GL_UNSIGNED_SHORT_5_5_5_1;		break;
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case FBO_RGB565:		internalFormat = GL_RGB565;		format = GL_RGB;	type = GL_UNSIGNED_SHORT_5_6_5;			break;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case FBO_RGBA8:			internalFormat = GL_RGBA8;		format = GL_RGBA;	type = GL_UNSIGNED_BYTE;				break;
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case FBO_RGB10_A2:		internalFormat = GL_RGB10_A2;	format = GL_RGBA;	type = GL_UNSIGNED_INT_2_10_10_10_REV;	break;
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case FBO_RGBA_FLOAT16:	internalFormat = GL_RGBA16F;	format = GL_RGBA;	type = GL_HALF_FLOAT;					break;
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case FBO_RGBA_FLOAT32:	internalFormat = GL_RGBA32F;	format = GL_RGBA;	type = GL_FLOAT;						break;
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "Creating fbo. Texture internalFormat = " << glu::getPixelFormatStr(internalFormat)
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< ", format = " << glu::getPixelFormatStr(format)
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< ", type = " << glu::getTypeStr(type)
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::EndMessage;
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// gen texture
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genTextures(1, &m_texID);
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(GL_TEXTURE_2D, m_texID);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE, 0, format, type, DE_NULL);
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "texture init");
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// gen fbo
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genFramebuffers(1, &m_fboID);
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texID, 0);
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "fbo init");
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("could not create fbo for testing.");
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FramebufferRenderCase::deinit (void)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_texID)
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteTextures(1, &m_texID);
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texID = 0;
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fboID)
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteFramebuffers(1, &m_fboID);
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fboID = 0;
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFramebufferRenderCase::IterateResult FramebufferRenderCase::iterate (void)
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// bind fbo (or don't if we are using default)
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fboID)
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// do something with special floats
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	testFBO();
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests special floats as vertex attributes
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that special floats transferred to the shader using vertex
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * attributes do not change the results of normal floating point
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * calculations. Special floats are put to 4-vector's x and y components and
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * value 1.0 is put to z and w. The resulting fragment's green channel
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * should be 1.0 everywhere.
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * After the calculation test a test pattern is drawn to detect possible
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * floating point operation anomalies.
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VertexAttributeCase : public RenderCase
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Storage
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STORAGE_BUFFER = 0,
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STORAGE_CLIENT,
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STORAGE_LAST
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ShaderType
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_VERTEX = 0,
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FRAGMENT,
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_LAST
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						VertexAttributeCase			(Context& context, const char* name, const char* desc, Storage storage, ShaderType type);
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~VertexAttributeCase		(void);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init						(void);
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit						(void);
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate						(void);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genVertexSource				(void) const;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genFragmentSource			(void) const;
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Storage		m_storage;
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderType	m_type;
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint				m_positionVboID;
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint				m_attribVboID;
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint				m_elementVboID;
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexAttributeCase::VertexAttributeCase (Context& context, const char* name, const char* desc, Storage storage, ShaderType type)
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: RenderCase			(context, name, desc)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_storage				(storage)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type				(type)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_positionVboID		(0)
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_attribVboID			(0)
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_elementVboID		(0)
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(storage < STORAGE_LAST);
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(type < TYPE_LAST);
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexAttributeCase::~VertexAttributeCase (void)
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexAttributeCase::init (void)
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::init();
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// init gl resources
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_storage == STORAGE_BUFFER)
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &m_positionVboID);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &m_attribVboID);
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &m_elementVboID);
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexAttributeCase::deinit (void)
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::deinit();
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_attribVboID)
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteBuffers(1, &m_attribVboID);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_attribVboID = 0;
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_positionVboID)
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteBuffers(1, &m_positionVboID);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_positionVboID = 0;
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_elementVboID)
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteBuffers(1, &m_elementVboID);
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_elementVboID = 0;
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexAttributeCase::IterateResult VertexAttributeCase::iterate (void)
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create a [s_specialFloats] X [s_specialFloats] grid of vertices with each vertex having 2 [s_specialFloats] values
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// and calculate some basic operations with the floating point values. If all goes well, nothing special should happen
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec4>	gridVertices	(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::UVec4>	gridAttributes	(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint16>	indices			((DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * 6);
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			resultImage		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertices
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	one		= 0x3F800000;
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		posX	= (float)x / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f; // map from [0, len(s_specialFloats) - 1] to [-1, 1]
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		posY	= (float)y / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f;
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridVertices[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y]	= tcu::Vec4(posX, posY, 0.0f, 1.0f);
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridAttributes[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y]	= tcu::UVec4(s_specialFloats[x], s_specialFloats[y], one, one);
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// tiles
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++x)
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++y)
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) + y) * 6;
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 0] = (x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0);
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 1] = (x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 2] = (x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0);
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 3] = (x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0);
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 4] = (x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1);
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 5] = (x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1);
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a grid with the shader. Setting a_attr for each vertex to (special, special, 1, 1)." << tcu::TestLog::EndMessage;
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw grid
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				attribLoc	= gl.getAttribLocation(m_program->getProgram(), "a_attr");
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_storage == STORAGE_BUFFER)
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, m_positionVboID);
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(gridVertices.size() * sizeof(tcu::Vec4)), &gridVertices[0], GL_STATIC_DRAW);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, m_attribVboID);
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(gridAttributes.size() * sizeof(tcu::UVec4)), &gridAttributes[0], GL_STATIC_DRAW);
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementVboID);
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indices.size() * sizeof(deUint16)), &indices[0], GL_STATIC_DRAW);
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_program->getProgram());
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_storage == STORAGE_BUFFER)
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, m_positionVboID);
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, m_attribVboID);
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.enableVertexAttribArray(positionLoc);
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.enableVertexAttribArray(attribLoc);
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, DE_NULL);
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.disableVertexAttribArray(positionLoc);
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.disableVertexAttribArray(attribLoc);
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_storage == STORAGE_CLIENT)
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridAttributes[0]);
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.enableVertexAttribArray(positionLoc);
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.enableVertexAttribArray(attribLoc);
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]);
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.disableVertexAttribArray(positionLoc);
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.disableVertexAttribArray(attribLoc);
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(0);
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish();
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify everywhere was drawn (all pixels have Green = 255)
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!checkResultImage(resultImage))
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// test drawing still works
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!drawTestPattern(false))
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// all ok
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string VertexAttributeCase::genVertexSource (void) const
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TYPE_VERTEX)
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_pos;\n"
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_attr;\n"
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"out mediump vec4 v_out;\n"
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a1 = a_attr.xz + a_attr.yw; // add\n"
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a2 = a_attr.xz - a_attr.yw; // sub\n"
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a3 = a_attr.xz * a_attr.yw; // mul\n"
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a4 = a_attr.xz / a_attr.yw; // div\n"
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a5 = a_attr.xz + a_attr.yw * a_attr.xz; // fma\n"
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n"
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	v_out = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n"
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_pos;\n"
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_attrPassthroughVertexShaderSource;
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string VertexAttributeCase::genFragmentSource (void) const
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TYPE_VERTEX)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_colorPassthroughFragmentShaderSource;
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 fragColor;\n"
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 v_attr;\n"
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a1 = v_attr.xz + v_attr.yw; // add\n"
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a2 = v_attr.xz - v_attr.yw; // sub\n"
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a3 = v_attr.xz * v_attr.yw; // mul\n"
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a4 = v_attr.xz / v_attr.yw; // div\n"
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a5 = v_attr.xz + v_attr.yw * v_attr.xz; // fma\n"
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a6 = dFdx(v_attr.xz);\n"
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y + a6.y) - 6.0);\n"
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	fragColor = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x+a6.x, 1.0);\n"
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests special floats as uniforms
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that special floats transferred to the shader as uniforms do
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * not change the results of normal floating point calculations. Special
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * floats are put to 4-vector's x and y components and value 1.0 is put to
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * z and w. The resulting fragment's green channel should be 1.0
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * everywhere.
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * After the calculation test a test pattern is drawn to detect possible
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * floating point operation anomalies.
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformCase : public RenderCase
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ShaderType
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_VERTEX = 0,
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FRAGMENT,
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						UniformCase					(Context& context, const char* name, const char* desc, ShaderType type);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~UniformCase				(void);
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init						(void);
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit						(void);
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate						(void);
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genVertexSource				(void) const;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genFragmentSource			(void) const;
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderType	m_type;
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* name, const char* desc, ShaderType type)
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: RenderCase	(context, name, desc)
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type		(type)
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::~UniformCase (void)
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::init (void)
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::init();
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::deinit (void)
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::deinit();
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::IterateResult UniformCase::iterate (void)
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create a [s_specialFloats] X [s_specialFloats] grid of tile with each tile having 2 [s_specialFloats] values
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// and calculate some basic operations with the floating point values. If all goes well, nothing special should happen
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec4>	gridVertices	((DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1));
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint16>	indices			(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			resultImage		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertices
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++x)
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++y)
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		posX	= (float)x / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f; // map from [0, len(s_specialFloats) ] to [-1, 1]
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		posY	= (float)y / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f;
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridVertices[x * (DE_LENGTH_OF_ARRAY(s_specialFloats)+1) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// tiles
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats)) + y) * 6;
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 0] = (x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0);
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 1] = (x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1);
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 2] = (x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0);
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 3] = (x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 4] = (x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1);
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 5] = (x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1);
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a grid with the shader. Setting u_special for vertex each tile to (special, special, 1, 1)." << tcu::TestLog::EndMessage;
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw grid
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				specialLoc	= gl.getUniformLocation(m_program->getProgram(), "u_special");
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_program->getProgram());
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(positionLoc);
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32		one				= 0x3F800000;
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::UVec4	uniformValue	= tcu::UVec4(s_specialFloats[x], s_specialFloats[y], one, one);
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int			indexIndex		= (x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y) * 6;
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform4fv(specialLoc, 1, (const float*)uniformValue.getPtr());
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(positionLoc);
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(0);
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish();
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "UniformCase::iterate");
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify everywhere was drawn (all pixels have Green = 255)
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!checkResultImage(resultImage))
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// test drawing still works
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!drawTestPattern(false))
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// all ok
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string UniformCase::genVertexSource (void) const
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TYPE_VERTEX)
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_pos;\n"
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform highp vec4 u_special;\n"
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"out mediump vec4 v_out;\n"
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a1 = u_special.xz + u_special.yw; // add\n"
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a2 = u_special.xz - u_special.yw; // sub\n"
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a3 = u_special.xz * u_special.yw; // mul\n"
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a4 = u_special.xz / u_special.yw; // div\n"
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a5 = u_special.xz + u_special.yw * u_special.xz; // fma\n"
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n"
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	v_out = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n"
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_pos;\n"
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_pos;\n"
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_pos;\n"
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string UniformCase::genFragmentSource (void) const
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TYPE_VERTEX)
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_colorPassthroughFragmentShaderSource;
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 fragColor;\n"
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform highp vec4 u_special;\n"
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a1 = u_special.xz + u_special.yw; // add\n"
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a2 = u_special.xz - u_special.yw; // sub\n"
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a3 = u_special.xz * u_special.yw; // mul\n"
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a4 = u_special.xz / u_special.yw; // div\n"
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a5 = u_special.xz + u_special.yw * u_special.xz; // fma\n"
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a6 = mod(u_special.xz, u_special.yw);\n"
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp vec2 a7 = mix(u_special.xz, u_special.yw, a6);\n"
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y + a6.y + a7.y) - 7.0);\n"
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	fragColor = vec4(a1.x*a3.x, green, a5.x*a4.x + a2.x*a7.x, 1.0);\n"
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests special floats in floating point textures
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that sampling special floats from a floating point texture
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * does not affect the values of other color components of the sample. Test
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * samples a RG texture with R channel filled with special floats and G
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * channel filled with test values.
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that linear sampling using compare mode = COMPARE_REF_TO_TEXTURE
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * of a floating point depth texture containing special floating point
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * values does not produce values outside the [0, 1] range.
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * After the calculation test a test pattern is drawn to detect possible
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * texture sampling anomalies.
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCase : public RenderCase
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ShaderType
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_VERTEX = 0,
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FRAGMENT,
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_LAST
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum TextureType
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEXTURE_FLOAT = 0,
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEXTURE_DEPTH,
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEXTURE_LAST
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum UploadType
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UPLOAD_CLIENT = 0,
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UPLOAD_PBO,
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UPLOAD_LAST
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TextureCase					(Context& context, const char* name, const char* desc, ShaderType type, TextureType texType, UploadType uploadType);
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~TextureCase				(void);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init						(void);
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit						(void);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate						(void);
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genVertexSource				(void) const;
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genFragmentSource			(void) const;
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderType	m_type;
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureType	m_textureType;
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const UploadType	m_uploadType;
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint				m_textureID;
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint				m_pboID;
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCase::TextureCase (Context& context, const char* name, const char* desc, ShaderType type, TextureType texType, UploadType uploadType)
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: RenderCase	(context, name, desc)
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type		(type)
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureType	(texType)
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uploadType	(uploadType)
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureID	(0)
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pboID		(0)
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(type < TYPE_LAST);
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(texType < TEXTURE_LAST);
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(uploadType < UPLOAD_LAST);
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCase::~TextureCase (void)
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCase::init (void)
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// requirements
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint maxTextureSize = 0;
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (maxTextureSize < TEST_TEXTURE_SIZE)
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") + de::toString(TEST_TEXTURE_SIZE));
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::init();
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// gen texture
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(12345);
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genTextures(1, &m_textureID);
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(GL_TEXTURE_2D, m_textureID);
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_uploadType == UPLOAD_PBO)
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genBuffers(1, &m_pboID);
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pboID);
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureCase::init");
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_textureType == TEXTURE_FLOAT)
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<deUint32>	texData	(TEST_TEXTURE_SIZE*TEST_TEXTURE_SIZE*2);
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32*			dataPtr = (m_uploadType == UPLOAD_CLIENT) ? (&texData[0]) : (DE_NULL);
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Creating a 2D 2-component float texture. Pixel contents are of form (special, 1)." << tcu::TestLog::EndMessage;
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// set green channel to 1.0
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < TEST_TEXTURE_SIZE; ++x)
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < TEST_TEXTURE_SIZE; ++y)
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texData[(x * TEST_TEXTURE_SIZE + y) * 2 + 0] = rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texData[(x * TEST_TEXTURE_SIZE + y) * 2 + 1] = 0x3F800000;	// one
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_uploadType == UPLOAD_PBO)
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.bufferData(GL_PIXEL_UNPACK_BUFFER, (glw::GLsizeiptr)(texData.size() * sizeof(deUint32)), &texData[0], GL_STATIC_DRAW);
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RG32F, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, 0, GL_RG, GL_FLOAT, dataPtr);
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureCase::init");
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_textureType == TEXTURE_DEPTH)
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<deUint32>	texData	(TEST_TEXTURE_SIZE*TEST_TEXTURE_SIZE);
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32*			dataPtr = (m_uploadType == UPLOAD_CLIENT) ? (&texData[0]) : (DE_NULL);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "Creating a 2D depth texture and filling it with special floating point values.\n"
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "  TEXTURE_COMPARE_MODE = COMPARE_REF_TO_TEXTURE"
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< tcu::TestLog::EndMessage;
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < TEST_TEXTURE_SIZE; ++x)
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < TEST_TEXTURE_SIZE; ++y)
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texData[x * TEST_TEXTURE_SIZE + y] = rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_uploadType == UPLOAD_PBO)
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.bufferData(GL_PIXEL_UNPACK_BUFFER, (glw::GLsizeiptr)(texData.size() * sizeof(deUint32)), &texData[0], GL_STATIC_DRAW);
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, 0, GL_DEPTH_COMPONENT, GL_FLOAT, dataPtr);
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureCase::init");
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_uploadType == UPLOAD_PBO)
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "PBO used for image upload." << tcu::TestLog::EndMessage;
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.deleteBuffers(1, &m_pboID);
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_pboID = 0;
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCase::deinit (void)
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::deinit();
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureID)
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteTextures(1, &m_textureID);
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureID = 0;
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_pboID)
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteBuffers(1, &m_pboID);
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_pboID = 0;
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCase::IterateResult TextureCase::iterate (void)
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw a grid and texture it with a floating point texture containing special values. If all goes well, nothing special should happen
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				gridSize		= 16;
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec4>	gridVertices	(gridSize * gridSize);
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec2>	gridTexCoords	(gridSize * gridSize);
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint16>	indices			((gridSize - 1) * (gridSize - 1) * 6);
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			resultImage		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertices
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < gridSize; ++x)
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < gridSize; ++y)
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float posX		= (float)x / ((float)gridSize - 1.0f) * 2.0f - 1.0f; // map from [0, gridSize - 1] to [-1, 1]
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float posY		= (float)y / ((float)gridSize - 1.0f) * 2.0f - 1.0f;
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float texCoordX	= deFloatPow(2.0f, (float)x - (float)gridSize / 2.0f);
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float texCoordY	= deFloatPow(2.0f, (float)y - (float)gridSize / 2.0f);
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridVertices[x * gridSize + y]	= tcu::Vec4(posX, posY, 0.0f, 1.0f);
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridTexCoords[x * gridSize + y]	= tcu::Vec2(texCoordX, texCoordY);
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// tiles
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < gridSize - 1; ++x)
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < gridSize - 1; ++y)
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int baseNdx = (x * (gridSize - 1) + y) * 6;
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 0] = (x+0) * gridSize + (y+0);
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 1] = (x+1) * gridSize + (y+1);
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 2] = (x+1) * gridSize + (y+0);
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 3] = (x+0) * gridSize + (y+0);
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 4] = (x+1) * gridSize + (y+1);
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 5] = (x+0) * gridSize + (y+1);
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a textured grid with the shader." << tcu::TestLog::EndMessage;
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw grid
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				texCoordLoc	= gl.getAttribLocation(m_program->getProgram(), "a_attr");
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				samplerLoc	= gl.getUniformLocation(m_program->getProgram(), "u_sampler");
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_program->getProgram());
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.uniform1i(samplerLoc, 0);
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(GL_TEXTURE_2D, m_textureID);
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, &gridTexCoords[0]);
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(positionLoc);
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(texCoordLoc);
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]);
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(positionLoc);
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(texCoordLoc);
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(0);
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish();
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "TextureCase::iterate");
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify everywhere was drawn (all pixels have Green = 255)
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!checkResultImage(resultImage))
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// test drawing and textures still works
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!drawTestPattern(true))
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// all ok
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string TextureCase::genVertexSource (void) const
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertex shader is passthrough, fragment does the calculations
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TYPE_FRAGMENT)
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_attrPassthroughVertexShaderSource;
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertex shader does the calculations
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buf;
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"#version 300 es\n"
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_pos;\n"
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec2 a_attr;\n"
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"out mediump vec4 v_out;\n";
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureType == TEXTURE_FLOAT)
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"uniform highp sampler2D u_sampler;\n";
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_textureType == TEXTURE_DEPTH)
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"uniform highp sampler2DShadow u_sampler;\n";
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"void main ()\n"
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n";
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureType == TEXTURE_FLOAT)
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	v_out = vec4(textureLod(u_sampler, a_attr, 0.0).rg, 1.0, 1.0);\n";
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_textureType == TEXTURE_DEPTH)
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	highp float a1 = textureLod(u_sampler, vec3(a_attr, 0.0), 0.0);\n"
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	v_out = vec4(a1, (a1 > 1.0 || a1 < 0.0) ? (0.0) : (1.0), 1.0, 1.0);\n";
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"	gl_Position = a_pos;\n"
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string TextureCase::genFragmentSource (void) const
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// fragment shader is passthrough
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TYPE_VERTEX)
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_colorPassthroughFragmentShaderSource;
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// fragment shader does the calculations
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buf;
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"#version 300 es\n"
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 fragColor;\n";
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureType == TEXTURE_FLOAT)
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"uniform highp sampler2D u_sampler;\n";
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_textureType == TEXTURE_DEPTH)
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"uniform highp sampler2DShadow u_sampler;\n";
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"in highp vec4 v_attr;\n"
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n";
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureType == TEXTURE_FLOAT)
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	highp vec2 a1 = texture(u_sampler, v_attr.xy).rg;\n"
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	fragColor = vec4(a1.x, a1.y, 1.0, 1.0);\n";
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_textureType == TEXTURE_DEPTH)
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	highp float a1 = texture(u_sampler, vec3(v_attr.xy, 0.0));\n"
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	fragColor = vec4(a1, (a1 > 1.0 || a1 < 0.0) ? (0.0) : (1.0), 1.0, 1.0);\n";
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf << "}\n";
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests special floats as texture samping arguments
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that special floats given as texture coordinates or LOD levels
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * to sampling functions do not return invalid values (values not in the
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * texture). Every texel's green component is 1.0.
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * After the calculation test a test pattern is drawn to detect possible
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * texture sampling anomalies.
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureSamplerCase : public RenderCase
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ShaderType
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_VERTEX = 0,
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FRAGMENT,
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_LAST
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum TestType
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEST_TEX_COORD = 0,
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEST_LOD,
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEST_GRAD,
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEST_TEX_COORD_CUBE,
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEST_LAST
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TextureSamplerCase			(Context& context, const char* name, const char* desc, ShaderType type, TestType testType);
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~TextureSamplerCase			(void);
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init						(void);
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit						(void);
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate						(void);
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genVertexSource				(void) const;
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genFragmentSource			(void) const;
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderType	m_type;
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestType		m_testType;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint				m_textureID;
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureSamplerCase::TextureSamplerCase (Context& context, const char* name, const char* desc, ShaderType type, TestType testType)
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: RenderCase	(context, name, desc)
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type		(type)
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_testType	(testType)
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureID	(0)
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(type < TYPE_LAST);
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(testType < TEST_LAST);
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureSamplerCase::~TextureSamplerCase (void)
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureSamplerCase::init (void)
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// requirements
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint maxTextureSize = 0;
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (maxTextureSize < TEST_TEXTURE_SIZE)
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") + de::toString(TEST_TEXTURE_SIZE));
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::init();
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// gen texture
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<deUint8>	texData	(TEST_TEXTURE_SIZE*TEST_TEXTURE_SIZE*4);
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd		(12345);
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genTextures(1, &m_textureID);
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < TEST_TEXTURE_SIZE; ++x)
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < TEST_TEXTURE_SIZE; ++y)
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// RGBA8, green and alpha channel are always 255 for verification
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 0] = rnd.getUint32() & 0xFF;
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 1] = 0xFF;
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 2] = rnd.getUint32() & 0xFF;
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 3] = 0xFF;
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_testType == TEST_TEX_COORD)
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Creating a 2D texture with a test pattern." << tcu::TestLog::EndMessage;
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(GL_TEXTURE_2D, m_textureID);
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]);
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_testType == TEST_LOD || m_testType == TEST_GRAD)
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Creating a mipmapped 2D texture with a test pattern." << tcu::TestLog::EndMessage;
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(GL_TEXTURE_2D, m_textureID);
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int level = 0; (TEST_TEXTURE_SIZE >> level); ++level)
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.texImage2D(GL_TEXTURE_2D, level, GL_RGBA8, TEST_TEXTURE_SIZE >> level, TEST_TEXTURE_SIZE >> level, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]);
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_testType == TEST_TEX_COORD_CUBE)
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_STATIC_ASSERT(TEST_TEXTURE_CUBE_SIZE <= TEST_TEXTURE_SIZE);
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const GLenum faces[] =
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_TEXTURE_CUBE_MAP_POSITIVE_X,
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Creating a cube map with a test pattern." << tcu::TestLog::EndMessage;
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureID);
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int faceNdx = 0; faceNdx < DE_LENGTH_OF_ARRAY(faces); ++faceNdx)
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.texImage2D(faces[faceNdx], 0, GL_RGBA8, TEST_TEXTURE_CUBE_SIZE, TEST_TEXTURE_CUBE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]);
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureSamplerCase::deinit (void)
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderCase::deinit();
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureID)
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteTextures(1, &m_textureID);
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureID = 0;
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureSamplerCase::IterateResult TextureSamplerCase::iterate (void)
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw a grid and texture it with a texture and sample it using special special values. The result samples should all have the green channel at 255 as per the test image.
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec4>	gridVertices	(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::UVec2>	gridTexCoords	(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint16>	indices			((DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * 6);
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			resultImage		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertices
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float posX = (float)x / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f; // map from [0, len(s_specialFloats) - 1] to [-1, 1]
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float posY = (float)y / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f;
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridVertices[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y]	= tcu::Vec4(posX, posY, 0.0f, 1.0f);
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridTexCoords[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y]	= tcu::UVec2(s_specialFloats[x], s_specialFloats[y]);
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// tiles
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++x)
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++y)
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) + y) * 6;
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 0] = (x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0);
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 1] = (x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1);
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 2] = (x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0);
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 3] = (x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0);
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 4] = (x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1);
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 5] = (x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1);
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a textured grid with the shader. Sampling from the texture using special floating point values." << tcu::TestLog::EndMessage;
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw grid
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				texCoordLoc	= gl.getAttribLocation(m_program->getProgram(), "a_attr");
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				samplerLoc	= gl.getUniformLocation(m_program->getProgram(), "u_sampler");
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_program->getProgram());
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.uniform1i(samplerLoc, 0);
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_testType != TEST_TEX_COORD_CUBE)
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(GL_TEXTURE_2D, m_textureID);
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureID);
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, &gridTexCoords[0]);
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(positionLoc);
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(texCoordLoc);
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]);
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(positionLoc);
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(texCoordLoc);
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(0);
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.finish();
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::iterate");
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify everywhere was drawn and samples were from the texture (all pixels have Green = 255)
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!checkResultImage(resultImage))
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// test drawing and textures still works
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!drawTestPattern(true))
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// all ok
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string TextureSamplerCase::genVertexSource (void) const
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertex shader is passthrough, fragment does the calculations
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TYPE_FRAGMENT)
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_attrPassthroughVertexShaderSource;
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertex shader does the calculations
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buf;
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"#version 300 es\n"
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_pos;\n"
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec2 a_attr;\n";
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_testType != TEST_TEX_COORD_CUBE)
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"uniform highp sampler2D u_sampler;\n";
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"uniform highp samplerCube u_sampler;\n";
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"out mediump vec4 v_out;\n"
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n";
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_testType == TEST_TEX_COORD)
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	v_out = textureLod(u_sampler, a_attr, 0.0);\n";
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_testType == TEST_LOD)
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	v_out = textureLod(u_sampler, a_attr, a_attr.x);\n";
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_testType == TEST_GRAD)
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	v_out = textureGrad(u_sampler, a_attr, a_attr, a_attr.yx);\n";
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_testType == TEST_TEX_COORD_CUBE)
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	v_out = textureLod(u_sampler, vec3(a_attr, a_attr.x + a_attr.y), 0.0);\n";
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"\n"
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_pos;\n"
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string TextureSamplerCase::genFragmentSource (void) const
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// fragment shader is passthrough
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TYPE_VERTEX)
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_colorPassthroughFragmentShaderSource;
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// fragment shader does the calculations
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buf;
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"#version 300 es\n"
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 fragColor;\n";
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_testType != TEST_TEX_COORD_CUBE)
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"uniform highp sampler2D u_sampler;\n";
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"uniform highp samplerCube u_sampler;\n";
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"in highp vec4 v_attr;\n"
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n";
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_testType == TEST_TEX_COORD)
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf << "	fragColor = texture(u_sampler, v_attr.xy);\n";
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_testType == TEST_LOD)
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf << "	fragColor = texture(u_sampler, v_attr.xy, v_attr.x);\n";
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_testType == TEST_GRAD)
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	fragColor = textureGrad(u_sampler, v_attr.xy, v_attr.xy, v_attr.yx);\n";
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_testType == TEST_TEX_COORD_CUBE)
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	fragColor = texture(u_sampler, vec3(v_attr.xy,v_attr.x + v_attr.y));\n";
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"}\n";
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests special floats as fragment shader outputs
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that outputting special floats from a fragment shader does not change
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the normal floating point values of outputted from a fragment shader. Special
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * floats are outputted in the green component, normal floating point values
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * in the red and blue component. Potential changes are tested by rendering
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * test pattern two times with different floating point values. The resulting
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * images' red and blue channels should be equal.
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass OutputCase : public FramebufferRenderCase
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						OutputCase				(Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type);
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~OutputCase				(void);
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				testFBO					(void);
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genVertexSource			(void) const;
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genFragmentSource		(void) const;
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryOutputCase::OutputCase (Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type)
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: FramebufferRenderCase	(context, name, desc, type)
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryOutputCase::~OutputCase (void)
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid OutputCase::testFBO (void)
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create a 1 X [s_specialFloats] grid of tiles (stripes).
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec4>	gridVertices	((DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) * 2);
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint16>	indices			(DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureFormat		textureFormat	(tcu::TextureFormat::RGBA, (m_fboType == FBO_RGBA_FLOAT16 || m_fboType == FBO_RGBA_FLOAT32) ? (tcu::TextureFormat::FLOAT) : (tcu::TextureFormat::UNORM_INT8));
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel		specialImage	(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel		normalImage		(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertices
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++y)
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float posY = (float)y / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f; // map from [0, len(s_specialFloats) ] to [-1, 1]
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridVertices[y * 2 + 0] = tcu::Vec4(-1.0, posY, 0.0f, 1.0f);
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridVertices[y * 2 + 1] = tcu::Vec4( 1.0, posY, 0.0f, 1.0f);
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// tiles
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int baseNdx = y * 6;
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 0] = (y + 0) * 2;
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 1] = (y + 1) * 2;
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 2] = (y + 1) * 2 + 1;
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 3] = (y + 0) * 2;
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 4] = (y + 1) * 2 + 1;
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 5] = (y + 0) * 2 + 1;
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw grids
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				specialLoc	= gl.getUniformLocation(m_program->getProgram(), "u_special");
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_program->getProgram());
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw");
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(positionLoc);
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// draw 2 passes. Special and normal.
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int passNdx = 0; passNdx < 2; ++passNdx)
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool specialPass	= (passNdx == 0);
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Pass " << passNdx << ": Drawing stripes with the shader. Setting u_special for each stripe to (" << ((specialPass) ? ("special") : ("1.0")) << ")." << tcu::TestLog::EndMessage;
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// draw stripes
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clear(GL_COLOR_BUFFER_BIT);
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	one				= 0x3F800000;
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	special			= s_specialFloats[y];
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	uniformValue	= (specialPass) ? (special) : (one);
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		indexIndex		= y * 6;
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.uniform1fv(specialLoc, 1, (const float*)&uniformValue);
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.finish();
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_context.getRenderContext(), 0, 0, ((specialPass) ? (specialImage) : (normalImage)).getAccess());
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(positionLoc);
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(0);
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "OutputCase::iterate");
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check results
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface		errorMask		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA		badPixelColor	= tcu::RGBA::red;
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA		okPixelColor	= tcu::RGBA::green;
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					badPixels		= 0;
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Checking passes have identical red and blue channels and the green channel is correct in the constant pass." << tcu::TestLog::EndMessage;
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < specialImage.getHeight(); ++y)
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < specialImage.getWidth(); ++x)
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		greenThreshold	= 0.1f;
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4	cNormal			= normalImage.getAccess().getPixel(x, y);
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4	cSpecial		= specialImage.getAccess().getPixel(x, y);
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (cNormal.x() != cSpecial.x() || cNormal.z() != cSpecial.z() || cNormal.y() < 1.0f - greenThreshold)
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				++badPixels;
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				errorMask.setPixel(x, y, badPixelColor);
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				errorMask.setPixel(x, y, okPixelColor);
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Found " << badPixels << " invalid pixel(s)." << tcu::TestLog::EndMessage;
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (badPixels)
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog()
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::ImageSet("Results", "Result verification")
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::Image("Image with special green channel",	"Image with special green channel",		specialImage)
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::Image("Image with constant green channel",	"Image with constant green channel",	normalImage)
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::Image("Error Mask",						"Error Mask",							errorMask)
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::EndImageSet;
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// all ok?
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string OutputCase::genVertexSource (void) const
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec4 a_pos;\n"
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"out highp vec2 v_pos;\n"
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main ()\n"
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_pos;\n"
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_pos = a_pos.xy;\n"
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string OutputCase::genFragmentSource (void) const
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out highp vec4 fragColor;\n"
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp float u_special;\n"
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec2 v_pos;\n"
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main ()\n"
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	fragColor = vec4((v_pos.x + 1.0) * 0.5, u_special, (v_pos.y + 1.0) * 0.5, 1.0);\n"
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests special floats in blending
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests special floats as alpha and color components with various blending
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * modes. Test draws a test pattern and then does various blend operations
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * with special float values. After the blending test another test pattern
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is drawn to detect possible blending anomalies. Test patterns should be
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * identical.
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BlendingCase : public FramebufferRenderCase
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						BlendingCase			(Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type);
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~BlendingCase			(void);
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				testFBO					(void);
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				drawTestImage			(tcu::PixelBufferAccess dst, GLuint uColorLoc, int maxVertexIndex);
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genVertexSource			(void) const;
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genFragmentSource		(void) const;
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlendingCase::BlendingCase (Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type)
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: FramebufferRenderCase	(context, name, desc, type)
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlendingCase::~BlendingCase (void)
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlendingCase::testFBO (void)
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const GLenum equations[] =
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_FUNC_ADD,
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_FUNC_SUBTRACT,
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_FUNC_REVERSE_SUBTRACT,
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_MIN,
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_MAX
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const GLenum functions[] =
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_ZERO,
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_ONE,
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_SRC_COLOR,
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_ONE_MINUS_SRC_COLOR,
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_SRC_ALPHA,
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_ONE_MINUS_SRC_ALPHA,
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create a [BlendFuncs] X [s_specialFloats] grid of tiles. ( BlendFuncs = equations x functions )
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numBlendFuncs	= DE_LENGTH_OF_ARRAY(equations) * DE_LENGTH_OF_ARRAY(functions);
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec4>			gridVertices	((numBlendFuncs + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1));
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint16>			indices			(numBlendFuncs * DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureFormat				textureFormat	(tcu::TextureFormat::RGBA, (m_fboType == FBO_RGBA_FLOAT16 || m_fboType == FBO_RGBA_FLOAT32) ? (tcu::TextureFormat::FLOAT) : (tcu::TextureFormat::UNORM_INT8));
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel				beforeImage		(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel				afterImage		(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vertices
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++x)
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < numBlendFuncs + 1; ++y)
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		posX	= (float)x / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f; // map from [0, len(s_specialFloats)] to [-1, 1]
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		posY	= (float)y / (float)numBlendFuncs * 2.0f - 1.0f;
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gridVertices[x * (numBlendFuncs + 1) + y]	= tcu::Vec4(posX, posY, 0.0f, 1.0f);
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// tiles
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < numBlendFuncs; ++y)
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int baseNdx = (x * numBlendFuncs + y) * 6;
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 0] = (x+0) * (numBlendFuncs + 1) + (y+0);
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 1] = (x+1) * (numBlendFuncs + 1) + (y+1);
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 2] = (x+1) * (numBlendFuncs + 1) + (y+0);
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 3] = (x+0) * (numBlendFuncs + 1) + (y+0);
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 4] = (x+1) * (numBlendFuncs + 1) + (y+1);
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[baseNdx + 5] = (x+0) * (numBlendFuncs + 1) + (y+1);
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw tiles
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numPasses	= 5;
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint				specialLoc	= gl.getUniformLocation(m_program->getProgram(), "u_special");
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_program->getProgram());
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable(GL_BLEND);
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw");
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(positionLoc);
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// draw "before" image
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Drawing pre-draw pattern." << tcu::TestLog::EndMessage;
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawTestImage(beforeImage.getAccess(), specialLoc, (int)gridVertices.size() - 1);
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw pattern");
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// draw multiple passes with special floats
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int passNdx = 0; passNdx < numPasses; ++passNdx)
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			de::Random rnd(123 + 567 * passNdx);
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog()
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< tcu::TestLog::Message
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "Pass " << passNdx << ": Drawing tiles with the shader.\n"
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tVarying u_special for each tile.\n"
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\tVarying blend function and blend equation for each tile.\n"
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< tcu::TestLog::EndMessage;
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// draw tiles
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < numBlendFuncs; ++y)
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLenum		blendEquation		= equations[y % DE_LENGTH_OF_ARRAY(equations)];
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLenum		blendFunction		= functions[y / DE_LENGTH_OF_ARRAY(equations)];
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLenum		blendFunctionDst	= rnd.choose<GLenum>(DE_ARRAY_BEGIN(functions), DE_ARRAY_END(functions));
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			indexIndex			= (x * numBlendFuncs + y) * 6;
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// "rnd.get"s are run in a deterministic order
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32		componentR			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32		componentG			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32		componentB			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32		componentA			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::UVec4	uniformValue		= tcu::UVec4(componentR, componentG, componentB, componentA);
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.uniform4fv(specialLoc, 1, (const float*)uniformValue.getPtr());
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.blendEquation(blendEquation);
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.blendFunc(blendFunction, blendFunctionDst);
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "special passes");
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// draw "after" image
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Drawing post-draw pattern." << tcu::TestLog::EndMessage;
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawTestImage(afterImage.getAccess(), specialLoc, (int)gridVertices.size() - 1);
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "post-draw pattern");
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(positionLoc);
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(0);
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "OutputCase::iterate");
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check results
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface		errorMask		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA		badPixelColor	= tcu::RGBA::red;
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA		okPixelColor	= tcu::RGBA::green;
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					badPixels		= 0;
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Checking patterns are identical." << tcu::TestLog::EndMessage;
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < beforeImage.getHeight(); ++y)
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < beforeImage.getWidth(); ++x)
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4	cBefore	= beforeImage.getAccess().getPixel(x, y);
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4	cAfter	= afterImage.getAccess().getPixel(x, y);
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (cBefore != cAfter)
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				++badPixels;
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				errorMask.setPixel(x, y, badPixelColor);
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				errorMask.setPixel(x, y, okPixelColor);
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Found " << badPixels << " invalid pixel(s)." << tcu::TestLog::EndMessage;
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (badPixels)
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog()
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::ImageSet("Results", "Result verification")
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::Image("Pattern drawn before special float blending",	"Pattern drawn before special float blending",		beforeImage)
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::Image("Pattern drawn after special float blending",	"Pattern drawn after special float blending",		afterImage)
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::EndImageSet;
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// all ok?
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlendingCase::drawTestImage (tcu::PixelBufferAccess dst, GLuint uColorLoc, int maxVertexIndex)
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd	(123);
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.blendEquation(GL_FUNC_ADD);
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.blendFunc(GL_ONE, GL_ONE);
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int tri = 0; tri < 20; ++tri)
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4 color;
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		color.x() = rnd.getFloat();
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		color.y() = rnd.getFloat();
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		color.z() = rnd.getFloat();
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		color.w() = rnd.getFloat();
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.uniform4fv(uColorLoc, 1, color.getPtr());
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint16 indices[3];
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[0] = rnd.getInt(0, maxVertexIndex);
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[1] = rnd.getInt(0, maxVertexIndex);
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		indices[2] = rnd.getInt(0, maxVertexIndex);
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, indices);
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.finish();
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), 0, 0, dst);
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string BlendingCase::genVertexSource (void) const
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec4 a_pos;\n"
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main ()\n"
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_pos;\n"
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string BlendingCase::genFragmentSource (void) const
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out highp vec4 fragColor;\n"
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp vec4 u_special;\n"
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main ()\n"
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	fragColor = u_special;\n"
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} //anonymous
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20773c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySpecialFloatTests::SpecialFloatTests (Context& context)
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "special_float", "Special float tests")
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20823c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySpecialFloatTests::~SpecialFloatTests (void)
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SpecialFloatTests::init (void)
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const vertexGroup		= new tcu::TestCaseGroup(m_testCtx, "vertex",		"Run vertex shader with special float values");
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const fragmentGroup		= new tcu::TestCaseGroup(m_testCtx, "fragment",		"Run fragment shader with special float values");
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const framebufferGroup	= new tcu::TestCaseGroup(m_testCtx, "framebuffer",	"Test framebuffers containing special float values");
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .vertex
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new VertexAttributeCase	(m_context, "attribute_buffer",			"special attribute values in a buffer",					VertexAttributeCase::STORAGE_BUFFER, VertexAttributeCase::TYPE_VERTEX));
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new VertexAttributeCase	(m_context, "attribute_client",			"special attribute values in a client storage",			VertexAttributeCase::STORAGE_CLIENT, VertexAttributeCase::TYPE_VERTEX));
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new UniformCase			(m_context, "uniform",					"special uniform values",								UniformCase::TYPE_VERTEX));
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new TextureCase			(m_context, "texture",					"texture with special floating point values",			TextureCase::TYPE_VERTEX, TextureCase::TEXTURE_FLOAT, TextureCase::UPLOAD_CLIENT));
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new TextureCase			(m_context, "texture_pbo",				"texture (via pbo) with special floating point values",	TextureCase::TYPE_VERTEX, TextureCase::TEXTURE_FLOAT, TextureCase::UPLOAD_PBO));
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new TextureCase			(m_context, "texture_shadow",			"shadow texture with special floating point values",	TextureCase::TYPE_VERTEX, TextureCase::TEXTURE_DEPTH, TextureCase::UPLOAD_CLIENT));
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new TextureSamplerCase	(m_context, "sampler_tex_coord",		"special texture coords",								TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_TEX_COORD));
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new TextureSamplerCase	(m_context, "sampler_tex_coord_cube",	"special texture coords to cubemap",					TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_TEX_COORD_CUBE));
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new TextureSamplerCase	(m_context, "sampler_lod",				"special texture lod",									TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_LOD));
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexGroup->addChild(new TextureSamplerCase	(m_context, "sampler_grad",				"special texture grad",									TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_GRAD));
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(vertexGroup);
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .fragment
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new VertexAttributeCase	(m_context, "attribute_buffer",			"special attribute values in a buffer",					VertexAttributeCase::STORAGE_BUFFER, VertexAttributeCase::TYPE_FRAGMENT));
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new VertexAttributeCase	(m_context, "attribute_client",			"special attribute values in a client storage",			VertexAttributeCase::STORAGE_CLIENT, VertexAttributeCase::TYPE_FRAGMENT));
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new UniformCase			(m_context, "uniform",					"special uniform values",								UniformCase::TYPE_FRAGMENT));
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new TextureCase			(m_context, "texture",					"texture with special floating point values",			TextureCase::TYPE_FRAGMENT, TextureCase::TEXTURE_FLOAT, TextureCase::UPLOAD_CLIENT));
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new TextureCase			(m_context, "texture_pbo",				"texture (via pbo) with special floating point values",	TextureCase::TYPE_FRAGMENT, TextureCase::TEXTURE_FLOAT, TextureCase::UPLOAD_PBO));
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new TextureCase			(m_context, "texture_shadow",			"shadow texture with special floating point values",	TextureCase::TYPE_FRAGMENT, TextureCase::TEXTURE_DEPTH, TextureCase::UPLOAD_CLIENT));
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new TextureSamplerCase	(m_context, "sampler_tex_coord",		"special texture coords",								TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_TEX_COORD));
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new TextureSamplerCase	(m_context, "sampler_tex_coord_cube",	"special texture coords to cubemap",					TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_TEX_COORD_CUBE));
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new TextureSamplerCase	(m_context, "sampler_lod",				"special texture lod",									TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_LOD));
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentGroup->addChild(new TextureSamplerCase	(m_context, "sampler_grad",				"special texture grad",									TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_GRAD));
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(fragmentGroup);
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .framebuffer
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new OutputCase		(m_context, "write_default",			"write special floating point values to default framebuffer",	FramebufferRenderCase::FBO_DEFAULT));
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgba4",				"write special floating point values to RGBA4 framebuffer",		FramebufferRenderCase::FBO_RGBA4));
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgb5_a1",			"write special floating point values to RGB5_A1 framebuffer",	FramebufferRenderCase::FBO_RGB5_A1));
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgb565",				"write special floating point values to RGB565 framebuffer",	FramebufferRenderCase::FBO_RGB565));
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgba8",				"write special floating point values to RGBA8 framebuffer",		FramebufferRenderCase::FBO_RGBA8));
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgb10_a2",			"write special floating point values to RGB10_A2 framebuffer",	FramebufferRenderCase::FBO_RGB10_A2));
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new OutputCase		(m_context, "write_float16",			"write special floating point values to float16 framebuffer",	FramebufferRenderCase::FBO_RGBA_FLOAT16));
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new OutputCase		(m_context, "write_float32",			"write special floating point values to float32 framebuffer",	FramebufferRenderCase::FBO_RGBA_FLOAT32));
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new BlendingCase		(m_context, "blend_default",			"blend special floating point values in a default framebuffer",	FramebufferRenderCase::FBO_DEFAULT));
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new BlendingCase		(m_context, "blend_rgba8",				"blend special floating point values in a RGBA8 framebuffer",	FramebufferRenderCase::FBO_RGBA8));
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferGroup->addChild(new BlendingCase		(m_context, "blend_float16",			"blend special floating point values in a float16 framebuffer",	FramebufferRenderCase::FBO_RGBA_FLOAT16));
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(framebufferGroup);
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Stress
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2146