/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Special float stress tests.
 *//*--------------------------------------------------------------------*/

#include "es3sSpecialFloatTests.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"
#include "gluContextInfo.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "deStringUtil.hpp"
#include "deMath.h"
#include "deRandom.hpp"

#include <limits>
#include <sstream>

using namespace glw;

namespace deqp
{
namespace gles3
{
namespace Stress
{
namespace
{

static const int		TEST_CANVAS_SIZE		= 256;
static const int		TEST_TEXTURE_SIZE		= 128;
static const int		TEST_TEXTURE_CUBE_SIZE	= 32;
static const deUint32	s_specialFloats[]		=
{
	0x00000000,	//          zero
	0x80000000,	// negative zero
	0x3F800000,	//          one
	0xBF800000,	// negative one
	0x00800000,	// minimum positive normalized value
	0x80800000,	// maximum negative normalized value
	0x00000001,	// minimum positive denorm value
	0x80000001,	// maximum negative denorm value
	0x7F7FFFFF,	// maximum finite value.
	0xFF7FFFFF,	// minimum finite value.
	0x7F800000,	//  inf
	0xFF800000,	// -inf
	0x34000000,	//          epsilon
	0xB4000000,	// negative epsilon
	0x7FC00000,	//          quiet_NaN
	0xFFC00000,	// negative quiet_NaN
	0x7FC00001,	//          signaling_NaN
	0xFFC00001,	// negative signaling_NaN
	0x7FEAAAAA,	//          quiet payloaded NaN		(payload of repeated pattern of 101010...)
	0xFFEAAAAA,	// negative quiet payloaded NaN		( .. )
	0x7FAAAAAA,	//          signaling payloaded NaN	( .. )
	0xFFAAAAAA,	// negative signaling payloaded NaN	( .. )
};

static const char* const s_colorPassthroughFragmentShaderSource	=	"#version 300 es\n"
																	"layout(location = 0) out mediump vec4 fragColor;\n"
																	"in mediump vec4 v_out;\n"
																	"void main ()\n"
																	"{\n"
																	"	fragColor = v_out;\n"
																	"}\n";
static const char* const s_attrPassthroughVertexShaderSource	=	"#version 300 es\n"
																	"in highp vec4 a_pos;\n"
																	"in highp vec4 a_attr;\n"
																	"out highp vec4 v_attr;\n"
																	"void main ()\n"
																	"{\n"
																	"	v_attr = a_attr;\n"
																	"	gl_Position = a_pos;\n"
																	"}\n";

class RenderCase : public TestCase
{
public:
	enum RenderTargetType
	{
		RENDERTARGETTYPE_SCREEN,
		RENDERTARGETTYPE_FBO
	};

								RenderCase			(Context& context, const char* name, const char* desc, RenderTargetType renderTargetType = RENDERTARGETTYPE_SCREEN);
	virtual						~RenderCase			(void);

	virtual void				init				(void);
	virtual void				deinit				(void);

protected:
	bool						checkResultImage	(const tcu::Surface& result);
	bool						drawTestPattern		(bool useTexture);

	virtual std::string			genVertexSource		(void) const = 0;
	virtual std::string			genFragmentSource	(void) const = 0;

	const glu::ShaderProgram*	m_program;
	const RenderTargetType		m_renderTargetType;
};

RenderCase::RenderCase (Context& context, const char* name, const char* desc, RenderTargetType renderTargetType)
	: TestCase				(context, name, desc)
	, m_program				(DE_NULL)
	, m_renderTargetType	(renderTargetType)
{
}

RenderCase::~RenderCase (void)
{
	deinit();
}

void RenderCase::init (void)
{
	const int width	 = m_context.getRenderTarget().getWidth();
	const int height = m_context.getRenderTarget().getHeight();

	// check target size
	if (m_renderTargetType == RENDERTARGETTYPE_SCREEN)
	{
		if (width < TEST_CANVAS_SIZE || height < TEST_CANVAS_SIZE)
			throw tcu::NotSupportedError(std::string("Render target size must be at least ") + de::toString(TEST_CANVAS_SIZE) + "x" + de::toString(TEST_CANVAS_SIZE));
	}
	else if (m_renderTargetType == RENDERTARGETTYPE_FBO)
	{
		GLint maxTexSize = 0;
		m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);

		if (maxTexSize < TEST_CANVAS_SIZE)
			throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") + de::toString(TEST_CANVAS_SIZE));
	}
	else
		DE_ASSERT(false);

	// gen shader

	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shader." << tcu::TestLog::EndMessage;

	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource()) << glu::FragmentSource(genFragmentSource()));
	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
		throw tcu::TestError("shader compile failed");
}

void RenderCase::deinit (void)
{
	if (m_program)
	{
		delete m_program;
		m_program = DE_NULL;
	}
}

bool RenderCase::checkResultImage (const tcu::Surface& result)
{
	tcu::Surface	errorMask	(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
	bool			error		= false;

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image." << tcu::TestLog::EndMessage;

	for (int y = 0; y < TEST_CANVAS_SIZE; ++y)
	for (int x = 0; x < TEST_CANVAS_SIZE; ++x)
	{
		const tcu::RGBA col = result.getPixel(x, y);

		if (col.getGreen() == 255)
			errorMask.setPixel(x, y, tcu::RGBA::green());
		else
		{
			errorMask.setPixel(x, y, tcu::RGBA::red());
			error = true;
		}
	}

	if (error)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Result image has missing or invalid pixels" << tcu::TestLog::EndMessage;
		m_testCtx.getLog()
			<< tcu::TestLog::ImageSet("Results", "Result verification")
			<< tcu::TestLog::Image("Result",		"Result",		result)
			<< tcu::TestLog::Image("Error mask",	"Error mask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::ImageSet("Results", "Result verification")
			<< tcu::TestLog::Image("Result", "Result", result)
			<< tcu::TestLog::EndImageSet;
	}

	return !error;
}

bool RenderCase::drawTestPattern (bool useTexture)
{
	static const tcu::Vec4 fullscreenQuad[4] =
	{
		tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
	};
	const char* const	vertexSource		=	"#version 300 es\n"
												"in highp vec4 a_pos;\n"
												"out mediump vec4 v_position;\n"
												"void main ()\n"
												"{\n"
												"	v_position = a_pos;\n"
												"	gl_Position = a_pos;\n"
												"}\n";
	const char* const	fragmentSourceNoTex	=	"#version 300 es\n"
												"layout(location = 0) out mediump vec4 fragColor;\n"
												"in mediump vec4 v_position;\n"
												"void main ()\n"
												"{\n"
												"	fragColor = vec4((v_position.x + 1.0) * 0.5, 1.0, 1.0, 1.0);\n"
												"}\n";
	const char* const	fragmentSourceTex	=	"#version 300 es\n"
												"layout(location = 0) out mediump vec4 fragColor;\n"
												"uniform mediump sampler2D u_sampler;\n"
												"in mediump vec4 v_position;\n"
												"void main ()\n"
												"{\n"
												"	fragColor = texture(u_sampler, v_position.xy);\n"
												"}\n";
	const char* const	fragmentSource		=	(useTexture) ? (fragmentSourceTex) : (fragmentSourceNoTex);
	const tcu::RGBA		formatThreshold		= m_context.getRenderTarget().getPixelFormat().getColorThreshold();

	tcu::Surface		resultImage			(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
	tcu::Surface		errorMask			(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
	bool				error				=	false;

	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a test pattern to detect " << ((useTexture) ? ("texture sampling") : ("")) << " side-effects." << tcu::TestLog::EndMessage;

	// draw pattern
	{
		const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
		const glu::ShaderProgram	patternProgram	(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vertexSource) << glu::FragmentSource(fragmentSource));
		const GLint					positionLoc		= gl.getAttribLocation(patternProgram.getProgram(), "a_pos");
		GLuint						textureID		= 0;

		if (useTexture)
		{
			const int textureSize = 32;
			std::vector<tcu::Vector<deUint8, 4> > buffer(textureSize*textureSize);

			for (int x = 0; x < textureSize; ++x)
			for (int y = 0; y < textureSize; ++y)
			{
				// sum of two axis aligned gradients. Each gradient is 127 at the edges and 0 at the center.
				// pattern is symmetric (x and y) => no discontinuity near boundary => no need to worry of results with LINEAR filtering near boundaries
				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);

				buffer[x * textureSize + y] = tcu::Vector<deUint8, 4>(redComponent, 255, 255, 255);
			}

			gl.genTextures(1, &textureID);
			gl.bindTexture(GL_TEXTURE_2D, textureID);
			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureSize, textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer[0].getPtr());
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		}

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		gl.useProgram(patternProgram.getProgram());

		if (useTexture)
			gl.uniform1i(gl.getUniformLocation(patternProgram.getProgram(), "u_sampler"), 0);

		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &fullscreenQuad[0]);

		gl.enableVertexAttribArray(positionLoc);
		gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
		gl.disableVertexAttribArray(positionLoc);

		gl.useProgram(0);
		gl.finish();
		GLU_EXPECT_NO_ERROR(gl.getError(), "RenderCase::drawTestPattern");

		if (textureID)
			gl.deleteTextures(1, &textureID);

		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
	}

