/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 *
 * 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  glcPackedDepthStencilTests.cpp
 * \brief
 */ /*-------------------------------------------------------------------*/

#include "glcPackedDepthStencilTests.hpp"
#include "deMath.h"
#include "gluContextInfo.hpp"
#include "gluDrawUtil.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "gluStrUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include <algorithm>
#include <cstring>
#include <stdio.h>

using namespace glw;
using namespace glu;

namespace glcts
{

#define TEX_SIZE 256
#define TOLERANCE_LOW 0.48
#define TOLERANCE_HIGH 0.52
#define EPSILON 0.01

enum DrawMode
{
	DEFAULT,
	DEPTH_SPAN1,
	DEPTH_SPAN2,
};

struct D32F_S8
{
	GLfloat d;
	GLuint  s;
};

// Reference texture names for the described 5 textures and framebuffers
// and also for identifying other cases' reference textures
enum TextureNames
{
	packedTexImage,
	packedTexRender,
	packedTexRenderInitStencil,
	packedTexRenderDepthStep,
	packedTexRenderStencilStep,
	NUM_TEXTURES,
	verifyCopyTexImage,
	verifyPartialAttachments,
	verifyMixedAttachments,
	verifyClearBufferDepth,
	verifyClearBufferStencil,
	verifyClearBufferDepthStencil,
	verifyBlit,
};

struct TypeFormat
{
	GLenum		type;
	GLenum		format;
	const char* formatName;
	int			size;
	int			d;
	int			s;
};

#define NUM_TEXTURE_TYPES 2

static const TypeFormat TextureTypes[NUM_TEXTURE_TYPES] = {
	{ GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8, "depth24_stencil8", sizeof(GLuint), 24, 8 },
	{ GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8, "depth32f_stencil8", sizeof(GLuint) + sizeof(GLfloat),
	  32, 8 },
};

// Texture targets for initial state checking
static const GLenum coreTexTargets[] = {
	GL_TEXTURE_2D,
	GL_TEXTURE_3D,
	GL_TEXTURE_2D_ARRAY,
	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
	GL_TEXTURE_1D,
	GL_TEXTURE_1D_ARRAY,
	GL_TEXTURE_CUBE_MAP_ARRAY,
	GL_TEXTURE_RECTANGLE,
	GL_TEXTURE_2D_MULTISAMPLE,
	GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
	GL_PROXY_TEXTURE_1D,
	GL_PROXY_TEXTURE_2D,
	GL_PROXY_TEXTURE_3D,
	GL_PROXY_TEXTURE_1D_ARRAY,
	GL_PROXY_TEXTURE_2D_ARRAY,
	GL_PROXY_TEXTURE_CUBE_MAP_ARRAY,
	GL_PROXY_TEXTURE_RECTANGLE,
	GL_PROXY_TEXTURE_CUBE_MAP,
	GL_PROXY_TEXTURE_2D_MULTISAMPLE,
	GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY,
};
static const GLenum esTexTargets[] = {
	GL_TEXTURE_2D,
	GL_TEXTURE_3D,
	GL_TEXTURE_2D_ARRAY,
	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
};

// Listing of non-depth_stencil types for error tests
static const GLenum coreNonDepthStencilTypes[] = {
	GL_UNSIGNED_BYTE,
	GL_BYTE,
	GL_UNSIGNED_SHORT,
	GL_SHORT,
	GL_UNSIGNED_INT,
	GL_INT,
	GL_HALF_FLOAT,
	GL_FLOAT,
	GL_UNSIGNED_SHORT_5_6_5,
	GL_UNSIGNED_SHORT_4_4_4_4,
	GL_UNSIGNED_SHORT_5_5_5_1,
	GL_UNSIGNED_INT_2_10_10_10_REV,
	GL_UNSIGNED_INT_10F_11F_11F_REV,
	GL_UNSIGNED_INT_5_9_9_9_REV,
	GL_UNSIGNED_BYTE_3_3_2,
	GL_UNSIGNED_BYTE_2_3_3_REV,
	GL_UNSIGNED_SHORT_5_6_5_REV,
	GL_UNSIGNED_SHORT_4_4_4_4_REV,
	GL_UNSIGNED_SHORT_1_5_5_5_REV,
	GL_UNSIGNED_INT_8_8_8_8,
	GL_UNSIGNED_INT_8_8_8_8_REV,
	GL_UNSIGNED_INT_10_10_10_2,
};
static const GLenum esNonDepthStencilTypes[] = {
	GL_UNSIGNED_BYTE,
	GL_BYTE,
	GL_UNSIGNED_SHORT,
	GL_SHORT,
	GL_UNSIGNED_INT,
	GL_INT,
	GL_HALF_FLOAT,
	GL_FLOAT,
	GL_UNSIGNED_SHORT_5_6_5,
	GL_UNSIGNED_SHORT_4_4_4_4,
	GL_UNSIGNED_SHORT_5_5_5_1,
	GL_UNSIGNED_INT_2_10_10_10_REV,
	GL_UNSIGNED_INT_10F_11F_11F_REV,
	GL_UNSIGNED_INT_5_9_9_9_REV,
};

// Listing of non-depth_stencil formats for error tests
static const GLenum coreNonDepthStencilFormats[] = {
	GL_STENCIL_INDEX, GL_RED,		  GL_GREEN,		   GL_BLUE,			 GL_RG,			  GL_RGB,		 GL_RGBA,
	GL_BGR,			  GL_BGRA,		  GL_RED_INTEGER,  GL_GREEN_INTEGER, GL_BLUE_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER,
	GL_RGBA_INTEGER,  GL_BGR_INTEGER, GL_BGRA_INTEGER,
};
static const GLenum esNonDepthStencilFormats[] = {
	GL_RED,
	GL_RG,
	GL_RGB,
	GL_RGBA,
	GL_LUMINANCE,		// for es3+
	GL_ALPHA,			// for es3+
	GL_LUMINANCE_ALPHA, // for es3+
	GL_RED_INTEGER,
	GL_RG_INTEGER,
	GL_RGB_INTEGER,
	GL_RGBA_INTEGER,
};

// Listing of non-depth_stencil base formats for error tests
static const GLenum coreOtherBaseFormats[] = {
	GL_RED, GL_RG, GL_RGB, GL_RGBA,
};
static const GLenum esOtherBaseFormats[] = {
	GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_ALPHA, GL_LUMINANCE_ALPHA,
};

struct AttachmentParam
{
	GLenum pname;
	GLint  value;
};

#define NUM_ATTACHMENT_PARAMS_CORE 13
#define NUM_ATTACHMENT_PARAMS_ES 12

static const AttachmentParam coreAttachmentParams[NUM_TEXTURE_TYPES][NUM_ATTACHMENT_PARAMS_CORE] = {
	{
		{ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 24 },
		{ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 },
		{ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_UNSIGNED_NORMALIZED },
		{ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR },
		{ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_LAYERED, 0 },
	},
	{
		{ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 32 },
		{ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 },
		{ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FLOAT },
		{ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR },
		{ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_LAYERED, 0 },
	},
};
static const AttachmentParam esAttachmentParams[NUM_TEXTURE_TYPES][NUM_ATTACHMENT_PARAMS_ES] = {
	{
		{ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 24 },
		{ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 },
		{ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_UNSIGNED_NORMALIZED },
		{ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR },
		{ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 },
	},
	{
		{ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 32 },
		{ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 },
		{ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FLOAT },
		{ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR },
		{ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 },
		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 },
	},
};

enum ColorFunction
{
	COLOR_CHECK_DEFAULT,
	COLOR_CHECK_DEPTH,
	COLOR_CHECK_STENCIL,
};

class BaseTest : public deqp::TestCase
{
public:
	BaseTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~BaseTest();

	void								 init(void);
	virtual tcu::TestNode::IterateResult iterate(void);

	const AttachmentParam* getAttachmentParams() const;
	void createGradient(std::vector<GLbyte>& data);

	void setDrawReadBuffer(GLenum draw, GLenum read);
	void restoreDrawReadBuffer();

	void createTextures();
	void setupTexture();
	void destroyTextures();

	GLuint createProgram(const char* vsCode, const char* fsCode);
	void setupColorProgram(GLint& uColor);
	bool setupTextureProgram();
	bool setupStencilProgram();
	bool setTextureUniform(GLuint programId);

	void drawQuad(DrawMode drawMode, GLuint program);
	void renderToTextures();
	bool verifyDepthStencilGradient(GLvoid* data, unsigned int texIndex, int width, int height);
	bool verifyColorGradient(GLvoid* data, unsigned int texIndex, int function, int width, int height);
	bool doReadPixels(GLuint texture, int function);

protected:
	GLuint m_defaultFBO;
	GLuint m_drawBuffer;
	GLuint m_readBuffer;

	const GLenum* m_textureTargets;
	GLuint		  m_textureTargetsCount;
	const GLenum* m_nonDepthStencilTypes;
	GLuint		  m_nonDepthStencilTypesCount;
	const GLenum* m_nonDepthStencilFormats;
	GLuint		  m_nonDepthStencilFormatsCount;
	const GLenum* m_otherBaseFormats;
	GLuint		  m_otherBaseFormatsCount;

	const AttachmentParam* m_attachmentParams[NUM_TEXTURE_TYPES];
	GLuint				   m_attachmentParamsCount;

	const TypeFormat& m_typeFormat;

	GLuint m_textureProgram;
	GLuint m_colorProgram;
	GLuint m_stencilProgram;