	// verify pattern
	for (int y = 0; y < TEST_CANVAS_SIZE; ++y)
	for (int x = 0; x < TEST_CANVAS_SIZE; ++x)
	{
		const float			texGradientPosX = deFloatFrac((float)x * 2.0f / (float)TEST_CANVAS_SIZE);
		const float			texGradientPosY = deFloatFrac((float)y * 2.0f / (float)TEST_CANVAS_SIZE);
		const deUint8		texRedComponent = (deUint8)de::clamp(de::abs(texGradientPosX - 0.5f) * 255.0f + de::abs(texGradientPosY - 0.5f) * 255.0f, 0.0f, 255.0f);

		const tcu::RGBA		refColTexture	= tcu::RGBA(texRedComponent, 255, 255, 255);
		const tcu::RGBA		refColGradient	= tcu::RGBA((int)((float)x / (float)TEST_CANVAS_SIZE * 255.0f), 255, 255, 255);
		const tcu::RGBA&	refCol			= (useTexture) ? (refColTexture) : (refColGradient);

		const int			colorThreshold	= 10;
		const tcu::RGBA		col				= resultImage.getPixel(x, y);
		const tcu::IVec4	colorDiff		= tcu::abs(col.toIVec() - refCol.toIVec());

		if (colorDiff.x() > formatThreshold.getRed()   + colorThreshold ||
			colorDiff.y() > formatThreshold.getGreen() + colorThreshold ||
			colorDiff.z() > formatThreshold.getBlue()  + colorThreshold)
		{
			errorMask.setPixel(x, y, tcu::RGBA::red());
			error = true;
		}
		else
			errorMask.setPixel(x, y, tcu::RGBA::green());
	}

	// report error
	if (error)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Test pattern has missing/invalid pixels" << tcu::TestLog::EndMessage;
		m_testCtx.getLog()
			<< tcu::TestLog::ImageSet("Results", "Result verification")
			<< tcu::TestLog::Image("Result",		"Result",		resultImage)
			<< tcu::TestLog::Image("Error mask",	"Error mask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
		m_testCtx.getLog() << tcu::TestLog::Message << "No side-effects found." << tcu::TestLog::EndMessage;

	return !error;
}

class FramebufferRenderCase : public RenderCase
{
public:
	enum FrameBufferType
	{
		FBO_DEFAULT = 0,
		FBO_RGBA4,
		FBO_RGB5_A1,
		FBO_RGB565,
		FBO_RGBA8,
		FBO_RGB10_A2,
		FBO_RGBA_FLOAT16,
		FBO_RGBA_FLOAT32,

		FBO_LAST
	};

							FramebufferRenderCase	(Context& context, const char* name, const char* desc, FrameBufferType fboType);
	virtual					~FramebufferRenderCase	(void);

	virtual void			init					(void);
	virtual void			deinit					(void);
	IterateResult			iterate					(void);

	virtual void			testFBO					(void) = DE_NULL;

protected:
	const FrameBufferType	m_fboType;

private:
	GLuint					m_texID;
	GLuint					m_fboID;
};

FramebufferRenderCase::FramebufferRenderCase (Context& context, const char* name, const char* desc, FrameBufferType fboType)
	: RenderCase	(context, name, desc, (fboType == FBO_DEFAULT) ? (RENDERTARGETTYPE_SCREEN) : (RENDERTARGETTYPE_FBO))
	, m_fboType		(fboType)
	, m_texID		(0)
	, m_fboID		(0)
{
	DE_ASSERT(m_fboType < FBO_LAST);
}

FramebufferRenderCase::~FramebufferRenderCase (void)
{
	deinit();
}

void FramebufferRenderCase::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// check requirements
	if (m_fboType == FBO_RGBA_FLOAT16)
	{
		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_half_float") &&
			!m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_float"))
			throw tcu::NotSupportedError("Color renderable half float texture required.");
	}
	else if (m_fboType == FBO_RGBA_FLOAT32)
	{
		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_float"))
			throw tcu::NotSupportedError("Color renderable float texture required.");
	}

	// gen shader
	RenderCase::init();

	// create render target
	if (m_fboType == FBO_DEFAULT)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Using default framebuffer." << tcu::TestLog::EndMessage;
	}
	else
	{
		GLuint internalFormat	= 0;
		GLuint format			= 0;
		GLuint type				= 0;

		switch (m_fboType)
		{
			case FBO_RGBA4:			internalFormat = GL_RGBA4;		format = GL_RGBA;	type = GL_UNSIGNED_SHORT_4_4_4_4;		break;
			case FBO_RGB5_A1:		internalFormat = GL_RGB5_A1;	format = GL_RGBA;	type = GL_UNSIGNED_SHORT_5_5_5_1;		break;
			case FBO_RGB565:		internalFormat = GL_RGB565;		format = GL_RGB;	type = GL_UNSIGNED_SHORT_5_6_5;			break;
			case FBO_RGBA8:			internalFormat = GL_RGBA8;		format = GL_RGBA;	type = GL_UNSIGNED_BYTE;				break;
			case FBO_RGB10_A2:		internalFormat = GL_RGB10_A2;	format = GL_RGBA;	type = GL_UNSIGNED_INT_2_10_10_10_REV;	break;
			case FBO_RGBA_FLOAT16:	internalFormat = GL_RGBA16F;	format = GL_RGBA;	type = GL_HALF_FLOAT;					break;
			case FBO_RGBA_FLOAT32:	internalFormat = GL_RGBA32F;	format = GL_RGBA;	type = GL_FLOAT;						break;

			default:
				DE_ASSERT(false);
				break;
		}

		m_testCtx.getLog() << tcu::TestLog::Message
			<< "Creating fbo. Texture internalFormat = " << glu::getTextureFormatStr(internalFormat)
			<< ", format = " << glu::getTextureFormatStr(format)
			<< ", type = " << glu::getTypeStr(type)
			<< tcu::TestLog::EndMessage;

		// gen texture
		gl.genTextures(1, &m_texID);
		gl.bindTexture(GL_TEXTURE_2D, m_texID);
		gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE, 0, format, type, DE_NULL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "texture init");

		// gen fbo
		gl.genFramebuffers(1, &m_fboID);
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texID, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "fbo init");

		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
			throw tcu::NotSupportedError("could not create fbo for testing.");
	}
}

void FramebufferRenderCase::deinit (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_texID)
	{
		gl.deleteTextures(1, &m_texID);
		m_texID = 0;
	}

	if (m_fboID)
	{
		gl.deleteFramebuffers(1, &m_fboID);
		m_fboID = 0;
	}
}

FramebufferRenderCase::IterateResult FramebufferRenderCase::iterate (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// bind fbo (or don't if we are using default)
	if (m_fboID)
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);

	// do something with special floats
	testFBO();

	return STOP;
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests special floats as vertex attributes
 *
 * Tests that special floats transferred to the shader using vertex
 * attributes do not change the results of normal floating point
 * calculations. Special floats are put to 4-vector's x and y components and
 * value 1.0 is put to z and w. The resulting fragment's green channel
 * should be 1.0 everywhere.
 *
 * After the calculation test a test pattern is drawn to detect possible
 * floating point operation anomalies.
 *//*--------------------------------------------------------------------*/
class VertexAttributeCase : public RenderCase
{
public:
	enum Storage
	{
		STORAGE_BUFFER = 0,
		STORAGE_CLIENT,

		STORAGE_LAST
	};
	enum ShaderType
	{
		TYPE_VERTEX = 0,
		TYPE_FRAGMENT,

		TYPE_LAST
	};

						VertexAttributeCase			(Context& context, const char* name, const char* desc, Storage storage, ShaderType type);
						~VertexAttributeCase		(void);

	void				init						(void);
	void				deinit						(void);
	IterateResult		iterate						(void);

private:
	std::string			genVertexSource				(void) const;
	std::string			genFragmentSource			(void) const;

	const Storage		m_storage;
	const ShaderType	m_type;
	GLuint				m_positionVboID;
	GLuint				m_attribVboID;
	GLuint				m_elementVboID;
};

VertexAttributeCase::VertexAttributeCase (Context& context, const char* name, const char* desc, Storage storage, ShaderType type)
	: RenderCase			(context, name, desc)
	, m_storage				(storage)
	, m_type				(type)
	, m_positionVboID		(0)
	, m_attribVboID			(0)
	, m_elementVboID		(0)
{
	DE_ASSERT(storage < STORAGE_LAST);
	DE_ASSERT(type < TYPE_LAST);
}

VertexAttributeCase::~VertexAttributeCase (void)
{
	deinit();
}

void VertexAttributeCase::init (void)
{
	RenderCase::init();

	// init gl resources
	if (m_storage == STORAGE_BUFFER)
	{
		const glw::Functions& gl = m_context.getRenderContext().getFunctions();

		gl.genBuffers(1, &m_positionVboID);
		gl.genBuffers(1, &m_attribVboID);
		gl.genBuffers(1, &m_elementVboID);
	}
}

void VertexAttributeCase::deinit (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	RenderCase::deinit();

	if (m_attribVboID)
	{
		gl.deleteBuffers(1, &m_attribVboID);
		m_attribVboID = 0;
	}

	if (m_positionVboID)
	{
		gl.deleteBuffers(1, &m_positionVboID);
		m_positionVboID = 0;
	}

	if (m_elementVboID)
	{
		gl.deleteBuffers(1, &m_elementVboID);
		m_elementVboID = 0;
	}
}

VertexAttributeCase::IterateResult VertexAttributeCase::iterate (void)
{
	// Create a [s_specialFloats] X [s_specialFloats] grid of vertices with each vertex having 2 [s_specialFloats] values
	// and calculate some basic operations with the floating point values. If all goes well, nothing special should happen

	std::vector<tcu::Vec4>	gridVertices	(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
	std::vector<tcu::UVec4>	gridAttributes	(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
	std::vector<deUint16>	indices			((DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * 6);
	tcu::Surface			resultImage		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);

	// vertices
	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
	{
		const deUint32	one		= 0x3F800000;
		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]
		const float		posY	= (float)y / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f;

		gridVertices[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y]	= tcu::Vec4(posX, posY, 0.0f, 1.0f);
		gridAttributes[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y]	= tcu::UVec4(s_specialFloats[x], s_specialFloats[y], one, one);
	}

	// tiles
	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++x)
	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++y)
	{
		const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) + y) * 6;

		indices[baseNdx + 0] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0));
		indices[baseNdx + 1] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1));
		indices[baseNdx + 2] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0));

		indices[baseNdx + 3] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0));
		indices[baseNdx + 4] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1));
		indices[baseNdx + 5] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1));
	}

	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;

	// Draw grid
	{
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
		const GLint				attribLoc	= gl.getAttribLocation(m_program->getProgram(), "a_attr");

		if (m_storage == STORAGE_BUFFER)
		{
			gl.bindBuffer(GL_ARRAY_BUFFER, m_positionVboID);
			gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(gridVertices.size() * sizeof(tcu::Vec4)), &gridVertices[0], GL_STATIC_DRAW);
			GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");

			gl.bindBuffer(GL_ARRAY_BUFFER, m_attribVboID);
			gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(gridAttributes.size() * sizeof(tcu::UVec4)), &gridAttributes[0], GL_STATIC_DRAW);
			GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");

			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementVboID);
			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indices.size() * sizeof(deUint16)), &indices[0], GL_STATIC_DRAW);
			GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
		}

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		gl.useProgram(m_program->getProgram());

		if (m_storage == STORAGE_BUFFER)
		{
			gl.bindBuffer(GL_ARRAY_BUFFER, m_positionVboID);
			gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);

			gl.bindBuffer(GL_ARRAY_BUFFER, m_attribVboID);
			gl.vertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);

			gl.enableVertexAttribArray(positionLoc);
			gl.enableVertexAttribArray(attribLoc);
			gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, DE_NULL);
			gl.disableVertexAttribArray(positionLoc);
			gl.disableVertexAttribArray(attribLoc);

			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		}
		else if (m_storage == STORAGE_CLIENT)
		{
			gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
			gl.vertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridAttributes[0]);

			gl.enableVertexAttribArray(positionLoc);
			gl.enableVertexAttribArray(attribLoc);
			gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]);
			gl.disableVertexAttribArray(positionLoc);
			gl.disableVertexAttribArray(attribLoc);
		}
		else
			DE_ASSERT(false);

		gl.useProgram(0);
		gl.finish();
		GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");

		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
	}

	// verify everywhere was drawn (all pixels have Green = 255)
	if (!checkResultImage(resultImage))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
		return STOP;
	}

	// test drawing still works
	if (!drawTestPattern(false))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
		return STOP;
	}

	// all ok
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

std::string VertexAttributeCase::genVertexSource (void) const
{
	if (m_type == TYPE_VERTEX)
		return
			"#version 300 es\n"
			"in highp vec4 a_pos;\n"
			"in highp vec4 a_attr;\n"
			"out mediump vec4 v_out;\n"
			"void main ()\n"
			"{\n"
			"	highp vec2 a1 = a_attr.xz + a_attr.yw; // add\n"
			"	highp vec2 a2 = a_attr.xz - a_attr.yw; // sub\n"
			"	highp vec2 a3 = a_attr.xz * a_attr.yw; // mul\n"
			"	highp vec2 a4 = a_attr.xz / a_attr.yw; // div\n"
			"	highp vec2 a5 = a_attr.xz + a_attr.yw * a_attr.xz; // fma\n"
			"\n"
			"	highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n"
			"	v_out = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n"
			"	gl_Position = a_pos;\n"
			"}\n";
	else
		return s_attrPassthroughVertexShaderSource;
}

std::string VertexAttributeCase::genFragmentSource (void) const
{
	if (m_type == TYPE_VERTEX)
		return s_colorPassthroughFragmentShaderSource;
	else
		return
			"#version 300 es\n"
			"layout(location = 0) out mediump vec4 fragColor;\n"
			"in highp vec4 v_attr;\n"
			"void main ()\n"
			"{\n"
			"	highp vec2 a1 = v_attr.xz + v_attr.yw; // add\n"
			"	highp vec2 a2 = v_attr.xz - v_attr.yw; // sub\n"
			"	highp vec2 a3 = v_attr.xz * v_attr.yw; // mul\n"
			"	highp vec2 a4 = v_attr.xz / v_attr.yw; // div\n"
			"	highp vec2 a5 = v_attr.xz + v_attr.yw * v_attr.xz; // fma\n"
			"	highp vec2 a6 = dFdx(v_attr.xz);\n"
			"\n"
			"	highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y + a6.y) - 6.0);\n"
			"	fragColor = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x+a6.x, 1.0);\n"
			"}\n";
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests special floats as uniforms
 *
 * Tests that special floats transferred to the shader as uniforms do
 * not change the results of normal floating point calculations. Special
 * floats are put to 4-vector's x and y components and value 1.0 is put to
 * z and w. The resulting fragment's green channel should be 1.0
 * everywhere.
 *
 * After the calculation test a test pattern is drawn to detect possible
 * floating point operation anomalies.
 *//*--------------------------------------------------------------------*/
class UniformCase : public RenderCase
{
public:
	enum ShaderType
	{
		TYPE_VERTEX = 0,
		TYPE_FRAGMENT,
	};

						UniformCase					(Context& context, const char* name, const char* desc, ShaderType type);
						~UniformCase				(void);

	void				init						(void);
	void				deinit						(void);
	IterateResult		iterate						(void);

private:
	std::string			genVertexSource				(void) const;
	std::string			genFragmentSource			(void) const;

	const ShaderType	m_type;
};

UniformCase::UniformCase (Context& context, const char* name, const char* desc, ShaderType type)
	: RenderCase	(context, name, desc)
	, m_type		(type)
{
}

UniformCase::~UniformCase (void)
{
	deinit();
}

void UniformCase::init (void)
{
	RenderCase::init();
}

void UniformCase::deinit (void)
{
	RenderCase::deinit();
}

UniformCase::IterateResult UniformCase::iterate (void)
{
	// Create a [s_specialFloats] X [s_specialFloats] grid of tile with each tile having 2 [s_specialFloats] values
	// and calculate some basic operations with the floating point values. If all goes well, nothing special should happen

	std::vector<tcu::Vec4>	gridVertices	((DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1));
	std::vector<deUint16>	indices			(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
	tcu::Surface			resultImage		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);

	// vertices
	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++x)
	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++y)
	{
		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]
		const float		posY	= (float)y / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f;

		gridVertices[x * (DE_LENGTH_OF_ARRAY(s_specialFloats)+1) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
	}

	// tiles
	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
	{
		const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats)) + y) * 6;

		indices[baseNdx + 0] = (deUint16)((x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0));
		indices[baseNdx + 1] = (deUint16)((x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1));
		indices[baseNdx + 2] = (deUint16)((x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0));

		indices[baseNdx + 3] = (deUint16)((x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0));
		indices[baseNdx + 4] = (deUint16)((x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1));
		indices[baseNdx + 5] = (deUint16)((x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1));
	}

	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;

	// Draw grid
	{
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
		const GLint				specialLoc	= gl.getUniformLocation(m_program->getProgram(), "u_special");

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		gl.useProgram(m_program->getProgram());

		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
		gl.enableVertexAttribArray(positionLoc);

		for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
		for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
		{
			const deUint32		one				= 0x3F800000;
			const tcu::UVec4	uniformValue	= tcu::UVec4(s_specialFloats[x], s_specialFloats[y], one, one);
			const int			indexIndex		= (x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y) * 6;

			gl.uniform4fv(specialLoc, 1, (const float*)uniformValue.getPtr());
			gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
		}


		gl.disableVertexAttribArray(positionLoc);

		gl.useProgram(0);
		gl.finish();
		GLU_EXPECT_NO_ERROR(gl.getError(), "UniformCase::iterate");

		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
	}

	// verify everywhere was drawn (all pixels have Green = 255)
	if (!checkResultImage(resultImage))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
		return STOP;
	}

	// test drawing still works
	if (!drawTestPattern(false))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
		return STOP;
	}

	// all ok
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