	GLuint m_textures[NUM_TEXTURES];
	GLuint m_framebuffers[NUM_TEXTURES];
};

BaseTest::BaseTest(deqp::Context& context, const TypeFormat& tf)
	: deqp::TestCase(context, tf.formatName, "")
	, m_defaultFBO(0)
	, m_drawBuffer(GL_COLOR_ATTACHMENT0)
	, m_readBuffer(GL_COLOR_ATTACHMENT0)
	, m_textureTargets(coreTexTargets)
	, m_textureTargetsCount(DE_LENGTH_OF_ARRAY(coreTexTargets))
	, m_nonDepthStencilTypes(coreNonDepthStencilTypes)
	, m_nonDepthStencilTypesCount(DE_LENGTH_OF_ARRAY(coreNonDepthStencilTypes))
	, m_nonDepthStencilFormats(coreNonDepthStencilFormats)
	, m_nonDepthStencilFormatsCount(DE_LENGTH_OF_ARRAY(coreNonDepthStencilFormats))
	, m_otherBaseFormats(coreOtherBaseFormats)
	, m_otherBaseFormatsCount(DE_LENGTH_OF_ARRAY(coreOtherBaseFormats))
	, m_attachmentParamsCount(0)
	, m_typeFormat(tf)
	, m_textureProgram(0)
	, m_colorProgram(0)
	, m_stencilProgram(0)

{
}

BaseTest::~BaseTest()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	if (m_textureProgram)
		gl.deleteProgram(m_textureProgram);
	if (m_colorProgram)
		gl.deleteProgram(m_colorProgram);
	if (m_stencilProgram)
		gl.deleteProgram(m_stencilProgram);
}

void BaseTest::init(void)
{
	if (glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		m_textureTargets			  = esTexTargets;
		m_textureTargetsCount		  = DE_LENGTH_OF_ARRAY(esTexTargets);
		m_nonDepthStencilTypes		  = esNonDepthStencilTypes;
		m_nonDepthStencilTypesCount   = DE_LENGTH_OF_ARRAY(esNonDepthStencilTypes);
		m_nonDepthStencilFormats	  = esNonDepthStencilFormats;
		m_nonDepthStencilFormatsCount = DE_LENGTH_OF_ARRAY(esNonDepthStencilFormats);
		m_otherBaseFormats			  = esOtherBaseFormats;
		m_otherBaseFormatsCount		  = DE_LENGTH_OF_ARRAY(esOtherBaseFormats);

		for (int i				  = 0; i < NUM_TEXTURE_TYPES; i++)
			m_attachmentParams[i] = esAttachmentParams[i];
		m_attachmentParamsCount   = NUM_ATTACHMENT_PARAMS_ES;
	}
	else
	{
		for (int i				  = 0; i < NUM_TEXTURE_TYPES; i++)
			m_attachmentParams[i] = coreAttachmentParams[i];
		m_attachmentParamsCount   = NUM_ATTACHMENT_PARAMS_CORE;
	}
}

tcu::TestNode::IterateResult BaseTest::iterate(void)
{
	m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	return STOP;
}

const AttachmentParam* BaseTest::getAttachmentParams() const
{
	// find type index
	int index = 0;
	for (; index < NUM_TEXTURE_TYPES; index++)
	{
		if (TextureTypes[index].format == m_typeFormat.format)
			break;
	}

	if (index >= NUM_TEXTURE_TYPES)
		TCU_FAIL("Missing attachment definition");

	return m_attachmentParams[index];
}

// Creates a gradient texture data in the given type parameter format
void BaseTest::createGradient(std::vector<GLbyte>& data)
{
	switch (m_typeFormat.type)
	{
	case GL_UNSIGNED_INT_24_8:
	{
		data.resize(TEX_SIZE * TEX_SIZE * sizeof(GLuint));
		GLuint* dataPtr = reinterpret_cast<GLuint*>(&data[0]);
		for (int j = 0; j < TEX_SIZE; j++)
		{
			for (int i = 0; i < TEX_SIZE; i++)
			{
				GLuint  d = static_cast<GLuint>(static_cast<float>(i) / (TEX_SIZE - 1) * 0x00ffffff);
				GLubyte s = i & 0xff;

				dataPtr[TEX_SIZE * j + i] = (d << 8) + s;
			}
		}
		return;
	}
	case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
	{
		data.resize(TEX_SIZE * TEX_SIZE * sizeof(D32F_S8));
		D32F_S8* dataPtr = reinterpret_cast<D32F_S8*>(&data[0]);
		for (int j = 0; j < TEX_SIZE; j++)
		{
			for (int i = 0; i < TEX_SIZE; i++)
			{
				D32F_S8 v				  = { static_cast<float>(i) / (TEX_SIZE - 1), static_cast<GLuint>(i & 0xff) };
				dataPtr[TEX_SIZE * j + i] = v;
			}
		}
		return;
	}
	default:
		TCU_FAIL("Unsuported type");
	}
}

void BaseTest::setDrawReadBuffer(GLenum draw, GLenum read)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	GLint drawBuffer;
	gl.getIntegerv(GL_DRAW_BUFFER0, &drawBuffer);
	m_drawBuffer = static_cast<GLuint>(drawBuffer);

	GLint readBuffer;
	gl.getIntegerv(GL_READ_BUFFER, &readBuffer);
	m_readBuffer = static_cast<GLuint>(readBuffer);

	gl.drawBuffers(1, &draw);
	gl.readBuffer(read);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer");
}

void BaseTest::restoreDrawReadBuffer()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	gl.drawBuffers(1, &m_drawBuffer);
	gl.readBuffer(m_readBuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer");
}

void BaseTest::createTextures()
{
	// Creates all the textures and framebuffers
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genTextures(NUM_TEXTURES, m_textures);
	gl.genFramebuffers(NUM_TEXTURES, m_framebuffers);

	// packedTexImage
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);
	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]);
	setupTexture();
	std::vector<GLbyte> data;
	createGradient(data);
	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
				  &data[0]);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0);

	// packedTexRender
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]);
	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRender]);
	setupTexture();
	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
				  NULL);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRender], 0);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRender], 0);

	// packedTexRenderInitStencil
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderInitStencil]);
	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderInitStencil]);
	setupTexture();
	createGradient(data);
	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
				  &data[0]);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderInitStencil],
							0);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
							m_textures[packedTexRenderInitStencil], 0);

	// packedTexRenderDepthStep
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderDepthStep]);
	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep]);
	setupTexture();
	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
				  NULL);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep],
							0);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep],
							0);

	// packedTexRenderStencilStep
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderStencilStep]);
	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderStencilStep]);
	setupTexture();
	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
				  NULL);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderStencilStep],
							0);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
							m_textures[packedTexRenderStencilStep], 0);

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
}

void BaseTest::setupTexture()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
}

// Destroys all the textures and framebuffers
void BaseTest::destroyTextures()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	gl.deleteFramebuffers(NUM_TEXTURES, m_framebuffers);
	gl.deleteTextures(NUM_TEXTURES, m_textures);
}

GLuint BaseTest::createProgram(const char* vsCode, const char* fsCode)
{
	glu::RenderContext&   renderContext = m_context.getRenderContext();
	glu::ContextType	  contextType   = renderContext.getType();
	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
	glu::GLSLVersion	  glslVersion   = glu::getContextTypeGLSLVersion(contextType);
	const char*			  version		= glu::getGLSLVersionDeclaration(glslVersion);

	glu::Shader vs(gl, glu::SHADERTYPE_VERTEX);
	const char* vSources[] = { version, vsCode };
	const int   vLengths[] = { int(strlen(version)), int(strlen(vsCode)) };
	vs.setSources(2, vSources, vLengths);
	vs.compile();
	if (!vs.getCompileStatus())
		TCU_FAIL("Vertex shader compilation failed");

	glu::Shader fs(gl, glu::SHADERTYPE_FRAGMENT);
	const char* fSources[] = { version, fsCode };
	const int   fLengths[] = { int(strlen(version)), int(strlen(fsCode)) };
	fs.setSources(2, fSources, fLengths);
	fs.compile();
	if (!fs.getCompileStatus())
		TCU_FAIL("Fragment shader compilation failed");

	GLuint p = gl.createProgram();
	gl.attachShader(p, vs.getShader());
	gl.attachShader(p, fs.getShader());
	gl.linkProgram(p);
	return p;
}

void BaseTest::setupColorProgram(GLint& uColor)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	const char* vs = "\n"
					 "precision highp float;\n"
					 "in vec4 pos;\n"
					 "void main() {\n"
					 "  gl_Position = pos;\n"
					 "}\n";

	const char* fs = "\n"
					 "precision highp float;\n"
					 "out vec4 color;\n"
					 "uniform vec4 uColor;\n"
					 "void main() {\n"
					 "  color = uColor;\n"
					 "}\n";

	// setup shader program
	if (!m_colorProgram)
		m_colorProgram = createProgram(vs, fs);
	if (!m_colorProgram)
		TCU_FAIL("Error while loading shader program");

	gl.useProgram(m_colorProgram);

	// Setup program uniforms
	uColor = gl.getUniformLocation(m_colorProgram, "uColor");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation");

	if (uColor == -1)
		TCU_FAIL("Error getting uniform uColor");

	gl.uniform4f(uColor, 1.0f, 1.0f, 1.0f, 1.0f);
}