std::string UniformCase::genVertexSource (void) const
{
	if (m_type == TYPE_VERTEX)
		return
			"#version 300 es\n"
			"in highp vec4 a_pos;\n"
			"uniform highp vec4 u_special;\n"
			"out mediump vec4 v_out;\n"
			"void main ()\n"
			"{\n"
			"	highp vec2 a1 = u_special.xz + u_special.yw; // add\n"
			"	highp vec2 a2 = u_special.xz - u_special.yw; // sub\n"
			"	highp vec2 a3 = u_special.xz * u_special.yw; // mul\n"
			"	highp vec2 a4 = u_special.xz / u_special.yw; // div\n"
			"	highp vec2 a5 = u_special.xz + u_special.yw * u_special.xz; // fma\n"
			"\n"
			"	highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n"
			"	v_out = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n"
			"	gl_Position = a_pos;\n"
			"}\n";
	else
		return
			"#version 300 es\n"
			"in highp vec4 a_pos;\n"
			"void main ()\n"
			"{\n"
			"	gl_Position = a_pos;\n"
			"}\n";
}

std::string UniformCase::genFragmentSource (void) const
{
	if (m_type == TYPE_VERTEX)
		return s_colorPassthroughFragmentShaderSource;
	else
		return
			"#version 300 es\n"
			"layout(location = 0) out mediump vec4 fragColor;\n"
			"uniform highp vec4 u_special;\n"
			"void main ()\n"
			"{\n"
			"	highp vec2 a1 = u_special.xz + u_special.yw; // add\n"
			"	highp vec2 a2 = u_special.xz - u_special.yw; // sub\n"
			"	highp vec2 a3 = u_special.xz * u_special.yw; // mul\n"
			"	highp vec2 a4 = u_special.xz / u_special.yw; // div\n"
			"	highp vec2 a5 = u_special.xz + u_special.yw * u_special.xz; // fma\n"
			"	highp vec2 a6 = mod(u_special.xz, u_special.yw);\n"
			"	highp vec2 a7 = mix(u_special.xz, u_special.yw, a6);\n"
			"\n"
			"	highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y + a6.y + a7.y) - 7.0);\n"
			"	fragColor = vec4(a1.x*a3.x, green, a5.x*a4.x + a2.x*a7.x, 1.0);\n"
			"}\n";
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests special floats in floating point textures
 *
 * Tests that sampling special floats from a floating point texture
 * does not affect the values of other color components of the sample. Test
 * samples a RG texture with R channel filled with special floats and G
 * channel filled with test values.
 *
 * Tests that linear sampling using compare mode = COMPARE_REF_TO_TEXTURE
 * of a floating point depth texture containing special floating point
 * values does not produce values outside the [0, 1] range.
 *
 * After the calculation test a test pattern is drawn to detect possible
 * texture sampling anomalies.
 *//*--------------------------------------------------------------------*/
class TextureCase : public RenderCase
{
public:
	enum ShaderType
	{
		TYPE_VERTEX = 0,
		TYPE_FRAGMENT,

		TYPE_LAST
	};
	enum TextureType
	{
		TEXTURE_FLOAT = 0,
		TEXTURE_DEPTH,

		TEXTURE_LAST
	};
	enum UploadType
	{
		UPLOAD_CLIENT = 0,
		UPLOAD_PBO,

		UPLOAD_LAST
	};

						TextureCase					(Context& context, const char* name, const char* desc, ShaderType type, TextureType texType, UploadType uploadType);
						~TextureCase				(void);

	void				init						(void);
	void				deinit						(void);
	IterateResult		iterate						(void);

private:
	std::string			genVertexSource				(void) const;
	std::string			genFragmentSource			(void) const;

	const ShaderType	m_type;
	const TextureType	m_textureType;
	const UploadType	m_uploadType;
	GLuint				m_textureID;
	GLuint				m_pboID;
};

TextureCase::TextureCase (Context& context, const char* name, const char* desc, ShaderType type, TextureType texType, UploadType uploadType)
	: RenderCase	(context, name, desc)
	, m_type		(type)
	, m_textureType	(texType)
	, m_uploadType	(uploadType)
	, m_textureID	(0)
	, m_pboID		(0)
{
	DE_ASSERT(type < TYPE_LAST);
	DE_ASSERT(texType < TEXTURE_LAST);
	DE_ASSERT(uploadType < UPLOAD_LAST);
}

TextureCase::~TextureCase (void)
{
	deinit();
}

void TextureCase::init (void)
{
	// requirements
	{
		GLint maxTextureSize = 0;
		m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
		if (maxTextureSize < TEST_TEXTURE_SIZE)
			throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") + de::toString(TEST_TEXTURE_SIZE));
	}

	RenderCase::init();

	// gen texture
	{
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		de::Random				rnd			(12345);

		gl.genTextures(1, &m_textureID);
		gl.bindTexture(GL_TEXTURE_2D, m_textureID);

		if (m_uploadType == UPLOAD_PBO)
		{
			gl.genBuffers(1, &m_pboID);
			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pboID);
			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureCase::init");
		}

		if (m_textureType == TEXTURE_FLOAT)
		{
			std::vector<deUint32>	texData	(TEST_TEXTURE_SIZE*TEST_TEXTURE_SIZE*2);
			const deUint32*			dataPtr = (m_uploadType == UPLOAD_CLIENT) ? (&texData[0]) : (DE_NULL);

			m_testCtx.getLog() << tcu::TestLog::Message << "Creating a 2D 2-component float texture. Pixel contents are of form (special, 1)." << tcu::TestLog::EndMessage;

			// set green channel to 1.0
			for (int x = 0; x < TEST_TEXTURE_SIZE; ++x)
			for (int y = 0; y < TEST_TEXTURE_SIZE; ++y)
			{
				texData[(x * TEST_TEXTURE_SIZE + y) * 2 + 0] = rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
				texData[(x * TEST_TEXTURE_SIZE + y) * 2 + 1] = 0x3F800000;	// one
			}

			if (m_uploadType == UPLOAD_PBO)
				gl.bufferData(GL_PIXEL_UNPACK_BUFFER, (glw::GLsizeiptr)(texData.size() * sizeof(deUint32)), &texData[0], GL_STATIC_DRAW);

			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RG32F, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, 0, GL_RG, GL_FLOAT, dataPtr);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureCase::init");
		}
		else if (m_textureType == TEXTURE_DEPTH)
		{
			std::vector<deUint32>	texData	(TEST_TEXTURE_SIZE*TEST_TEXTURE_SIZE);
			const deUint32*			dataPtr = (m_uploadType == UPLOAD_CLIENT) ? (&texData[0]) : (DE_NULL);

			m_testCtx.getLog() << tcu::TestLog::Message
				<< "Creating a 2D depth texture and filling it with special floating point values.\n"
				<< "  TEXTURE_COMPARE_MODE = COMPARE_REF_TO_TEXTURE"
				<< tcu::TestLog::EndMessage;

			for (int x = 0; x < TEST_TEXTURE_SIZE; ++x)
			for (int y = 0; y < TEST_TEXTURE_SIZE; ++y)
				texData[x * TEST_TEXTURE_SIZE + y] = rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));

			if (m_uploadType == UPLOAD_PBO)
				gl.bufferData(GL_PIXEL_UNPACK_BUFFER, (glw::GLsizeiptr)(texData.size() * sizeof(deUint32)), &texData[0], GL_STATIC_DRAW);

			gl.texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, 0, GL_DEPTH_COMPONENT, GL_FLOAT, dataPtr);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureCase::init");
		}
		else
			DE_ASSERT(false);

		if (m_uploadType == UPLOAD_PBO)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "PBO used for image upload." << tcu::TestLog::EndMessage;

			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			gl.deleteBuffers(1, &m_pboID);
			m_pboID = 0;
		}
	}
}

void TextureCase::deinit (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	RenderCase::deinit();

	if (m_textureID)
	{
		gl.deleteTextures(1, &m_textureID);
		m_textureID = 0;
	}
	if (m_pboID)
	{
		gl.deleteBuffers(1, &m_pboID);
		m_pboID = 0;
	}
}