// Common code for default and stencil texture rendering shaders
bool BaseTest::setTextureUniform(GLuint programId)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(programId);

	GLint uniformTex = gl.getUniformLocation(programId, "tex");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation");

	if (uniformTex == -1)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Error getting uniform tex" << tcu::TestLog::EndMessage;
		return false;
	}

	gl.uniform1i(uniformTex, 0);
	return true;
}

// Loads texture rendering shader
bool BaseTest::setupTextureProgram()
{
	const char* vs = "\n"
					 "precision highp float;\n"
					 "in vec4 pos;\n"
					 "in vec2 UV;\n"
					 "out vec2 vUV;\n"
					 "void main() {\n"
					 "  gl_Position = pos;\n"
					 "  vUV = UV;\n"
					 "}\n";

	const char* fs = "\n"
					 "precision highp float;\n"
					 "in vec2 vUV;\n"
					 "out vec4 color;\n"
					 "uniform sampler2D tex;\n"
					 "void main() {\n"
					 "  color = texture(tex, vUV).rrra;\n"
					 "}\n";

	if (!m_textureProgram)
		m_textureProgram = createProgram(vs, fs);
	if (!m_textureProgram)
		return false;

	return setTextureUniform(m_textureProgram);
}

// Loads texture stencil rendering shader
bool BaseTest::setupStencilProgram()
{
	const char* vs = "\n"
					 "precision highp float;\n"
					 "in vec4 pos;\n"
					 "in vec2 UV;\n"
					 "out vec2 vUV;\n"
					 "void main() {\n"
					 "  gl_Position = pos;\n"
					 "  vUV = UV;\n"
					 "}\n";

	const char* fs = "\n"
					 "precision highp float;\n"
					 "in vec2 vUV;\n"
					 "out vec4 color;\n"
					 "uniform highp usampler2D tex;\n"
					 "void main() {\n"
					 "  float s = float(texture(tex, vUV).r);\n"
					 "  s /= 255.0;\n"
					 "  color = vec4(s, s, s, 1);\n"
					 "}\n";

	if (!m_stencilProgram)
		m_stencilProgram = createProgram(vs, fs);
	if (!m_stencilProgram)
		return false;

	return setTextureUniform(m_stencilProgram);
}

void BaseTest::drawQuad(DrawMode drawMode, GLuint program)
{
	static const GLfloat verticesDefault[] = {
		-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
	};

	static const GLfloat verticesDepthSpan1[] = {
		-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
	};

	static const GLfloat verticesDepthSpan2[] = {
		-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
	};

	static const GLfloat texCoords[] = {
		0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
	};

	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
	static PrimitiveList  quadPrimitive = glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices);

	static const glu::VertexArrayBinding depthSpanVA1[] = { glu::va::Float("pos", 4, 4, 0, verticesDepthSpan1) };
	static const glu::VertexArrayBinding depthSpanVA2[] = { glu::va::Float("pos", 4, 4, 0, verticesDepthSpan2) };
	static const glu::VertexArrayBinding defaultVA[]	= { glu::va::Float("pos", 4, 4, 0, verticesDefault),
														 glu::va::Float("UV", 2, 4, 0, texCoords) };

	const glu::RenderContext& renderContext = m_context.getRenderContext();
	if (drawMode == DEPTH_SPAN1)
		glu::draw(renderContext, program, 1, depthSpanVA1, quadPrimitive);
	else if (drawMode == DEPTH_SPAN2)
		glu::draw(renderContext, program, 1, depthSpanVA2, quadPrimitive);
	else
		glu::draw(renderContext, program, 2, defaultVA, quadPrimitive);
}

// Renders all non-trivial startup textures
void BaseTest::renderToTextures()
{
	const glu::RenderContext& renderContext = m_context.getRenderContext();
	const glw::Functions&	 gl			= renderContext.getFunctions();

	GLint uColor;
	setupColorProgram(uColor);

	gl.enable(GL_DEPTH_TEST);
	// depth writing must be enabled as it is disabled in places like doReadPixels
	gl.depthMask(GL_TRUE);

	if (glu::isContextTypeES(renderContext.getType()))
		gl.clearDepthf(1.0f);
	else
		gl.clearDepth(1.0);

	gl.depthFunc(GL_LEQUAL);
	gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);

	drawQuad(DEPTH_SPAN1, m_colorProgram);

	// packedTexRender
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]);

	setDrawReadBuffer(GL_NONE, GL_NONE);

	gl.enable(GL_STENCIL_TEST);
	gl.stencilFunc(GL_ALWAYS, 0x0, 0xFF);
	gl.stencilOp(GL_ZERO, GL_INCR, GL_INCR);

	gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	drawQuad(DEPTH_SPAN1, m_colorProgram);

	gl.disable(GL_STENCIL_TEST);

	restoreDrawReadBuffer();

	// packedTexRenderInitStencil
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderInitStencil]);

	setDrawReadBuffer(GL_NONE, GL_NONE);

	gl.clear(GL_DEPTH_BUFFER_BIT);
	drawQuad(DEPTH_SPAN1, m_colorProgram);

	restoreDrawReadBuffer();

	// packedTexRenderDepthStep
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderDepthStep]);

	setDrawReadBuffer(GL_NONE, GL_NONE);

	gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	drawQuad(DEPTH_SPAN2, m_colorProgram);
	drawQuad(DEPTH_SPAN1, m_colorProgram);

	restoreDrawReadBuffer();

	// packedTexRenderStencilStep
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderStencilStep]);

	setDrawReadBuffer(GL_NONE, GL_NONE);

	gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	gl.enable(GL_SCISSOR_TEST);
	gl.scissor(0, 0, TEX_SIZE, TEX_SIZE / 2);

	gl.enable(GL_STENCIL_TEST);
	gl.stencilFunc(GL_ALWAYS, 0x0, 0xFF);
	gl.stencilOp(GL_ZERO, GL_INCR, GL_INCR);
	for (int i = 0; i < 256; i++)
		drawQuad(DEPTH_SPAN2, m_colorProgram);
	gl.disable(GL_SCISSOR_TEST);

	gl.stencilFunc(GL_EQUAL, 0xFF, 0xFF);
	gl.clear(GL_DEPTH_BUFFER_BIT);
	drawQuad(DEPTH_SPAN1, m_colorProgram);
	gl.disable(GL_STENCIL_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");

	restoreDrawReadBuffer();

	// end
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
}

// Verifies DepthStencil buffer data against reference values
bool BaseTest::verifyDepthStencilGradient(GLvoid* data, unsigned int texIndex, int width, int height)
{
	bool result = true;

	int index, skip;
	int countD, countS;

	index  = 0;
	countD = 0;
	countS = 0;

	for (int j = 0; j < height; j++)
	{
		for (int i = 0; i < width; i++)
		{
			float d, dref = 0.0;
			int   s, sref = 0;

			skip = 0;

			switch (m_typeFormat.type)
			{
			case GL_UNSIGNED_INT_24_8:
			{
				GLuint v = ((GLuint*)data)[index];
				d		 = ((float)(v >> 8)) / 0xffffff;
				s		 = v & 0xff;
				break;
			}
			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
			{
				D32F_S8 v = ((D32F_S8*)data)[index];
				d		  = v.d;
				s		  = v.s & 0xff;
				break;
			}
			default:
				d = -1;
				s = -1;
				break;
			}

			switch (texIndex)
			{
			case packedTexImage:
				dref = ((float)i) / (width - 1);
				sref = (int)(dref * 255);
				break;
			case packedTexRender:
				dref = ((float)j) / (height - 1);
				sref = 1;
				break;
			case packedTexRenderInitStencil:
				dref = ((float)j) / (height - 1);
				sref = (int)(((float)i) / (width - 1) * 255);
				break;
			case packedTexRenderDepthStep:
				if (j < height * TOLERANCE_LOW)
				{
					dref = ((float)j) / (height - 1);
					sref = 0;
				}
				else if (j > height * TOLERANCE_HIGH)
				{
					dref = 1.0f - ((float)j) / (height - 1);
					sref = 0;
				}
				else
				{
					skip = 1; // give some tolerance to pixels in the middle
				}
				break;
			case packedTexRenderStencilStep:
				if (j < height * TOLERANCE_LOW)
				{
					dref = ((float)j) / (height - 1);
					sref = 255;
				}
				else if (j > height * TOLERANCE_HIGH)
				{
					dref = 1;
					sref = 0;
				}
				else
				{
					skip = 1; // give some tolerance to pixels in the middle
				}
				break;
			case verifyCopyTexImage:
				if (j < height * TOLERANCE_LOW)
				{
					dref = ((float)j) / (height - 1);
					sref = 1;
				}
				else if (j > height * TOLERANCE_HIGH)
				{
					dref = 0.5;
					sref = 1;
				}
				else
				{
					skip = 1; // give some tolerance to pixels in the middle
				}
				break;
			default:
				dref = -2;
				sref = -2;
				break;
			}

			if (!skip)
			{
				if (deFloatAbs(d - dref) > EPSILON)
				{
					result = false;
					countD++;
				}

				if (s != sref)
				{
					result = false;
					countS++;
				}
			}
			else
			{
				skip = 0;
			}

			index++;
		}
	}

	if (countD || countS)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "DEPTH_STENCIL comparison failed" << tcu::TestLog::EndMessage;
	}
	return result;
}

// Verifies Color buffer data against reference values
bool BaseTest::verifyColorGradient(GLvoid* data, unsigned int texIndex, int function, int width, int height)
{
	bool result = true;

	int index   = 0, skip;
	int channel = 0;
	int count   = 0;

	for (int j = 0; j < height; j++)
	{
		for (int i = 0; i < width; i++)
		{
			skip			= 0;
			GLuint color	= ((GLuint*)data)[index];
			GLuint colorref = 0;

// When data back from glReadPixels with arguments GL_RGBA + GL_UNSIGNED_BYTE,
// we should reverse byte order in big-endian platform for (GLuint*) pointer.
#if (DE_ENDIANNESS == DE_BIG_ENDIAN)
            color = deReverseBytes32(color);
#endif

			switch (texIndex)
			{
			case packedTexImage:
				channel  = (int)(((float)i) / (width - 1) * 255);
				colorref = 0xff000000 + channel * 0x00010101;
				break;
			case packedTexRender:
				if (function == COLOR_CHECK_DEPTH)
					channel = (int)(((float)j) / (height - 1) * 255);
				else
					channel = 1;
				colorref	= 0xff000000 + channel * 0x00010101;
				break;
			case packedTexRenderInitStencil:
				if (function == COLOR_CHECK_DEPTH)
					channel = (int)(((float)j) / (height - 1) * 255);
				else
					channel = (int)(((float)i) / (width - 1) * 255);
				colorref	= 0xff000000 + channel * 0x00010101;
				break;
			case packedTexRenderDepthStep:
				if (function == COLOR_CHECK_DEPTH)
				{
					if (j < height * TOLERANCE_LOW)
						channel = (int)(((float)j) / (height - 1) * 255);
					else if (j > height * TOLERANCE_HIGH)
						channel = 255 - (int)(((float)j) / (height - 1) * 255);
					else
						skip = 1; // give some tolerance to pixels in the middle
				}
				else
					channel = 0;
				colorref	= 0xff000000 + channel * 0x00010101;
				break;
			case packedTexRenderStencilStep:
				if (j < height * TOLERANCE_LOW)
				{
					if (function == COLOR_CHECK_DEPTH)
						channel = (int)(((float)j) / (height - 1) * 255);
					else
						channel = 255;
				}
				else if (j > height * TOLERANCE_HIGH)
					channel = (function == COLOR_CHECK_DEPTH) ? 255 : 0;
				else
					skip = 1; // give some tolerance to pixels in the middle
				colorref = 0xff000000 + channel * 0x00010101;
				break;
			case verifyCopyTexImage:
				if (j < height * TOLERANCE_LOW)
				{
					if (function == COLOR_CHECK_DEPTH)
						channel = (int)(((float)j) / (height - 1) * 255);
					else
						channel = 1;
				}
				else if (j > height * TOLERANCE_HIGH)
				{
					channel = (function == COLOR_CHECK_DEPTH) ? 127 : 1;
				}
				else
				{
					skip = 1; // give some tolerance to pixels in the middle
				}
				colorref = 0xff000000 + channel * 0x00010101;
				break;
			case verifyPartialAttachments:
				colorref = 0xffffffff;
				break;
			case verifyMixedAttachments:
				if (j > height * TOLERANCE_HIGH)
					colorref = 0xffffffff;
				else if (j < height * TOLERANCE_LOW)
					colorref = 0xcccccccc;
				else
					skip = 1;
				break;
			case verifyClearBufferDepth:
				if ((i & 0xff) == 0xff)
					colorref = 0xffffffff;
				else
					colorref = 0xcccccccc;
				break;
			case verifyClearBufferStencil:
				if (i > width * TOLERANCE_HIGH)
					colorref = 0xffffffff;
				else if (i < width * TOLERANCE_LOW)
					colorref = 0xcccccccc;
				else
					skip = 1;
				break;
			case verifyClearBufferDepthStencil:
				colorref = 0xffffffff;
				break;
			case verifyBlit:
				if (j > height * TOLERANCE_HIGH)
					colorref = 0xffffffff;
				else if (j < height * TOLERANCE_LOW)
					colorref = 0xcccccccc;
				else
					skip = 1;
				break;
			default:
				colorref = 0xdeadbeef;
				break;
			}

			if (skip)
				skip = 0;
			else if (color != colorref)
			{
				float d	= (float)(color & 0xff) / 0xff;
				float dref = (float)(colorref & 0xff) / 0xff;
				if (!((function == COLOR_CHECK_DEPTH) && (deFloatAbs(d - dref) < EPSILON)))
				{
					result = false;
					count++;
				}
			}

			index++;
		}
	}

	if (count)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "*** Color comparison failed" << tcu::TestLog::EndMessage;
		result = false;
	}
	return result;
}

// Verify DepthStencil texture by replicating it to color channels
// so it can be read using ReadPixels in Halti.
bool BaseTest::doReadPixels(GLuint texture, int function)
{
	bool				  result = true;
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();

	GLuint fbo;
	gl.genFramebuffers(1, &fbo);
	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);

	GLuint texColor;
	gl.genTextures(1, &texColor);
	gl.bindTexture(GL_TEXTURE_2D, texColor);
	setupTexture();
	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);
	setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);

	// Step 1: Verify depth values
	GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
	if (status != GL_FRAMEBUFFER_COMPLETE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
						   << tcu::TestLog::EndMessage;
		result = false;
	}
	else
	{
		setupTextureProgram();

		gl.bindTexture(GL_TEXTURE_2D, texture);

		gl.disable(GL_DEPTH_TEST);
		gl.depthMask(GL_FALSE);
		gl.disable(GL_STENCIL_TEST);
		gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
		gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
		gl.clear(GL_COLOR_BUFFER_BIT);
		drawQuad(DEFAULT, m_textureProgram);

		std::vector<GLuint> dataColor(TEX_SIZE * TEX_SIZE, 0);
		gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]);
		result &= verifyColorGradient(&dataColor[0], function, COLOR_CHECK_DEPTH, TEX_SIZE, TEX_SIZE);

		// Step 2: Verify stencil values
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);

		status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
		if (status != GL_FRAMEBUFFER_COMPLETE)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
							   << tcu::TestLog::EndMessage;
			result = false;
		}
		else
		{
			GLint uColor;
			setupColorProgram(uColor);

			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
			gl.clear(GL_COLOR_BUFFER_BIT);

			gl.enable(GL_STENCIL_TEST);
			for (int i = 0; i < 256; i++)
			{
				float v = i / 255.0f;
				gl.uniform4f(uColor, v, v, v, 1.0f);
				gl.stencilFunc(GL_EQUAL, i, 0xFF);
				gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
				drawQuad(DEFAULT, m_colorProgram);
			}

			gl.disable(GL_STENCIL_TEST);
			dataColor.assign(dataColor.size(), 0);
			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]);
			result &= verifyColorGradient(&dataColor[0], function, COLOR_CHECK_STENCIL, TEX_SIZE, TEX_SIZE);
		}
	}

	// clean up
	restoreDrawReadBuffer();
	gl.deleteFramebuffers(1, &fbo);
	gl.deleteTextures(1, &texColor);

	return result;
}

class InitialStateTest : public deqp::TestCase
{
public:
	InitialStateTest(deqp::Context& context);
	virtual ~InitialStateTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

InitialStateTest::InitialStateTest(deqp::Context& context)
	: deqp::TestCase(context, "initial_state", "TEXTURE_STENCIL_SIZE for the default texture objects should be 0")
{
}

InitialStateTest::~InitialStateTest()
{
}

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

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	for (int i = 0; i < DE_LENGTH_OF_ARRAY(coreTexTargets); i++)
	{
		GLenum target = coreTexTargets[i];

		GLfloat fp;
		gl.getTexLevelParameterfv(target, 0, GL_TEXTURE_STENCIL_SIZE, &fp);
		if (deFloatCmpNE(fp, 0.0f))
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "gl.getTexLevelParameterfv: Parameter is not 0"
							   << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}

		GLint ip;
		gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_STENCIL_SIZE, &ip);
		if (deFloatCmpNE((float)ip, 0.0f))
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "gl.getTexLevelParameteriv: Parameter is not 0"
							   << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

class ValidateErrorsTest : public BaseTest
{
public:
	ValidateErrorsTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~ValidateErrorsTest();

	virtual tcu::TestNode::IterateResult iterate(void);

protected:
	bool checkErrors();
};

ValidateErrorsTest::ValidateErrorsTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

ValidateErrorsTest::~ValidateErrorsTest()
{
}

tcu::TestNode::IterateResult ValidateErrorsTest::iterate(void)
{
	createTextures();
	if (checkErrors())
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	destroyTextures();
	return STOP;
}

//  Error tests [desktop only]:

//  - The error INVALID_ENUM is generated if ReadPixels is
//	called where format is DEPTH_STENCIL and type is not
//	UNSIGNED_INT_24_8, or FLOAT_32_UNSIGNED_INT_24_8_REV.

//  - The error INVALID_OPERATION is generated if ReadPixels
//	is called where type is UNSIGNED_INT_24_8 or
//	FLOAT_32_UNSIGNED_INT_24_8_REV and format is not DEPTH_STENCIL.

//  - The error INVALID_OPERATION is generated if ReadPixels
//	is called where format is DEPTH_STENCIL and there is not both a
//	depth buffer and a stencil buffer.

//  - Calling GetTexImage with a <format> of DEPTH_COMPONENT when the
//	base internal format of the texture image is not DEPTH_COMPONENT
//	or DEPTH_STENCIL causes the error INVALID_OPERATION.