TextureCase::IterateResult TextureCase::iterate (void)
{
	// Draw a grid and texture it with a floating point texture containing special values. If all goes well, nothing special should happen

	const int				gridSize		= 16;
	std::vector<tcu::Vec4>	gridVertices	(gridSize * gridSize);
	std::vector<tcu::Vec2>	gridTexCoords	(gridSize * gridSize);
	std::vector<deUint16>	indices			((gridSize - 1) * (gridSize - 1) * 6);
	tcu::Surface			resultImage		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);

	// vertices
	for (int x = 0; x < gridSize; ++x)
	for (int y = 0; y < gridSize; ++y)
	{
		const float posX		= (float)x / ((float)gridSize - 1.0f) * 2.0f - 1.0f; // map from [0, gridSize - 1] to [-1, 1]
		const float posY		= (float)y / ((float)gridSize - 1.0f) * 2.0f - 1.0f;
		const float texCoordX	= deFloatPow(2.0f, (float)x - (float)gridSize / 2.0f);
		const float texCoordY	= deFloatPow(2.0f, (float)y - (float)gridSize / 2.0f);

		gridVertices[x * gridSize + y]	= tcu::Vec4(posX, posY, 0.0f, 1.0f);
		gridTexCoords[x * gridSize + y]	= tcu::Vec2(texCoordX, texCoordY);
	}

	// tiles
	for (int x = 0; x < gridSize - 1; ++x)
	for (int y = 0; y < gridSize - 1; ++y)
	{
		const int baseNdx = (x * (gridSize - 1) + y) * 6;

		indices[baseNdx + 0] = (deUint16)((x+0) * gridSize + (y+0));
		indices[baseNdx + 1] = (deUint16)((x+1) * gridSize + (y+1));
		indices[baseNdx + 2] = (deUint16)((x+1) * gridSize + (y+0));

		indices[baseNdx + 3] = (deUint16)((x+0) * gridSize + (y+0));
		indices[baseNdx + 4] = (deUint16)((x+1) * gridSize + (y+1));
		indices[baseNdx + 5] = (deUint16)((x+0) * gridSize + (y+1));
	}

	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a textured grid with the shader." << tcu::TestLog::EndMessage;

	// Draw grid
	{
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
		const GLint				texCoordLoc	= gl.getAttribLocation(m_program->getProgram(), "a_attr");
		const GLint				samplerLoc	= gl.getUniformLocation(m_program->getProgram(), "u_sampler");

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		gl.useProgram(m_program->getProgram());

		gl.uniform1i(samplerLoc, 0);
		gl.bindTexture(GL_TEXTURE_2D, m_textureID);

		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
		gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, &gridTexCoords[0]);

		gl.enableVertexAttribArray(positionLoc);
		gl.enableVertexAttribArray(texCoordLoc);
		gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]);
		gl.disableVertexAttribArray(positionLoc);
		gl.disableVertexAttribArray(texCoordLoc);

		gl.useProgram(0);
		gl.finish();
		GLU_EXPECT_NO_ERROR(gl.getError(), "TextureCase::iterate");

		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
	}

	// verify everywhere was drawn (all pixels have Green = 255)
	if (!checkResultImage(resultImage))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
		return STOP;
	}

	// test drawing and textures still works
	if (!drawTestPattern(true))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
		return STOP;
	}

	// all ok
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

std::string TextureCase::genVertexSource (void) const
{
	// vertex shader is passthrough, fragment does the calculations
	if (m_type == TYPE_FRAGMENT)
		return s_attrPassthroughVertexShaderSource;

	// vertex shader does the calculations
	std::ostringstream buf;
	buf <<	"#version 300 es\n"
			"in highp vec4 a_pos;\n"
			"in highp vec2 a_attr;\n"
			"out mediump vec4 v_out;\n";

	if (m_textureType == TEXTURE_FLOAT)
		buf <<	"uniform highp sampler2D u_sampler;\n";
	else if (m_textureType == TEXTURE_DEPTH)
		buf <<	"uniform highp sampler2DShadow u_sampler;\n";
	else
		DE_ASSERT(DE_FALSE);

	buf <<	"void main ()\n"
			"{\n";

	if (m_textureType == TEXTURE_FLOAT)
		buf <<	"	v_out = vec4(textureLod(u_sampler, a_attr, 0.0).rg, 1.0, 1.0);\n";
	else if (m_textureType == TEXTURE_DEPTH)
		buf <<	"	highp float a1 = textureLod(u_sampler, vec3(a_attr, 0.0), 0.0);\n"
				"	v_out = vec4(a1, (a1 > 1.0 || a1 < 0.0) ? (0.0) : (1.0), 1.0, 1.0);\n";
	else
		DE_ASSERT(DE_FALSE);

	buf <<	"	gl_Position = a_pos;\n"
			"}\n";
	return buf.str();
}

std::string TextureCase::genFragmentSource (void) const
{
	// fragment shader is passthrough
	if (m_type == TYPE_VERTEX)
		return s_colorPassthroughFragmentShaderSource;

	// fragment shader does the calculations
	std::ostringstream buf;
	buf <<	"#version 300 es\n"
			"layout(location = 0) out mediump vec4 fragColor;\n";

	if (m_textureType == TEXTURE_FLOAT)
		buf <<	"uniform highp sampler2D u_sampler;\n";
	else if (m_textureType == TEXTURE_DEPTH)
		buf <<	"uniform highp sampler2DShadow u_sampler;\n";
	else
		DE_ASSERT(DE_FALSE);

	buf <<	"in highp vec4 v_attr;\n"
			"void main ()\n"
			"{\n";

	if (m_textureType == TEXTURE_FLOAT)
		buf <<	"	highp vec2 a1 = texture(u_sampler, v_attr.xy).rg;\n"
				"	fragColor = vec4(a1.x, a1.y, 1.0, 1.0);\n";
	else if (m_textureType == TEXTURE_DEPTH)
		buf <<	"	highp float a1 = texture(u_sampler, vec3(v_attr.xy, 0.0));\n"
				"	fragColor = vec4(a1, (a1 > 1.0 || a1 < 0.0) ? (0.0) : (1.0), 1.0, 1.0);\n";
	else
		DE_ASSERT(DE_FALSE);

	buf << "}\n";
	return buf.str();
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests special floats as texture samping arguments
 *
 * Tests that special floats given as texture coordinates or LOD levels
 * to sampling functions do not return invalid values (values not in the
 * texture). Every texel's green component is 1.0.
 *
 * After the calculation test a test pattern is drawn to detect possible
 * texture sampling anomalies.
 *//*--------------------------------------------------------------------*/
class TextureSamplerCase : public RenderCase
{
public:
	enum ShaderType
	{
		TYPE_VERTEX = 0,
		TYPE_FRAGMENT,

		TYPE_LAST
	};
	enum TestType
	{
		TEST_TEX_COORD = 0,
		TEST_LOD,
		TEST_GRAD,
		TEST_TEX_COORD_CUBE,

		TEST_LAST
	};

						TextureSamplerCase			(Context& context, const char* name, const char* desc, ShaderType type, TestType testType);
						~TextureSamplerCase			(void);

	void				init						(void);
	void				deinit						(void);
	IterateResult		iterate						(void);

private:
	std::string			genVertexSource				(void) const;
	std::string			genFragmentSource			(void) const;

	const ShaderType	m_type;
	const TestType		m_testType;
	GLuint				m_textureID;
};

TextureSamplerCase::TextureSamplerCase (Context& context, const char* name, const char* desc, ShaderType type, TestType testType)
	: RenderCase	(context, name, desc)
	, m_type		(type)
	, m_testType	(testType)
	, m_textureID	(0)
{
	DE_ASSERT(type < TYPE_LAST);
	DE_ASSERT(testType < TEST_LAST);
}

TextureSamplerCase::~TextureSamplerCase (void)
{
	deinit();
}

void TextureSamplerCase::init (void)
{
	// requirements
	{
		GLint maxTextureSize = 0;
		m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
		if (maxTextureSize < TEST_TEXTURE_SIZE)
			throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") + de::toString(TEST_TEXTURE_SIZE));
	}

	RenderCase::init();

	// gen texture
	{
		const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
		std::vector<deUint8>	texData	(TEST_TEXTURE_SIZE*TEST_TEXTURE_SIZE*4);
		de::Random				rnd		(12345);

		gl.genTextures(1, &m_textureID);

		for (int x = 0; x < TEST_TEXTURE_SIZE; ++x)
		for (int y = 0; y < TEST_TEXTURE_SIZE; ++y)
		{
			// RGBA8, green and alpha channel are always 255 for verification
			texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 0] = rnd.getUint32() & 0xFF;
			texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 1] = 0xFF;
			texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 2] = rnd.getUint32() & 0xFF;
			texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 3] = 0xFF;
		}

		if (m_testType == TEST_TEX_COORD)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Creating a 2D texture with a test pattern." << tcu::TestLog::EndMessage;

			gl.bindTexture(GL_TEXTURE_2D, m_textureID);
			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
		}
		else if (m_testType == TEST_LOD || m_testType == TEST_GRAD)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Creating a mipmapped 2D texture with a test pattern." << tcu::TestLog::EndMessage;

			gl.bindTexture(GL_TEXTURE_2D, m_textureID);

			for (int level = 0; (TEST_TEXTURE_SIZE >> level); ++level)
				gl.texImage2D(GL_TEXTURE_2D, level, GL_RGBA8, TEST_TEXTURE_SIZE >> level, TEST_TEXTURE_SIZE >> level, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]);

			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
		}
		else if (m_testType == TEST_TEX_COORD_CUBE)
		{
			DE_STATIC_ASSERT(TEST_TEXTURE_CUBE_SIZE <= TEST_TEXTURE_SIZE);

			static const GLenum faces[] =
			{
				GL_TEXTURE_CUBE_MAP_POSITIVE_X,
				GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
				GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
				GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
				GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
				GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
			};

			m_testCtx.getLog() << tcu::TestLog::Message << "Creating a cube map with a test pattern." << tcu::TestLog::EndMessage;

			gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureID);

			for (int faceNdx = 0; faceNdx < DE_LENGTH_OF_ARRAY(faces); ++faceNdx)
				gl.texImage2D(faces[faceNdx], 0, GL_RGBA8, TEST_TEXTURE_CUBE_SIZE, TEST_TEXTURE_CUBE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]);

			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
		}
		else
			DE_ASSERT(DE_FALSE);
	}
}