//  - Calling GetTexImage with a <format> of DEPTH_STENCIL when
//	the base internal format of the texture image is not
//	DEPTH_STENCIL causes the error INVALID_OPERATION.

//  Error tests [Halti only]:

//  - The error INVALID_ENUM is generated if ReadPixels is
//	called where format is DEPTH_STENCIL.

//  Error tests [desktop and Halti]:

//  - TexImage generates INVALID_OPERATION if one of the base internal format
//	and format is DEPTH_COMPONENT or DEPTH_STENCIL, and the other is neither
//	of these values.

//  - The error INVALID_OPERATION is generated if CopyTexImage
//	is called where format is DEPTH_STENCIL and there is not both a
//	depth buffer and a stencil buffer.
bool ValidateErrorsTest::checkErrors()
{
	bool					  result = true;
	GLuint					  fbo, fbo2;
	GLuint					  texColor;
	std::vector<GLfloat>	  data(4 * TEX_SIZE * TEX_SIZE, 0.0f);
	const glu::RenderContext& renderContext = m_context.getRenderContext();
	const glw::Functions&	 gl			= renderContext.getFunctions();
	bool					  isContextES   = glu::isContextTypeES(renderContext.getType());

	if (isContextES)
	{
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);
		setDrawReadBuffer(GL_NONE, GL_NONE);
		gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);

		GLenum error = gl.getError();
		if (((GL_INVALID_OPERATION != error) && (GL_INVALID_ENUM != error)) &&
			!((GL_NO_ERROR == error) && m_context.getContextInfo().isExtensionSupported("GL_NV_read_depth_stencil")))
		{
			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
			if (gl.getError() != GL_INVALID_OPERATION)
				result = false;
		}

		restoreDrawReadBuffer();
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
	}
	else
	{
		gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]);
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);
		setDrawReadBuffer(GL_NONE, GL_NONE);

		for (unsigned int i = 0; i < m_nonDepthStencilTypesCount; i++)
		{
			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_nonDepthStencilTypes[i], &data[0]);
			if (gl.getError() != GL_INVALID_ENUM)
				result = false;
		}

		for (unsigned int i = 0; i < m_nonDepthStencilFormatsCount; i++)
		{
			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, m_nonDepthStencilFormats[i], m_typeFormat.type, &data[0]);

			if (gl.getError() != GL_INVALID_OPERATION)
				result = false;
		}

		for (int i = 0; i < 2; i++)
		{
			// setup texture/fbo
			gl.genTextures(1, &texColor);
			gl.genFramebuffers(1, &fbo);
			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);

			GLenum attachmentType = (i == 0) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT;
			gl.framebufferTexture2D(GL_FRAMEBUFFER, attachmentType, GL_TEXTURE_2D, m_textures[packedTexImage], 0);

			gl.bindTexture(GL_TEXTURE_2D, texColor);
			setupTexture();
			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
			gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);

			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
			if (gl.getError() != GL_INVALID_OPERATION)
				result = false;

			gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
			gl.bindTexture(GL_TEXTURE_2D, 0);
			gl.deleteFramebuffers(1, &fbo);
			gl.deleteTextures(1, &texColor);
		}

		for (unsigned int i = 0; i < m_otherBaseFormatsCount; i++)
		{
			GLenum format = m_otherBaseFormats[i];
			gl.genTextures(1, &texColor);
			gl.bindTexture(GL_TEXTURE_2D, texColor);
			setupTexture();
			gl.texImage2D(GL_TEXTURE_2D, 0, format, TEX_SIZE, TEX_SIZE, 0, format, GL_UNSIGNED_BYTE, 0);

			if (format != GL_DEPTH_COMPONENT)
			{
				gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, &data[0]);

				if (gl.getError() != GL_INVALID_OPERATION)
					result = false;
			}

			gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, &data[0]);
			if (gl.getError() != GL_INVALID_OPERATION)
				result = false;

			gl.deleteTextures(1, &texColor);
		}
	}

	bool coreGL = !glu::isContextTypeES(m_context.getRenderContext().getType());
	for (int i = 0; i < 4; i++)
	{
		int limit;
		if (i < 2)
			limit = m_nonDepthStencilFormatsCount;
		else
			limit = m_otherBaseFormatsCount;

		for (int j = 0; j < limit; j++)
		{
			GLint internalFormat = 0;
			GLint format		 = 0;

			gl.genTextures(1, &texColor);
			gl.bindTexture(GL_TEXTURE_2D, texColor);
			setupTexture();

			switch (i)
			{
			case 0:
				internalFormat = GL_DEPTH_COMPONENT;
				format		   = m_nonDepthStencilFormats[j];
				break;
			case 1:
				internalFormat = GL_DEPTH_STENCIL;
				format		   = m_nonDepthStencilFormats[j];
				break;
			case 2:
				internalFormat = m_otherBaseFormats[j];
				format		   = GL_DEPTH_COMPONENT;
				break;
			case 3:
				internalFormat = m_otherBaseFormats[j];
				format		   = GL_DEPTH_STENCIL;
				break;
			}

			gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, TEX_SIZE, TEX_SIZE, 0, format,
						  (format == GL_DEPTH_STENCIL) ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_BYTE, 0);

			GLenum expectedError = GL_INVALID_OPERATION;
			if (coreGL && (format == GL_STENCIL_INDEX))
			{
				// The OpenGL 4.3 spec is imprecise about what error this should generate
				// see Bugzilla 10134: TexImage with a <format> of STENCIL_INDEX
				//	 4.3 core (Feb 14 2013) p. 174:
				//	 (describing TexImage3D)
				//		 The format STENCIL_INDEX is not allowed.
				// The new OpenGL 4.4 feature ARB_texture_stencil8 removes this error. So
				// the best we can do for OpenGL is to just allow any error, or no error,
				// for this specific case.
				gl.getError();
			}
			else if (gl.getError() != expectedError)
				result = false;

			gl.bindTexture(GL_TEXTURE_2D, 0);
			gl.deleteTextures(1, &texColor);
		}
	}

	gl.genFramebuffers(1, &fbo);
	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0);

	gl.genFramebuffers(1, &fbo2);
	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo2);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0);

	GLuint tex;
	gl.genTextures(1, &tex);
	gl.bindTexture(GL_TEXTURE_2D, tex);
	setupTexture();
	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, 0);

	for (int i = 0; i < 2; i++)
	{
		switch (i)
		{
		case 0:
			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
			gl.bindTexture(GL_TEXTURE_2D, tex);
			break;
		case 1:
			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo2);
			gl.bindTexture(GL_TEXTURE_2D, tex);
			break;
		}

		setDrawReadBuffer(GL_NONE, GL_NONE);

		gl.copyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 0, 0, TEX_SIZE, TEX_SIZE, 0);

		GLenum error = gl.getError();
		if ((GL_INVALID_OPERATION != error) && (GL_INVALID_ENUM != error))
		{
			gl.copyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 0, 0, TEX_SIZE, TEX_SIZE, 0);
			if (gl.getError() != GL_INVALID_OPERATION)
				result = false;
		}

		restoreDrawReadBuffer();
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
	}

	gl.bindTexture(GL_TEXTURE_2D, 0);
	gl.deleteTextures(1, &tex);

	gl.deleteFramebuffers(1, &fbo);
	gl.deleteFramebuffers(1, &fbo2);

	return result;
}

class VerifyReadPixelsTest : public BaseTest
{
public:
	VerifyReadPixelsTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~VerifyReadPixelsTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

VerifyReadPixelsTest::VerifyReadPixelsTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

VerifyReadPixelsTest::~VerifyReadPixelsTest()
{
}

tcu::TestNode::IterateResult VerifyReadPixelsTest::iterate(void)
{
	//  Use readpixels to verify the results for the 5 textures above are correct.
	//	Note that in ES you can only use gl.readpixels on color buffers.
	//  Test method:
	//  - on desktop: ReadPixel DEPTH_STENCIL value to buffer. Verify gradient.
	//  - on desktop/Halti: Create FBO with color/depth/stencil attachment.
	//	Draw a quad with depth texture bound. Verify gradient.
	//	Draw 256 times using stencil test and gradient color. Verify gradient.

	const glu::RenderContext& renderContext = m_context.getRenderContext();
	const glw::Functions&	 gl			= renderContext.getFunctions();
	std::size_t				  dataSize		= static_cast<std::size_t>(TEX_SIZE * TEX_SIZE * m_typeFormat.size);
	std::vector<GLubyte>	  data(dataSize);

	createTextures();
	renderToTextures();

	bool result = true;
	for (int i = 0; i < NUM_TEXTURES; i++)
	{
		// Read DEPTH_STENCIL value, applies only to desktop
		if (!glu::isContextTypeES(renderContext.getType()))
		{
			gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[i]);

			setDrawReadBuffer(GL_NONE, GL_NONE);

			data.assign(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0);
			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
			result &= verifyDepthStencilGradient(&data[0], i, TEX_SIZE, TEX_SIZE);

			restoreDrawReadBuffer();
		}

		// On ES3.2 we have to render to color buffer to verify.
		// We can run this also on desktop.
		result &= doReadPixels(m_textures[i], i);
	}

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class VerifyGetTexImageTest : public BaseTest
{
public:
	VerifyGetTexImageTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~VerifyGetTexImageTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

VerifyGetTexImageTest::VerifyGetTexImageTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

VerifyGetTexImageTest::~VerifyGetTexImageTest()
{
}

tcu::TestNode::IterateResult VerifyGetTexImageTest::iterate(void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	std::vector<GLubyte>  data(TEX_SIZE * TEX_SIZE * m_typeFormat.size);

	createTextures();
	renderToTextures();

	bool result = true;
	for (int i = 0; i < NUM_TEXTURES; i++)
	{
		data.assign(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0);
		gl.bindTexture(GL_TEXTURE_2D, m_textures[i]);
		gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
		result &= verifyDepthStencilGradient(&data[0], i, TEX_SIZE, TEX_SIZE);
	}

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class VerifyCopyTexImageTest : public BaseTest
{
public:
	VerifyCopyTexImageTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~VerifyCopyTexImageTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

VerifyCopyTexImageTest::VerifyCopyTexImageTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

VerifyCopyTexImageTest::~VerifyCopyTexImageTest()
{
}

tcu::TestNode::IterateResult VerifyCopyTexImageTest::iterate(void)
{
	// After rendering to depth and stencil, CopyTexImage the results to a new
	// DEPTH_STENCIL texture. Attach this texture to a new FBO. Verify that
	// depth and stencil tests work with the copied data.

	createTextures();
	renderToTextures();

	bool				  result = true;
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();

	// setup shader
	GLint uColor;
	setupColorProgram(uColor);

	// setup and copy texture/fbo
	GLuint tex;
	gl.genTextures(1, &tex);
	GLuint fbo;
	gl.genFramebuffers(1, &fbo);
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]);
	gl.bindTexture(GL_TEXTURE_2D, tex);
	setupTexture();

	setDrawReadBuffer(GL_NONE, GL_NONE);

	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
				  NULL);
	gl.copyTexImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, 0, 0, TEX_SIZE, TEX_SIZE, 0);