void TextureSamplerCase::deinit (void)
{
	RenderCase::deinit();

	if (m_textureID)
	{
		const glw::Functions& gl = m_context.getRenderContext().getFunctions();

		gl.deleteTextures(1, &m_textureID);
		m_textureID = 0;
	}
}

TextureSamplerCase::IterateResult TextureSamplerCase::iterate (void)
{
	// 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.

	std::vector<tcu::Vec4>	gridVertices	(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
	std::vector<tcu::UVec2>	gridTexCoords	(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
	std::vector<deUint16>	indices			((DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * 6);
	tcu::Surface			resultImage		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);

	// vertices
	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
	{
		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]
		const float posY = (float)y / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f;

		gridVertices[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y]	= tcu::Vec4(posX, posY, 0.0f, 1.0f);
		gridTexCoords[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y]	= tcu::UVec2(s_specialFloats[x], s_specialFloats[y]);
	}

	// tiles
	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++x)
	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++y)
	{
		const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) + y) * 6;

		indices[baseNdx + 0] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0));
		indices[baseNdx + 1] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1));
		indices[baseNdx + 2] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0));

		indices[baseNdx + 3] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0));
		indices[baseNdx + 4] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1));
		indices[baseNdx + 5] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1));
	}

	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;

	// Draw grid
	{
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
		const GLint				texCoordLoc	= gl.getAttribLocation(m_program->getProgram(), "a_attr");
		const GLint				samplerLoc	= gl.getUniformLocation(m_program->getProgram(), "u_sampler");

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		gl.useProgram(m_program->getProgram());

		gl.uniform1i(samplerLoc, 0);
		if (m_testType != TEST_TEX_COORD_CUBE)
			gl.bindTexture(GL_TEXTURE_2D, m_textureID);
		else
			gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureID);

		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
		gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, &gridTexCoords[0]);

		gl.enableVertexAttribArray(positionLoc);
		gl.enableVertexAttribArray(texCoordLoc);
		gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]);
		gl.disableVertexAttribArray(positionLoc);
		gl.disableVertexAttribArray(texCoordLoc);

		gl.useProgram(0);
		gl.finish();
		GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::iterate");

		glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
	}

	// verify everywhere was drawn and samples were from the texture (all pixels have Green = 255)
	if (!checkResultImage(resultImage))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
		return STOP;
	}

	// test drawing and textures still works
	if (!drawTestPattern(true))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
		return STOP;
	}

	// all ok
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

std::string TextureSamplerCase::genVertexSource (void) const
{
	// vertex shader is passthrough, fragment does the calculations
	if (m_type == TYPE_FRAGMENT)
		return s_attrPassthroughVertexShaderSource;

	// vertex shader does the calculations
	std::ostringstream buf;
	buf <<	"#version 300 es\n"
			"in highp vec4 a_pos;\n"
			"in highp vec2 a_attr;\n";

	if (m_testType != TEST_TEX_COORD_CUBE)
		buf <<	"uniform highp sampler2D u_sampler;\n";
	else
		buf <<	"uniform highp samplerCube u_sampler;\n";

	buf <<	"out mediump vec4 v_out;\n"
			"void main ()\n"
			"{\n";

	if (m_testType == TEST_TEX_COORD)
		buf <<	"	v_out = textureLod(u_sampler, a_attr, 0.0);\n";
	else if (m_testType == TEST_LOD)
		buf <<	"	v_out = textureLod(u_sampler, a_attr, a_attr.x);\n";
	else if (m_testType == TEST_GRAD)
		buf <<	"	v_out = textureGrad(u_sampler, a_attr, a_attr, a_attr.yx);\n";
	else if (m_testType == TEST_TEX_COORD_CUBE)
		buf <<	"	v_out = textureLod(u_sampler, vec3(a_attr, a_attr.x + a_attr.y), 0.0);\n";
	else
		DE_ASSERT(DE_FALSE);

	buf <<	"\n"
			"	gl_Position = a_pos;\n"
			"}\n";

	return buf.str();
}

std::string TextureSamplerCase::genFragmentSource (void) const
{
	// fragment shader is passthrough
	if (m_type == TYPE_VERTEX)
		return s_colorPassthroughFragmentShaderSource;

	// fragment shader does the calculations
	std::ostringstream buf;
	buf <<	"#version 300 es\n"
			"layout(location = 0) out mediump vec4 fragColor;\n";

	if (m_testType != TEST_TEX_COORD_CUBE)
		buf <<	"uniform highp sampler2D u_sampler;\n";
	else
		buf <<	"uniform highp samplerCube u_sampler;\n";

	buf <<	"in highp vec4 v_attr;\n"
			"void main ()\n"
			"{\n";

	if (m_testType == TEST_TEX_COORD)
		buf << "	fragColor = texture(u_sampler, v_attr.xy);\n";
	else if (m_testType == TEST_LOD)
		buf << "	fragColor = texture(u_sampler, v_attr.xy, v_attr.x);\n";
	else if (m_testType == TEST_GRAD)
		buf <<	"	fragColor = textureGrad(u_sampler, v_attr.xy, v_attr.xy, v_attr.yx);\n";
	else if (m_testType == TEST_TEX_COORD_CUBE)
		buf <<	"	fragColor = texture(u_sampler, vec3(v_attr.xy,v_attr.x + v_attr.y));\n";
	else
		DE_ASSERT(DE_FALSE);

	buf <<	"}\n";

	return buf.str();
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests special floats as fragment shader outputs
 *
 * Tests that outputting special floats from a fragment shader does not change
 * the normal floating point values of outputted from a fragment shader. Special
 * floats are outputted in the green component, normal floating point values
 * in the red and blue component. Potential changes are tested by rendering
 * test pattern two times with different floating point values. The resulting
 * images' red and blue channels should be equal.
 *//*--------------------------------------------------------------------*/
class OutputCase : public FramebufferRenderCase
{
public:
						OutputCase				(Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type);
						~OutputCase				(void);

	void				testFBO					(void);

private:
	std::string			genVertexSource			(void) const;
	std::string			genFragmentSource		(void) const;
};

OutputCase::OutputCase (Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type)
	: FramebufferRenderCase	(context, name, desc, type)
{
}

OutputCase::~OutputCase (void)
{
	deinit();
}

void OutputCase::testFBO (void)
{
	// Create a 1 X [s_specialFloats] grid of tiles (stripes).
	std::vector<tcu::Vec4>	gridVertices	((DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) * 2);
	std::vector<deUint16>	indices			(DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
	tcu::TextureFormat		textureFormat	(tcu::TextureFormat::RGBA, (m_fboType == FBO_RGBA_FLOAT16 || m_fboType == FBO_RGBA_FLOAT32) ? (tcu::TextureFormat::FLOAT) : (tcu::TextureFormat::UNORM_INT8));
	tcu::TextureLevel		specialImage	(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
	tcu::TextureLevel		normalImage		(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);

	// vertices
	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++y)
	{
		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]

		gridVertices[y * 2 + 0] = tcu::Vec4(-1.0, posY, 0.0f, 1.0f);
		gridVertices[y * 2 + 1] = tcu::Vec4( 1.0, posY, 0.0f, 1.0f);
	}

	// tiles
	for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
	{
		const int baseNdx = y * 6;

		indices[baseNdx + 0] = (deUint16)((y + 0) * 2);
		indices[baseNdx + 1] = (deUint16)((y + 1) * 2);
		indices[baseNdx + 2] = (deUint16)((y + 1) * 2 + 1);

		indices[baseNdx + 3] = (deUint16)((y + 0) * 2);
		indices[baseNdx + 4] = (deUint16)((y + 1) * 2 + 1);
		indices[baseNdx + 5] = (deUint16)((y + 0) * 2 + 1);
	}

	// Draw grids
	{
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
		const GLint				specialLoc	= gl.getUniformLocation(m_program->getProgram(), "u_special");

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		gl.useProgram(m_program->getProgram());
		GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw");

		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
		gl.enableVertexAttribArray(positionLoc);

		// draw 2 passes. Special and normal.
		for (int passNdx = 0; passNdx < 2; ++passNdx)
		{
			const bool specialPass	= (passNdx == 0);

			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;

			// draw stripes
			gl.clear(GL_COLOR_BUFFER_BIT);
			for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
			{
				const deUint32	one				= 0x3F800000;
				const deUint32	special			= s_specialFloats[y];
				const deUint32	uniformValue	= (specialPass) ? (special) : (one);
				const int		indexIndex		= y * 6;

				gl.uniform1fv(specialLoc, 1, (const float*)&uniformValue);
				gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
			}

			gl.finish();
			glu::readPixels(m_context.getRenderContext(), 0, 0, ((specialPass) ? (specialImage) : (normalImage)).getAccess());
		}

		gl.disableVertexAttribArray(positionLoc);
		gl.useProgram(0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "OutputCase::iterate");
	}

	// Check results
	{
		tcu::Surface		errorMask		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		const tcu::RGBA		badPixelColor	= tcu::RGBA::red();
		const tcu::RGBA		okPixelColor	= tcu::RGBA::green();
		int					badPixels		= 0;

		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;

		for (int y = 0; y < specialImage.getHeight(); ++y)
		for (int x = 0; x < specialImage.getWidth(); ++x)
		{
			const float		greenThreshold	= 0.1f;
			const tcu::Vec4	cNormal			= normalImage.getAccess().getPixel(x, y);
			const tcu::Vec4	cSpecial		= specialImage.getAccess().getPixel(x, y);

			if (cNormal.x() != cSpecial.x() || cNormal.z() != cSpecial.z() || cNormal.y() < 1.0f - greenThreshold)
			{
				++badPixels;
				errorMask.setPixel(x, y, badPixelColor);
			}
			else
				errorMask.setPixel(x, y, okPixelColor);
		}

		m_testCtx.getLog() << tcu::TestLog::Message << "Found " << badPixels << " invalid pixel(s)." << tcu::TestLog::EndMessage;

		if (badPixels)
		{
			m_testCtx.getLog()
					<< tcu::TestLog::ImageSet("Results", "Result verification")
					<< tcu::TestLog::Image("Image with special green channel",	"Image with special green channel",		specialImage)
					<< tcu::TestLog::Image("Image with constant green channel",	"Image with constant green channel",	normalImage)
					<< tcu::TestLog::Image("Error Mask",						"Error Mask",							errorMask)
					<< tcu::TestLog::EndImageSet;

			// all ok?
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
		}
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
}

std::string OutputCase::genVertexSource (void) const
{
	return
		"#version 300 es\n"
		"in highp vec4 a_pos;\n"
		"out highp vec2 v_pos;\n"
		"void main ()\n"
		"{\n"
		"	gl_Position = a_pos;\n"
		"	v_pos = a_pos.xy;\n"
		"}\n";
}

std::string OutputCase::genFragmentSource (void) const
{
	return
		"#version 300 es\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"uniform highp float u_special;\n"
		"in highp vec2 v_pos;\n"
		"void main ()\n"
		"{\n"
		"	fragColor = vec4((v_pos.x + 1.0) * 0.5, u_special, (v_pos.y + 1.0) * 0.5, 1.0);\n"
		"}\n";
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests special floats in blending
 *
 * Tests special floats as alpha and color components with various blending
 * modes. Test draws a test pattern and then does various blend operations
 * with special float values. After the blending test another test pattern
 * is drawn to detect possible blending anomalies. Test patterns should be
 * identical.
 *//*--------------------------------------------------------------------*/
class BlendingCase : public FramebufferRenderCase
{
public:
						BlendingCase			(Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type);
						~BlendingCase			(void);

	void				testFBO					(void);

private:
	void				drawTestImage			(tcu::PixelBufferAccess dst, GLuint uColorLoc, int maxVertexIndex);

	std::string			genVertexSource			(void) const;
	std::string			genFragmentSource		(void) const;
};

BlendingCase::BlendingCase (Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type)
	: FramebufferRenderCase	(context, name, desc, type)
{
}

BlendingCase::~BlendingCase (void)
{
	deinit();
}

void BlendingCase::testFBO (void)
{
	static const GLenum equations[] =
	{
		GL_FUNC_ADD,
		GL_FUNC_SUBTRACT,
		GL_FUNC_REVERSE_SUBTRACT,
		GL_MIN,
		GL_MAX
	};
	static const GLenum functions[] =
	{
		GL_ZERO,
		GL_ONE,
		GL_SRC_COLOR,
		GL_ONE_MINUS_SRC_COLOR,
		GL_SRC_ALPHA,
		GL_ONE_MINUS_SRC_ALPHA,
	};

	// Create a [BlendFuncs] X [s_specialFloats] grid of tiles. ( BlendFuncs = equations x functions )

	const int						numBlendFuncs	= DE_LENGTH_OF_ARRAY(equations) * DE_LENGTH_OF_ARRAY(functions);
	std::vector<tcu::Vec4>			gridVertices	((numBlendFuncs + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1));
	std::vector<deUint16>			indices			(numBlendFuncs * DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
	tcu::TextureFormat				textureFormat	(tcu::TextureFormat::RGBA, (m_fboType == FBO_RGBA_FLOAT16 || m_fboType == FBO_RGBA_FLOAT32) ? (tcu::TextureFormat::FLOAT) : (tcu::TextureFormat::UNORM_INT8));
	tcu::TextureLevel				beforeImage		(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
	tcu::TextureLevel				afterImage		(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);

	// vertices
	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++x)
	for (int y = 0; y < numBlendFuncs + 1; ++y)
	{
		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]
		const float		posY	= (float)y / (float)numBlendFuncs * 2.0f - 1.0f;

		gridVertices[x * (numBlendFuncs + 1) + y]	= tcu::Vec4(posX, posY, 0.0f, 1.0f);
	}

	// tiles
	for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
	for (int y = 0; y < numBlendFuncs; ++y)
	{
		const int baseNdx = (x * numBlendFuncs + y) * 6;

		indices[baseNdx + 0] = (deUint16)((x+0) * (numBlendFuncs + 1) + (y+0));
		indices[baseNdx + 1] = (deUint16)((x+1) * (numBlendFuncs + 1) + (y+1));
		indices[baseNdx + 2] = (deUint16)((x+1) * (numBlendFuncs + 1) + (y+0));

		indices[baseNdx + 3] = (deUint16)((x+0) * (numBlendFuncs + 1) + (y+0));
		indices[baseNdx + 4] = (deUint16)((x+1) * (numBlendFuncs + 1) + (y+1));
		indices[baseNdx + 5] = (deUint16)((x+0) * (numBlendFuncs + 1) + (y+1));
	}

	// Draw tiles
	{
		const int				numPasses	= 5;
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const GLint				positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_pos");
		const GLint				specialLoc	= gl.getUniformLocation(m_program->getProgram(), "u_special");

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		gl.useProgram(m_program->getProgram());
		gl.enable(GL_BLEND);
		GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw");

		gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
		gl.enableVertexAttribArray(positionLoc);

		// draw "before" image
		m_testCtx.getLog() << tcu::TestLog::Message << "Drawing pre-draw pattern." << tcu::TestLog::EndMessage;
		drawTestImage(beforeImage.getAccess(), specialLoc, (int)gridVertices.size() - 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw pattern");

		// draw multiple passes with special floats
		gl.clear(GL_COLOR_BUFFER_BIT);
		for (int passNdx = 0; passNdx < numPasses; ++passNdx)
		{
			de::Random rnd(123 + 567 * passNdx);

			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "Pass " << passNdx << ": Drawing tiles with the shader.\n"
				<< "\tVarying u_special for each tile.\n"
				<< "\tVarying blend function and blend equation for each tile.\n"
				<< tcu::TestLog::EndMessage;

			// draw tiles
			for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
			for (int y = 0; y < numBlendFuncs; ++y)
			{
				const GLenum		blendEquation		= equations[y % DE_LENGTH_OF_ARRAY(equations)];
				const GLenum		blendFunction		= functions[y / DE_LENGTH_OF_ARRAY(equations)];
				const GLenum		blendFunctionDst	= rnd.choose<GLenum>(DE_ARRAY_BEGIN(functions), DE_ARRAY_END(functions));
				const int			indexIndex			= (x * numBlendFuncs + y) * 6;

				// "rnd.get"s are run in a deterministic order
				const deUint32		componentR			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
				const deUint32		componentG			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
				const deUint32		componentB			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
				const deUint32		componentA			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
				const tcu::UVec4	uniformValue		= tcu::UVec4(componentR, componentG, componentB, componentA);

				gl.uniform4fv(specialLoc, 1, (const float*)uniformValue.getPtr());
				gl.blendEquation(blendEquation);
				gl.blendFunc(blendFunction, blendFunctionDst);
				gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
			}
		}
		GLU_EXPECT_NO_ERROR(gl.getError(), "special passes");

		// draw "after" image
		m_testCtx.getLog() << tcu::TestLog::Message << "Drawing post-draw pattern." << tcu::TestLog::EndMessage;
		drawTestImage(afterImage.getAccess(), specialLoc, (int)gridVertices.size() - 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "post-draw pattern");

		gl.disableVertexAttribArray(positionLoc);
		gl.useProgram(0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "OutputCase::iterate");
	}

	// Check results
	{
		tcu::Surface		errorMask		(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
		const tcu::RGBA		badPixelColor	= tcu::RGBA::red();
		const tcu::RGBA		okPixelColor	= tcu::RGBA::green();
		int					badPixels		= 0;

		m_testCtx.getLog() << tcu::TestLog::Message << "Checking patterns are identical." << tcu::TestLog::EndMessage;

		for (int y = 0; y < beforeImage.getHeight(); ++y)
		for (int x = 0; x < beforeImage.getWidth(); ++x)
		{
			const tcu::Vec4	cBefore	= beforeImage.getAccess().getPixel(x, y);
			const tcu::Vec4	cAfter	= afterImage.getAccess().getPixel(x, y);

			if (cBefore != cAfter)
			{
				++badPixels;
				errorMask.setPixel(x, y, badPixelColor);
			}
			else
				errorMask.setPixel(x, y, okPixelColor);
		}

		m_testCtx.getLog() << tcu::TestLog::Message << "Found " << badPixels << " invalid pixel(s)." << tcu::TestLog::EndMessage;

		if (badPixels)
		{
			m_testCtx.getLog()
					<< tcu::TestLog::ImageSet("Results", "Result verification")
					<< tcu::TestLog::Image("Pattern drawn before special float blending",	"Pattern drawn before special float blending",		beforeImage)
					<< tcu::TestLog::Image("Pattern drawn after special float blending",	"Pattern drawn after special float blending",		afterImage)
					<< tcu::TestLog::EndImageSet;

			// all ok?
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
		}
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
}

void BlendingCase::drawTestImage (tcu::PixelBufferAccess dst, GLuint uColorLoc, int maxVertexIndex)
{
	const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
	de::Random				rnd	(123);

	gl.clear(GL_COLOR_BUFFER_BIT);
	gl.blendEquation(GL_FUNC_ADD);
	gl.blendFunc(GL_ONE, GL_ONE);

	for (int tri = 0; tri < 20; ++tri)
	{
		tcu::Vec4 color;
		color.x() = rnd.getFloat();
		color.y() = rnd.getFloat();
		color.z() = rnd.getFloat();
		color.w() = rnd.getFloat();
		gl.uniform4fv(uColorLoc, 1, color.getPtr());

		deUint16 indices[3];
		indices[0] = (deUint16)rnd.getInt(0, maxVertexIndex);
		indices[1] = (deUint16)rnd.getInt(0, maxVertexIndex);
		indices[2] = (deUint16)rnd.getInt(0, maxVertexIndex);

		gl.drawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, indices);
	}

	gl.finish();
	glu::readPixels(m_context.getRenderContext(), 0, 0, dst);
}

std::string BlendingCase::genVertexSource (void) const
{
	return
		"#version 300 es\n"
		"in highp vec4 a_pos;\n"
		"void main ()\n"
		"{\n"
		"	gl_Position = a_pos;\n"
		"}\n";
}

std::string BlendingCase::genFragmentSource (void) const
{
	return
		"#version 300 es\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"uniform highp vec4 u_special;\n"
		"void main ()\n"
		"{\n"
		"	fragColor = u_special;\n"
		"}\n";
}

} //anonymous

SpecialFloatTests::SpecialFloatTests (Context& context)
	: TestCaseGroup(context, "special_float", "Special float tests")
{
}

SpecialFloatTests::~SpecialFloatTests (void)
{
}

void SpecialFloatTests::init (void)
{
	tcu::TestCaseGroup* const vertexGroup		= new tcu::TestCaseGroup(m_testCtx, "vertex",		"Run vertex shader with special float values");
	tcu::TestCaseGroup* const fragmentGroup		= new tcu::TestCaseGroup(m_testCtx, "fragment",		"Run fragment shader with special float values");
	tcu::TestCaseGroup* const framebufferGroup	= new tcu::TestCaseGroup(m_testCtx, "framebuffer",	"Test framebuffers containing special float values");

	// .vertex
	{
		vertexGroup->addChild(new VertexAttributeCase	(m_context, "attribute_buffer",			"special attribute values in a buffer",					VertexAttributeCase::STORAGE_BUFFER, VertexAttributeCase::TYPE_VERTEX));
		vertexGroup->addChild(new VertexAttributeCase	(m_context, "attribute_client",			"special attribute values in a client storage",			VertexAttributeCase::STORAGE_CLIENT, VertexAttributeCase::TYPE_VERTEX));
		vertexGroup->addChild(new UniformCase			(m_context, "uniform",					"special uniform values",								UniformCase::TYPE_VERTEX));
		vertexGroup->addChild(new TextureCase			(m_context, "texture",					"texture with special floating point values",			TextureCase::TYPE_VERTEX, TextureCase::TEXTURE_FLOAT, TextureCase::UPLOAD_CLIENT));
		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));
		vertexGroup->addChild(new TextureCase			(m_context, "texture_shadow",			"shadow texture with special floating point values",	TextureCase::TYPE_VERTEX, TextureCase::TEXTURE_DEPTH, TextureCase::UPLOAD_CLIENT));
		vertexGroup->addChild(new TextureSamplerCase	(m_context, "sampler_tex_coord",		"special texture coords",								TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_TEX_COORD));
		vertexGroup->addChild(new TextureSamplerCase	(m_context, "sampler_tex_coord_cube",	"special texture coords to cubemap",					TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_TEX_COORD_CUBE));
		vertexGroup->addChild(new TextureSamplerCase	(m_context, "sampler_lod",				"special texture lod",									TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_LOD));
		vertexGroup->addChild(new TextureSamplerCase	(m_context, "sampler_grad",				"special texture grad",									TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_GRAD));

		addChild(vertexGroup);
	}

	// .fragment
	{
		fragmentGroup->addChild(new VertexAttributeCase	(m_context, "attribute_buffer",			"special attribute values in a buffer",					VertexAttributeCase::STORAGE_BUFFER, VertexAttributeCase::TYPE_FRAGMENT));
		fragmentGroup->addChild(new VertexAttributeCase	(m_context, "attribute_client",			"special attribute values in a client storage",			VertexAttributeCase::STORAGE_CLIENT, VertexAttributeCase::TYPE_FRAGMENT));
		fragmentGroup->addChild(new UniformCase			(m_context, "uniform",					"special uniform values",								UniformCase::TYPE_FRAGMENT));
		fragmentGroup->addChild(new TextureCase			(m_context, "texture",					"texture with special floating point values",			TextureCase::TYPE_FRAGMENT, TextureCase::TEXTURE_FLOAT, TextureCase::UPLOAD_CLIENT));
		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));
		fragmentGroup->addChild(new TextureCase			(m_context, "texture_shadow",			"shadow texture with special floating point values",	TextureCase::TYPE_FRAGMENT, TextureCase::TEXTURE_DEPTH, TextureCase::UPLOAD_CLIENT));
		fragmentGroup->addChild(new TextureSamplerCase	(m_context, "sampler_tex_coord",		"special texture coords",								TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_TEX_COORD));
		fragmentGroup->addChild(new TextureSamplerCase	(m_context, "sampler_tex_coord_cube",	"special texture coords to cubemap",					TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_TEX_COORD_CUBE));
		fragmentGroup->addChild(new TextureSamplerCase	(m_context, "sampler_lod",				"special texture lod",									TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_LOD));
		fragmentGroup->addChild(new TextureSamplerCase	(m_context, "sampler_grad",				"special texture grad",									TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_GRAD));

		addChild(fragmentGroup);
	}

	// .framebuffer
	{
		framebufferGroup->addChild(new OutputCase		(m_context, "write_default",			"write special floating point values to default framebuffer",	FramebufferRenderCase::FBO_DEFAULT));
		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgba4",				"write special floating point values to RGBA4 framebuffer",		FramebufferRenderCase::FBO_RGBA4));
		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgb5_a1",			"write special floating point values to RGB5_A1 framebuffer",	FramebufferRenderCase::FBO_RGB5_A1));
		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgb565",				"write special floating point values to RGB565 framebuffer",	FramebufferRenderCase::FBO_RGB565));
		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgba8",				"write special floating point values to RGBA8 framebuffer",		FramebufferRenderCase::FBO_RGBA8));
		framebufferGroup->addChild(new OutputCase		(m_context, "write_rgb10_a2",			"write special floating point values to RGB10_A2 framebuffer",	FramebufferRenderCase::FBO_RGB10_A2));
		framebufferGroup->addChild(new OutputCase		(m_context, "write_float16",			"write special floating point values to float16 framebuffer",	FramebufferRenderCase::FBO_RGBA_FLOAT16));
		framebufferGroup->addChild(new OutputCase		(m_context, "write_float32",			"write special floating point values to float32 framebuffer",	FramebufferRenderCase::FBO_RGBA_FLOAT32));

		framebufferGroup->addChild(new BlendingCase		(m_context, "blend_default",			"blend special floating point values in a default framebuffer",	FramebufferRenderCase::FBO_DEFAULT));
		framebufferGroup->addChild(new BlendingCase		(m_context, "blend_rgba8",				"blend special floating point values in a RGBA8 framebuffer",	FramebufferRenderCase::FBO_RGBA8));
		framebufferGroup->addChild(new BlendingCase		(m_context, "blend_float16",			"blend special floating point values in a float16 framebuffer",	FramebufferRenderCase::FBO_RGBA_FLOAT16));

		addChild(framebufferGroup);
	}
}

} // Stress
} // gles3
} // deqp