	restoreDrawReadBuffer();

	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
	setDrawReadBuffer(GL_NONE, GL_NONE);

	int status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
	if (status != GL_FRAMEBUFFER_COMPLETE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
						   << tcu::TestLog::EndMessage;
		result = false;
		restoreDrawReadBuffer();
	}
	else
	{
		// render
		gl.enable(GL_DEPTH_TEST);
		gl.depthFunc(GL_LEQUAL);
		gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
		gl.enable(GL_STENCIL_TEST);
		gl.stencilFunc(GL_EQUAL, 0x1, 0xFF);
		gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
		drawQuad(DEFAULT, m_colorProgram);
		gl.disable(GL_STENCIL_TEST);

		// verify
		std::vector<GLubyte> data(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0);
		gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
		result &= verifyDepthStencilGradient(&data[0], verifyCopyTexImage, TEX_SIZE, TEX_SIZE);

		restoreDrawReadBuffer();

		result &= doReadPixels(tex, verifyCopyTexImage);
	}

	// clean up
	gl.deleteFramebuffers(1, &fbo);
	gl.deleteTextures(1, &tex);

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class VerifyPartialAttachmentsTest : public BaseTest
{
public:
	VerifyPartialAttachmentsTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~VerifyPartialAttachmentsTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

VerifyPartialAttachmentsTest::VerifyPartialAttachmentsTest(deqp::Context& context, const TypeFormat& tf)
	: BaseTest(context, tf)
{
}

VerifyPartialAttachmentsTest::~VerifyPartialAttachmentsTest()
{
}

tcu::TestNode::IterateResult VerifyPartialAttachmentsTest::iterate(void)
{
	createTextures();
	renderToTextures();

	bool result = true;

	//  - Create an FBO with a packed depth stencil renderbuffer attached to
	//	DEPTH_ATTACHMENT only. If this FBO is complete, stencil test must act as
	//	if there is no stencil buffer (always pass.)

	//  - Create an FBO with a packed depth stencil renderbuffer attached to
	//	STENCIL_ATTACHMENT only. If this FBO is complete, depth test must act as
	//	if there is no depth buffer (always pass.)

	//  - Create an FBO with a packed depth stencil renderbuffer attached to
	//	STENCIL_ATTACHMENT only. If this FBO is complete, occlusion query must
	//	act as if there is no depth buffer (always pass.)

	const glu::RenderContext& renderContext = m_context.getRenderContext();
	const glw::Functions&	 gl			= renderContext.getFunctions();
	bool					  isContextES   = glu::isContextTypeES(renderContext.getType());

	// setup shader
	GLint uColor;
	setupColorProgram(uColor);

	GLuint occ;
	gl.genQueries(1, &occ);

	for (int i = 0; i < 3; i++)
	{
		// setup fbo
		GLuint fbo;
		gl.genFramebuffers(1, &fbo);
		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);

		GLuint rbo[2]; // color, D/S
		gl.genRenderbuffers(2, rbo);
		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, TEX_SIZE, TEX_SIZE);
		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
		gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE);

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
		setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);

		switch (i)
		{
		case 0:
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
			break;
		case 1:
		case 2:
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
			break;
		default:
			result = false;
		}

		if (!result)
			break;

		int status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
		if (status != GL_FRAMEBUFFER_COMPLETE)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
							   << tcu::TestLog::EndMessage;
			result = false;
		}
		else
		{
			// render
			gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
			if (isContextES)
				gl.clearDepthf(1.0f);
			else
				gl.clearDepth(1.0);

			gl.clearStencil(0);
			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

			switch (i)
			{
			case 0:
				gl.disable(GL_DEPTH_TEST);
				gl.enable(GL_STENCIL_TEST);
				gl.stencilFunc(GL_NEVER, 0xFF, 0xFF);
				gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
				break;
			case 1:
				gl.enable(GL_DEPTH_TEST);
				gl.depthFunc(GL_NEVER);
				gl.disable(GL_STENCIL_TEST);
				break;
			case 2:
				gl.enable(GL_DEPTH_TEST);
				gl.depthFunc(GL_NEVER);
				gl.disable(GL_STENCIL_TEST);
				gl.beginQuery(GL_ANY_SAMPLES_PASSED, occ);
				break;
			default:
				break;
			}

			drawQuad(DEFAULT, m_colorProgram);

			if (i == 2)
			{
				GLuint n;

				gl.endQuery(GL_ANY_SAMPLES_PASSED);
				gl.getQueryObjectuiv(occ, GL_QUERY_RESULT, &n);

				if (n > 0)
				{
					drawQuad(DEFAULT, m_colorProgram);
				}
			}

			std::vector<GLuint> data(TEX_SIZE * TEX_SIZE, 0);
			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
			result &= verifyColorGradient(&data[0], verifyPartialAttachments, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
		}

		restoreDrawReadBuffer();

		gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);

		// clean up
		gl.deleteFramebuffers(1, &fbo);
		gl.deleteRenderbuffers(2, rbo);
	}

	gl.deleteQueries(1, &occ);

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class VerifyMixedAttachmentsTest : public BaseTest
{
public:
	VerifyMixedAttachmentsTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~VerifyMixedAttachmentsTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

VerifyMixedAttachmentsTest::VerifyMixedAttachmentsTest(deqp::Context& context, const TypeFormat& tf)
	: BaseTest(context, tf)
{
}

VerifyMixedAttachmentsTest::~VerifyMixedAttachmentsTest()
{
}

tcu::TestNode::IterateResult VerifyMixedAttachmentsTest::iterate(void)
{
	// Create FBOs that mix DEPTH_STENCIL renderbuffers with DEPTH or STENCIL
	// renderbuffers. If these FBOs are complete, depth and stencil test
	// must work properly.

	// Create an FBO with two different packed depth stencil renderbuffers, one
	// attached to DEPTH_ATTACHMENT and the other attached to STENCIL_ATTACHMENT.
	// Querying DEPTH_STENCIL_ATTACHMENT must fail with INVALID_OPERATION. If
	// this FBO is complete, depth and stencil tests must work properly.

	createTextures();
	renderToTextures();

	bool result = true;

	const glu::RenderContext& renderContext = m_context.getRenderContext();
	const glw::Functions&	 gl			= renderContext.getFunctions();
	bool					  isContextES   = glu::isContextTypeES(renderContext.getType());

	GLint uColor;
	setupColorProgram(uColor);

	for (int i = 0; i < 3; i++)
	{
		// set up FBO/RBOs
		GLuint fbo;
		gl.genFramebuffers(1, &fbo);
		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);

		GLuint rbo[3]; // color, DEPTH_STENCIL, DEPTH/STENCIL
		gl.genRenderbuffers(3, rbo);

		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, TEX_SIZE, TEX_SIZE);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);

		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
		gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE);

		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[2]);
		switch (i)
		{
		case 0:
			gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[2]);
			break;
		case 1:
			gl.renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, TEX_SIZE, TEX_SIZE);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[2]);
			break;
		case 2:
			gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[2]);

			GLint param;
			gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
												   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &param);
			if (gl.getError() != GL_INVALID_OPERATION)
			{
				m_testCtx.getLog() << tcu::TestLog::Message
								   << "Expected INVALID_OPERATION for DEPTH_STENCIL_ATTACHMENT query"
								   << tcu::TestLog::EndMessage;
				result = false;
			}

			break;
		}

		GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
		if (status != GL_FRAMEBUFFER_COMPLETE)
		{
			if (status == GL_FRAMEBUFFER_UNSUPPORTED)
			{
				/* The spec only requires

					 "when both depth and stencil attachments are present, implementations are only
					  required to support framebuffer objects where both attachments refer to the same image."

				   Thus, it is accepatable for an implementation returning GL_FRAMEBUFFER_UNSUPPORTED.  And the
				   test can NOT be marked as fail.
				 */
			}
			else
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete" << tcu::TestLog::EndMessage;
				result = false;
			}
		}
		else
		{

			// render
			// step 1
			gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
			gl.enable(GL_DEPTH_TEST);
			gl.depthFunc(GL_LEQUAL);

			if (isContextES)
				gl.clearDepthf(1.0f);
			else
				gl.clearDepth(1.0);

			gl.enable(GL_STENCIL_TEST);
			gl.stencilFunc(GL_ALWAYS, 0x1, 0xFF);
			gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
			gl.clearStencil(0);
			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
			drawQuad(DEPTH_SPAN1, m_colorProgram);

			// step 2
			gl.stencilFunc(GL_EQUAL, 0x1, 0xFF);
			gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
			gl.clear(GL_COLOR_BUFFER_BIT);
			drawQuad(DEFAULT, m_colorProgram);

			std::vector<GLuint> data(TEX_SIZE * TEX_SIZE, 0);
			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
			result &= verifyColorGradient(&data[0], verifyMixedAttachments, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
		}

		// clean up
		gl.deleteRenderbuffers(3, rbo);
		gl.deleteFramebuffers(1, &fbo);
	}

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class VerifyParametersTest : public BaseTest
{
public:
	VerifyParametersTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~VerifyParametersTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

VerifyParametersTest::VerifyParametersTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

VerifyParametersTest::~VerifyParametersTest()
{
}

tcu::TestNode::IterateResult VerifyParametersTest::iterate(void)
{
	//  Verify GetFramebufferAttachmentParameter queries of each <pname> on
	//	DEPTH_STENCIL_ATTACHMENT work correctly if both attachments are populated
	//	with the same object.

	createTextures();
	renderToTextures();

	bool result = true;

	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);

	GLint param;
	gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
										   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &param);
	if (param != GL_TEXTURE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Invalid value for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: " << param
						   << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		return STOP;
	}

	const AttachmentParam* attachmentParams = getAttachmentParams();
	for (GLuint i = 0; i < m_attachmentParamsCount; i++)
	{
		int	ref;
		GLenum pname = attachmentParams[i].pname;
		if (GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE == pname)
		{
			gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, pname, &param);
			if (gl.getError() != GL_INVALID_OPERATION)
				result = false;
			continue;
		}

		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, pname, &param);

		ref = attachmentParams[i].value;
		if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)
			ref = m_textures[packedTexImage];

		if (param != ref)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for pname " << attachmentParams[i].pname
							   << ": " << param << " ( expected " << ref << ")" << tcu::TestLog::EndMessage;
			result = false;
		}
	}

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class RenderbuffersTest : public BaseTest
{
public:
	RenderbuffersTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~RenderbuffersTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

RenderbuffersTest::RenderbuffersTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

RenderbuffersTest::~RenderbuffersTest()
{
}

tcu::TestNode::IterateResult RenderbuffersTest::iterate(void)
{
	createTextures();
	renderToTextures();

	bool result = true;

	// Verify RENDERBUFFER_DEPTH_SIZE and RENDERBUFFER_STENCIL_SIZE report
	// appropriate values for for DEPTH_STENCIL renderbuffers.

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

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);

	GLuint rbo;
	gl.genRenderbuffers(1, &rbo);
	gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
	gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);

	GLint param;
	gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_DEPTH_SIZE, &param);
	if (param != m_typeFormat.d)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid depth: " << param << ", expected: " << m_typeFormat.d
						   << tcu::TestLog::EndMessage;
		result = false;
	}

	gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_STENCIL_SIZE, &param);
	if (param != m_typeFormat.s)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid stencil: " << param << ", expected: " << m_typeFormat.s
						   << tcu::TestLog::EndMessage;
		result = false;
	}

	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
	gl.deleteRenderbuffers(1, &rbo);
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class StencilSizeTest : public BaseTest
{
public:
	StencilSizeTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~StencilSizeTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

StencilSizeTest::StencilSizeTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

StencilSizeTest::~StencilSizeTest()
{
}

tcu::TestNode::IterateResult StencilSizeTest::iterate(void)
{
	// [desktop only] Verify TEXTURE_STENCIL_SIZE reports 8 for DEPTH_STENCIL
	// textures, and 0 for RGBA and DEPTH_COMPONENT textures.

	createTextures();
	renderToTextures();

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

	bool  result = true;
	GLint param;
	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]);
	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, &param);
	if (param != 8)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for DEPTH_STENCIL stencil size: " << param
						   << tcu::TestLog::EndMessage;
		result = false;
	}

	GLuint texRGBA;
	gl.genTextures(1, &texRGBA);
	gl.bindTexture(GL_TEXTURE_2D, texRGBA);
	setupTexture();
	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, &param);
	if (param != 0)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for RGBA stencil size: " << param
						   << tcu::TestLog::EndMessage;
		result = false;
	}
	gl.deleteTextures(1, &texRGBA);

	GLuint texDepth;
	gl.genTextures(1, &texDepth);
	gl.bindTexture(GL_TEXTURE_2D, texDepth);
	setupTexture();
	gl.texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
				  0);
	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, &param);
	if (param != 0)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for DEPTH_COMPONENT stencil size: " << param
						   << tcu::TestLog::EndMessage;
		result = false;
	}
	gl.deleteTextures(1, &texDepth);

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class ClearBufferTest : public BaseTest
{
public:
	ClearBufferTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~ClearBufferTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

ClearBufferTest::ClearBufferTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

ClearBufferTest::~ClearBufferTest()
{
}

tcu::TestNode::IterateResult ClearBufferTest::iterate(void)
{
	// Verify ClearBufferfv correctly clears the depth channel of a DEPTH_STENCIL
	// FBO attachment (and does not touch the stencil channel.)
	// Verify ClearBufferiv correctly clears the stencil channel of a
	// DEPTH_STENCIL FBO attachment (and does not touch the depth channel.)
	// Verify ClearBufferfi correctly clears the depth and stencil channels of a
	// DEPTH_STENCIL FBO attachment.

	createTextures();
	renderToTextures();

	bool	result = true;
	GLfloat valuef;
	GLint   valuei;
	GLenum  status;

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

	// setup shader
	GLint uColor;
	setupColorProgram(uColor);

	for (int i = 0; i < 3; i++)
	{
		// setup texture/fbo
		GLuint tex;
		GLuint texColor;
		GLuint fbo;
		gl.genTextures(1, &tex);
		gl.genTextures(1, &texColor);
		gl.genFramebuffers(1, &fbo);
		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);

		gl.bindTexture(GL_TEXTURE_2D, tex);
		setupTexture();
		std::vector<GLbyte> data;
		createGradient(data);
		gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
					  &data[0]);
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0);

		gl.bindTexture(GL_TEXTURE_2D, texColor);
		setupTexture();
		gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);

		setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);

		status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
		if (status != GL_FRAMEBUFFER_COMPLETE)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
							   << tcu::TestLog::EndMessage;
			result = false;
		}
		else
		{
			// clear relevant buffers
			switch (i)
			{
			case 0:
				valuef = 1.0f;
				gl.clearBufferfv(GL_DEPTH, 0, &valuef);
				break;
			case 1:
				valuei = 0xff;
				gl.clearBufferiv(GL_STENCIL, 0, &valuei);
				break;
			case 2:
				valuef = 1.0f;
				valuei = 0xff;
				gl.clearBufferfi(GL_DEPTH_STENCIL, 0, valuef, valuei);
				break;
			}

			// render reference image
			gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
			gl.enable(GL_DEPTH_TEST);
			gl.depthFunc(GL_LEQUAL);
			gl.enable(GL_STENCIL_TEST);
			gl.stencilFunc(GL_EQUAL, 0xFF, 0xFF);
			gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
			gl.clear(GL_COLOR_BUFFER_BIT);
			drawQuad(DEFAULT, m_colorProgram);

			// verify
			std::vector<GLubyte> readData(TEX_SIZE * TEX_SIZE * 4, 0);
			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &readData[0]);
			result &=
				verifyColorGradient(&readData[0], verifyClearBufferDepth + i, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
		}

		// destroy texture/fbo
		restoreDrawReadBuffer();

		gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
		gl.bindTexture(GL_TEXTURE_2D, 0);
		gl.deleteFramebuffers(1, &fbo);
		gl.deleteTextures(1, &tex);
		gl.deleteTextures(1, &texColor);
	}

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class BlitTest : public BaseTest
{
public:
	BlitTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~BlitTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

BlitTest::BlitTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

BlitTest::~BlitTest()
{
}

tcu::TestNode::IterateResult BlitTest::iterate(void)
{
	// Verify that NEAREST filtered blits of DEPTH and/or STENCIL between two
	// FBOs with the same format packed depth stencil attachment work. Test
	// non-multisample [1->1], multisample resolve [N->1], and multisample
	// replicate [1->N] blits, for each supported value of N up to MAX_SAMPLES.

	createTextures();
	renderToTextures();

	GLuint fbo[3]; // Framebuffers: source, dest, downsample
	GLuint rbo[4]; // Renderbuffers: source D/S, dest D/S, dest color, downsample color
	GLint  maxSamples;
	int	srcSamples, destSamples;
	bool   result = true;

	const glu::RenderContext& renderContext = m_context.getRenderContext();
	const glw::Functions&	 gl			= renderContext.getFunctions();
	bool					  isContextES   = glu::isContextTypeES(renderContext.getType());

	std::vector<GLuint> data(TEX_SIZE * TEX_SIZE);

	GLint uColor;
	setupColorProgram(uColor);

	gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples);

	// ES does not allow SAMPLE_BUFFERS for the draw frame
	// buffer is greater than zero when doing a blit.
	int loopCount = isContextES ? 1 : 2;

	for (int j = 0; j < loopCount; j++)
	{
		for (int i = 0; i <= maxSamples; i++)
		{
			// Create FBO/RBO
			gl.genFramebuffers(3, fbo);
			gl.genRenderbuffers(4, rbo);

			if (j == 0)
			{
				srcSamples  = i;
				destSamples = 0;
			}
			else
			{
				srcSamples  = 0;
				destSamples = i;
			}

			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, srcSamples, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[0]);

			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, destSamples, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);

			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[2]);
			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, destSamples, GL_RGBA8, TEX_SIZE, TEX_SIZE);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[2]);

			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[2]);
			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[3]);
			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[3]);

			// Render
			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
			setDrawReadBuffer(GL_NONE, GL_NONE);

			gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
			gl.enable(GL_DEPTH_TEST);
			gl.depthFunc(GL_LEQUAL);

			if (isContextES)
				gl.clearDepthf(1.0f);
			else
				gl.clearDepth(1.0);

			gl.enable(GL_STENCIL_TEST);
			gl.stencilFunc(GL_ALWAYS, 0x1, 0xFF);
			gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
			gl.clearStencil(0);
			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
			drawQuad(DEPTH_SPAN1, m_colorProgram);

			restoreDrawReadBuffer();

			// Blit
			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo[0]);
			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
			setDrawReadBuffer(GL_NONE, GL_NONE);
			gl.blitFramebuffer(0, 0, TEX_SIZE, TEX_SIZE, 0, 0, TEX_SIZE, TEX_SIZE,
							   GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
			restoreDrawReadBuffer();

			// Verify
			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
			setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);

			gl.stencilFunc(GL_EQUAL, 0x1, 0xFF);
			gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
			gl.clear(GL_COLOR_BUFFER_BIT);
			drawQuad(DEFAULT, m_colorProgram);

			restoreDrawReadBuffer();

			// Downsample blit
			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[2]);
			setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);
			gl.blitFramebuffer(0, 0, TEX_SIZE, TEX_SIZE, 0, 0, TEX_SIZE, TEX_SIZE, GL_COLOR_BUFFER_BIT, GL_NEAREST);
			restoreDrawReadBuffer();

			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[2]);

			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);

			result &= verifyColorGradient(&data[0], verifyBlit, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);

			// Clean up
			gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
			gl.bindRenderbuffer(GL_RENDERBUFFER, 0);

			gl.deleteRenderbuffers(4, rbo);
			gl.deleteFramebuffers(3, fbo);
		}
	}

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

class StencilTexturingTest : public BaseTest
{
public:
	StencilTexturingTest(deqp::Context& context, const TypeFormat& tf);
	virtual ~StencilTexturingTest();

	virtual tcu::TestNode::IterateResult iterate(void);
};

StencilTexturingTest::StencilTexturingTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
{
}

StencilTexturingTest::~StencilTexturingTest()
{
}

tcu::TestNode::IterateResult StencilTexturingTest::iterate(void)
{
	// Verifies that either depth or stencil can be sampled depending on
	// GL_DEPTH_STENCIL_TEXTURE_MODE

	const glu::RenderContext& renderContext = m_context.getRenderContext();
	glu::ContextType		  contextType   = renderContext.getType();
	const glw::Functions&	 gl			= renderContext.getFunctions();

	bool notSupported = false;
	if (glu::isContextTypeES(contextType))
		notSupported = !glu::contextSupports(contextType, glu::ApiType::es(3, 1));
	else
		notSupported = !glu::contextSupports(contextType, glu::ApiType::core(4, 3));

	if (notSupported)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "stencil_texturing extension is not supported");
		return STOP;
	}

	createTextures();
	renderToTextures();

	bool   result = true;
	GLuint fbo;
	gl.genFramebuffers(1, &fbo);
	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);

	GLuint texColor;
	gl.genTextures(1, &texColor);
	gl.bindTexture(GL_TEXTURE_2D, texColor);
	setupTexture();
	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);
	setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);

	// Step 1: Verify depth values
	GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
	if (status != GL_FRAMEBUFFER_COMPLETE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
						   << tcu::TestLog::EndMessage;
		result = false;
	}
	else
	{
		gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]);

		gl.disable(GL_DEPTH_TEST);
		gl.depthMask(GL_FALSE);
		gl.disable(GL_STENCIL_TEST);
		gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
		gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
		gl.clear(GL_COLOR_BUFFER_BIT);

		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
		setupTextureProgram();
		drawQuad(DEFAULT, m_textureProgram);

		std::vector<GLuint> dataColor(TEX_SIZE * TEX_SIZE, 0);
		gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]);
		result &= verifyColorGradient(&dataColor[0], packedTexImage, COLOR_CHECK_DEPTH, TEX_SIZE, TEX_SIZE);

		// Step 2: Verify stencil values
		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
		setupStencilProgram();
		drawQuad(DEFAULT, m_stencilProgram);

		dataColor.assign(TEX_SIZE * TEX_SIZE, 0);
		gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]);
		result &= verifyColorGradient(&dataColor[0], packedTexImage, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
	}

	restoreDrawReadBuffer();
	gl.deleteFramebuffers(1, &fbo);
	gl.deleteTextures(1, &texColor);

	destroyTextures();
	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

PackedDepthStencilTests::PackedDepthStencilTests(deqp::Context& context)
	: TestCaseGroup(context, "packed_depth_stencil", "")
{
}

PackedDepthStencilTests::~PackedDepthStencilTests(void)
{
}

void PackedDepthStencilTests::init(void)
{
	TestCaseGroup* validateErrorsGroup			 = new deqp::TestCaseGroup(m_context, "validate_errors", "");
	TestCaseGroup* verifyReadPixelsGroup		 = new deqp::TestCaseGroup(m_context, "verify_read_pixels", "");
	TestCaseGroup* verifyGetTexImageGroup		 = new deqp::TestCaseGroup(m_context, "verify_get_tex_image", "");
	TestCaseGroup* verifyCopyTexImageGroup		 = new deqp::TestCaseGroup(m_context, "verify_copy_tex_image", "");
	TestCaseGroup* verifyPartialAttachmentsGroup = new deqp::TestCaseGroup(m_context, "verify_partial_attachments", "");
	TestCaseGroup* verifyMixedAttachmentsGroup   = new deqp::TestCaseGroup(m_context, "verify_mixed_attachments", "");
	TestCaseGroup* verifyParametersGroup		 = new deqp::TestCaseGroup(m_context, "verify_parameters", "");
	TestCaseGroup* renderbuffersGroup			 = new deqp::TestCaseGroup(m_context, "renderbuffers", "");
	TestCaseGroup* clearBufferGroup				 = new deqp::TestCaseGroup(m_context, "clear_buffer", "");
	TestCaseGroup* blitGroup					 = new deqp::TestCaseGroup(m_context, "blit", "");
	TestCaseGroup* stencilTexturingGroup		 = new deqp::TestCaseGroup(m_context, "stencil_texturing", "");
	TestCaseGroup* stencilSizeGroup				 = new deqp::TestCaseGroup(m_context, "stencil_size", "");

	bool isContextCoreGL = !glu::isContextTypeES(m_context.getRenderContext().getType());
	if (isContextCoreGL)
		validateErrorsGroup->addChild(new InitialStateTest(m_context));

	for (int i = 0; i < NUM_TEXTURE_TYPES; i++)
	{
		const TypeFormat& typeFormat = TextureTypes[i];
		validateErrorsGroup->addChild(new ValidateErrorsTest(m_context, typeFormat));
		verifyReadPixelsGroup->addChild(new VerifyReadPixelsTest(m_context, typeFormat));
		verifyPartialAttachmentsGroup->addChild(new VerifyPartialAttachmentsTest(m_context, typeFormat));
		verifyMixedAttachmentsGroup->addChild(new VerifyMixedAttachmentsTest(m_context, typeFormat));
		verifyParametersGroup->addChild(new VerifyParametersTest(m_context, typeFormat));
		renderbuffersGroup->addChild(new RenderbuffersTest(m_context, typeFormat));
		clearBufferGroup->addChild(new ClearBufferTest(m_context, typeFormat));
		blitGroup->addChild(new BlitTest(m_context, typeFormat));
		stencilTexturingGroup->addChild(new StencilTexturingTest(m_context, typeFormat));

		if (isContextCoreGL)
		{
			verifyGetTexImageGroup->addChild(new VerifyGetTexImageTest(m_context, typeFormat));
			verifyCopyTexImageGroup->addChild(new VerifyCopyTexImageTest(m_context, typeFormat));
			stencilSizeGroup->addChild(new StencilSizeTest(m_context, typeFormat));
		}
	}

	addChild(validateErrorsGroup);
	addChild(verifyReadPixelsGroup);
	addChild(verifyGetTexImageGroup);
	addChild(verifyCopyTexImageGroup);
	addChild(verifyPartialAttachmentsGroup);
	addChild(verifyMixedAttachmentsGroup);
	addChild(verifyParametersGroup);
	addChild(renderbuffersGroup);
	addChild(clearBufferGroup);
	addChild(blitGroup);
	addChild(stencilTexturingGroup);
	addChild(stencilSizeGroup);
}

} /* glcts namespace */
