/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 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 Stencil texturing tests.
 *//*--------------------------------------------------------------------*/

#include "es31fStencilTexturingTests.hpp"

#include "gluStrUtil.hpp"
#include "gluObjectWrapper.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "gluDrawUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"
#include "gluContextInfo.hpp"

#include "glsTextureTestUtil.hpp"

#include "tcuVector.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexLookupVerifier.hpp"

#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include "deStringUtil.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{

using std::vector;
using std::string;
using tcu::IVec4;
using tcu::Vec2;
using tcu::Vec4;
using tcu::TestLog;
using tcu::TextureLevel;
using tcu::TextureFormat;

namespace
{

static void genTestRects (vector<IVec4>& rects, int width, int height)
{
	int curWidth	= width;
	int curHeight	= height;
	int ndx			= 0;

	for (;;)
	{
		rects.push_back(IVec4(width-curWidth, height-curHeight, curWidth, curHeight));

		DE_ASSERT(curWidth >= 1 && curHeight >= 1);
		if (curWidth == 1 && curHeight == 1)
			break;
		else if (curHeight > 1 && ((ndx%2) == 0 || curWidth == 1))
			curHeight -= 1;
		else
			curWidth -= 1;

		ndx += 1;
	}
}

static void rectsToTriangles (const vector<IVec4>& rects, int width, int height, vector<Vec2>& positions, vector<deUint16>& indices)
{
	const float		w		= float(width);
	const float		h		= float(height);

	positions.resize(rects.size()*4);
	indices.resize(rects.size()*6);

	for (int rectNdx = 0; rectNdx < (int)rects.size(); rectNdx++)
	{
		const int		rx		= rects[rectNdx].x();
		const int		ry		= rects[rectNdx].y();
		const int		rw		= rects[rectNdx].z();
		const int		rh		= rects[rectNdx].w();

		const float		x0		= float(rx*2)/w - 1.0f;
		const float		x1		= float((rx+rw)*2)/w - 1.0f;
		const float		y0		= float(ry*2)/h - 1.0f;
		const float		y1		= float((ry+rh)*2)/h - 1.0f;

		positions[rectNdx*4 + 0] = Vec2(x0, y0);
		positions[rectNdx*4 + 1] = Vec2(x1, y0);
		positions[rectNdx*4 + 2] = Vec2(x0, y1);
		positions[rectNdx*4 + 3] = Vec2(x1, y1);

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

static void drawTestPattern (const glu::RenderContext& renderCtx, int width, int height)
{
	const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
		<< glu::VertexSource(
			"#version 300 es\n"
			"in highp vec4 a_position;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"}\n")
		<< glu::FragmentSource(
			"#version 300 es\n"
			"void main (void) {}\n"));

	const glw::Functions&	gl		= renderCtx.getFunctions();
	vector<IVec4>			rects;
	vector<Vec2>			positions;
	vector<deUint16>		indices;

	if (!program.isOk())
		throw tcu::TestError("Compile failed");

	gl.useProgram	(program.getProgram());
	gl.viewport		(0, 0, width, height);
	gl.clear		(GL_STENCIL_BUFFER_BIT);
	gl.enable		(GL_STENCIL_TEST);
	gl.stencilOp	(GL_KEEP, GL_KEEP, GL_INCR_WRAP);
	gl.stencilFunc	(GL_ALWAYS, 0, ~0u);
	GLU_EXPECT_NO_ERROR(gl.getError(), "State setup failed");

	genTestRects	(rects, width, height);
	rectsToTriangles(rects, width, height, positions, indices);

	{
		const glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 2, (int)positions.size(), 0, positions[0].getPtr());
		glu::draw(renderCtx, program.getProgram(), 1, &posBinding, glu::pr::Triangles((int)indices.size(), &indices[0]));
	}

	gl.disable(GL_STENCIL_TEST);
}

static void renderTestPatternReference (const tcu::PixelBufferAccess& dst)
{
	const int		stencilBits		= tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilAccess(dst, tcu::Sampler::MODE_STENCIL).getFormat()).x();
	const deUint32	stencilMask		= (1u<<stencilBits)-1u;
	vector<IVec4>	rects;

	DE_ASSERT(dst.getFormat().order == TextureFormat::S || dst.getFormat().order == TextureFormat::DS);

	// clear depth and stencil
	if (dst.getFormat().order == TextureFormat::DS)
		tcu::clearDepth(dst, 0.0f);
	tcu::clearStencil(dst, 0u);

	genTestRects(rects, dst.getWidth(), dst.getHeight());

	for (vector<IVec4>::const_iterator rectIter = rects.begin(); rectIter != rects.end(); ++rectIter)
	{
		const int	x0		= rectIter->x();
		const int	y0		= rectIter->y();
		const int	x1		= x0+rectIter->z();
		const int	y1		= y0+rectIter->w();

		for (int y = y0; y < y1; y++)
		{
			for (int x = x0; x < x1; x++)
			{
				const int oldVal	= dst.getPixStencil(x, y);
				const int newVal	= (oldVal+1)&stencilMask;

				dst.setPixStencil(newVal, x, y);
			}
		}
	}
}

static void blitStencilToColor2D (const glu::RenderContext& renderCtx, deUint32 srcTex, int width, int height)
{
	const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
		<< glu::VertexSource(
			"#version 300 es\n"
			"in highp vec4 a_position;\n"
			"in highp vec2 a_texCoord;\n"
			"out highp vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_texCoord = a_texCoord;\n"
			"}\n")
		<< glu::FragmentSource(
			"#version 300 es\n"
			"uniform highp usampler2D u_sampler;\n"
			"in highp vec2 v_texCoord;\n"
			"layout(location = 0) out highp uint o_stencil;\n"
			"void main (void)\n"
			"{\n"
			"	o_stencil = texture(u_sampler, v_texCoord).x;\n"
			"}\n"));

	const float positions[] =
	{
		-1.0f, -1.0f,
		+1.0f, -1.0f,
		-1.0f, +1.0f,
		+1.0f, +1.0f
	};
	const float texCoord[] =
	{
		0.0f, 0.0f,
		1.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f
	};
	const glu::VertexArrayBinding vertexArrays[] =
	{
		glu::va::Float("a_position", 2, 4, 0, &positions[0]),
		glu::va::Float("a_texCoord", 2, 4, 0, &texCoord[0])
	};
	const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };

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

	if (!program.isOk())
		throw tcu::TestError("Compile failed");

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, srcTex);
	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_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");

	gl.useProgram(program.getProgram());
	gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");

	gl.viewport(0, 0, width, height);
	glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
}

static void blitStencilToColor2DArray (const glu::RenderContext& renderCtx, deUint32 srcTex, int width, int height, int level)
{
	const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
		<< glu::VertexSource(
			"#version 300 es\n"
			"in highp vec4 a_position;\n"
			"in highp vec3 a_texCoord;\n"
			"out highp vec3 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_texCoord = a_texCoord;\n"
			"}\n")
		<< glu::FragmentSource(
			"#version 300 es\n"
			"uniform highp usampler2DArray u_sampler;\n"
			"in highp vec3 v_texCoord;\n"
			"layout(location = 0) out highp uint o_stencil;\n"
			"void main (void)\n"
			"{\n"
			"	o_stencil = texture(u_sampler, v_texCoord).x;\n"
			"}\n"));

	const float positions[] =
	{
		-1.0f, -1.0f,
		+1.0f, -1.0f,
		-1.0f, +1.0f,
		+1.0f, +1.0f
	};
	const float texCoord[] =
	{
		0.0f, 0.0f, float(level),
		1.0f, 0.0f, float(level),
		0.0f, 1.0f, float(level),
		1.0f, 1.0f, float(level)
	};
	const glu::VertexArrayBinding vertexArrays[] =
	{
		glu::va::Float("a_position", 2, 4, 0, &positions[0]),
		glu::va::Float("a_texCoord", 3, 4, 0, &texCoord[0])
	};
	const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };

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

	if (!program.isOk())
		throw tcu::TestError("Compile failed");

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D_ARRAY, srcTex);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");

	gl.useProgram(program.getProgram());
	gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");

	gl.viewport(0, 0, width, height);
	glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
}

static void blitStencilToColorCube (const glu::RenderContext& renderCtx, deUint32 srcTex, const float* texCoord, int width, int height)
{
	const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
		<< glu::VertexSource(
			"#version 300 es\n"
			"in highp vec4 a_position;\n"
			"in highp vec3 a_texCoord;\n"
			"out highp vec3 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_texCoord = a_texCoord;\n"
			"}\n")
		<< glu::FragmentSource(
			"#version 300 es\n"
			"uniform highp usamplerCube u_sampler;\n"
			"in highp vec3 v_texCoord;\n"
			"layout(location = 0) out highp vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color.x = float(texture(u_sampler, v_texCoord).x) / 255.0;\n"
			"	o_color.yzw = vec3(0.0, 0.0, 1.0);\n"
			"}\n"));

	const float positions[] =
	{
		-1.0f, -1.0f,
		-1.0f, +1.0f,
		+1.0f, -1.0f,
		+1.0f, +1.0f
	};
	const glu::VertexArrayBinding vertexArrays[] =
	{
		glu::va::Float("a_position", 2, 4, 0, &positions[0]),
		glu::va::Float("a_texCoord", 3, 4, 0, texCoord)
	};
	const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };

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

	if (!program.isOk())
		throw tcu::TestError("Compile failed");

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, srcTex);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");

	gl.useProgram(program.getProgram());
	gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");

	gl.viewport(0, 0, width, height);
	glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
}

static inline tcu::ConstPixelBufferAccess stencilToRedAccess (const tcu::ConstPixelBufferAccess& access)
{
	DE_ASSERT(access.getFormat() == TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8));
	return tcu::ConstPixelBufferAccess(TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT8), access.getSize(), access.getPitch(), access.getDataPtr());
}

static bool compareStencilToRed (tcu::TestLog& log, const tcu::ConstPixelBufferAccess& stencilRef, const tcu::ConstPixelBufferAccess& result)
{
	const int		maxPrints		= 10;
	int				numFailed		= 0;

	DE_ASSERT(stencilRef.getFormat().order == TextureFormat::S);
	DE_ASSERT(stencilRef.getWidth() == result.getWidth() && stencilRef.getHeight() == result.getHeight());

	for (int y = 0; y < stencilRef.getHeight(); y++)
	{
		for (int x = 0; x < stencilRef.getWidth(); x++)
		{
			const int		ref		= stencilRef.getPixStencil(x, y);
			const int		res		= result.getPixelInt(x, y).x();

			if (ref != res)
			{
				if (numFailed < maxPrints)
					log << TestLog::Message << "ERROR: Expected " << ref << ", got " << res << " at (" << x << ", " << y << ")" << TestLog::EndMessage;
				else if (numFailed == maxPrints)
					log << TestLog::Message << "..." << TestLog::EndMessage;

				numFailed += 1;
			}
		}
	}

	log << TestLog::Message << "Found " << numFailed << " faulty pixels, comparison " << (numFailed == 0 ? "passed." : "FAILED!") << TestLog::EndMessage;

	log << TestLog::ImageSet("ComparisonResult", "Image comparison result")
		<< TestLog::Image("Result", "Result stencil buffer", result);

	if (numFailed > 0)
		log << TestLog::Image("Reference", "Reference stencil buffer", stencilToRedAccess(stencilRef));

	log << TestLog::EndImageSet;

	return numFailed == 0;
}

static bool compareRedChannel (tcu::TestLog& log, const tcu::ConstPixelBufferAccess& result, int reference)
{
	const int		maxPrints		= 10;
	int				numFailed		= 0;

	for (int y = 0; y < result.getHeight(); y++)
	{
		for (int x = 0; x < result.getWidth(); x++)
		{
			const int res = result.getPixelInt(x, y).x();

			if (reference != res)
			{
				if (numFailed < maxPrints)
					log << TestLog::Message << "ERROR: Expected " << reference << ", got " << res << " at (" << x << ", " << y << ")" << TestLog::EndMessage;
				else if (numFailed == maxPrints)
					log << TestLog::Message << "..." << TestLog::EndMessage;

				numFailed += 1;
			}
		}
	}

	log << TestLog::Message << "Found " << numFailed << " faulty pixels, comparison " << (numFailed == 0 ? "passed." : "FAILED!") << TestLog::EndMessage;

	log << TestLog::ImageSet("ComparisonResult", "Image comparison result")
		<< TestLog::Image("Result", "Result stencil buffer", result);

	log << TestLog::EndImageSet;

	return numFailed == 0;
}

static void stencilToUnorm8 (const tcu::TextureCube& src, tcu::TextureCube& dst)
{
	for (int levelNdx = 0; levelNdx < src.getNumLevels(); levelNdx++)
	{
		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
		{
			const tcu::CubeFace face = tcu::CubeFace(faceNdx);

			if (!src.isLevelEmpty(face, levelNdx))
			{
				dst.allocLevel(face, levelNdx);

				const tcu::ConstPixelBufferAccess	srcLevel	= src.getLevelFace(levelNdx, face);
				const tcu::PixelBufferAccess		dstLevel	= dst.getLevelFace(levelNdx, face);

				for (int y = 0; y < src.getSize(); y++)
				for (int x = 0; x < src.getSize(); x++)
					dstLevel.setPixel(Vec4(float(srcLevel.getPixStencil(x, y)) / 255.f, 0.f, 0.f, 1.f), x, y);
			}
		}
	}
}

static void checkDepthStencilFormatSupport (Context& context, deUint32 format)
{
	if (format == GL_STENCIL_INDEX8)
	{
		const char*			reqExt		= "GL_OES_texture_stencil8";
		glu::ContextType	contextType	= context.getRenderContext().getType();
		if (!glu::contextSupports(contextType, glu::ApiType::es(3, 2)) &&
			!glu::contextSupports(contextType, glu::ApiType::core(4, 5)) &&
			!context.getContextInfo().isExtensionSupported(reqExt))
			throw tcu::NotSupportedError(glu::getTextureFormatStr(format).toString() + " requires " + reqExt);
	}
	else
	{
		DE_ASSERT(format == GL_DEPTH32F_STENCIL8 || format == GL_DEPTH24_STENCIL8);
	}
}

static void checkFramebufferStatus (const glw::Functions& gl)
{
	const deUint32 status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);

	if (status == GL_FRAMEBUFFER_UNSUPPORTED)
		throw tcu::NotSupportedError("Unsupported framebuffer configuration");
	else if (status != GL_FRAMEBUFFER_COMPLETE)
		throw tcu::TestError("Incomplete framebuffer: " + glu::getFramebufferStatusStr(status).toString());
}

class UploadTex2DCase : public TestCase
{
public:
	UploadTex2DCase (Context& context, const char* name, deUint32 format)
		: TestCase	(context, name, glu::getTextureFormatName(format))
		, m_format	(format)
	{
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
		const glw::Functions&		gl					= renderCtx.getFunctions();
		const int					width				= 129;
		const int					height				= 113;
		glu::Framebuffer			fbo					(renderCtx);
		glu::Renderbuffer			colorBuf			(renderCtx);
		glu::Texture				depthStencilTex		(renderCtx);
		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height);
		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);

		checkDepthStencilFormatSupport(m_context, m_format);

		renderTestPatternReference(uploadLevel);
		renderTestPatternReference(stencilOnlyLevel);

		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);

		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
		checkFramebufferStatus(gl);

		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
		glu::readPixels(renderCtx, 0, 0, readLevel);

		{
			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
									compareOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}

private:
	const deUint32 m_format;
};

class UploadTex2DArrayCase : public TestCase
{
public:
	UploadTex2DArrayCase (Context& context, const char* name, deUint32 format)
		: TestCase	(context, name, glu::getTextureFormatName(format))
		, m_format	(format)
	{
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
		const glw::Functions&		gl					= renderCtx.getFunctions();
		const int					width				= 41;
		const int					height				= 13;
		const int					levels				= 7;
		const int					ptrnLevel			= 3;
		glu::Framebuffer			fbo					(renderCtx);
		glu::Renderbuffer			colorBuf			(renderCtx);
		glu::Texture				depthStencilTex		(renderCtx);
		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height, levels);

		checkDepthStencilFormatSupport(m_context, m_format);

		for (int levelNdx = 0; levelNdx < levels; levelNdx++)
		{
			const tcu::PixelBufferAccess levelAccess = tcu::getSubregion(uploadLevel.getAccess(), 0, 0, levelNdx, width, height, 1);

			if (levelNdx == ptrnLevel)
				renderTestPatternReference(levelAccess);
			else
				tcu::clearStencil(levelAccess, levelNdx);
		}

		gl.bindTexture(GL_TEXTURE_2D_ARRAY, *depthStencilTex);
		gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, width, height, levels);
		glu::texSubImage3D(renderCtx, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, uploadLevel);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);

		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
		checkFramebufferStatus(gl);

		{
			TextureLevel	readLevel		(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
			bool			allLevelsOk		= true;

			for (int levelNdx = 0; levelNdx < levels; levelNdx++)
			{
				tcu::ScopedLogSection section(m_testCtx.getLog(), "Level" + de::toString(levelNdx), "Level " + de::toString(levelNdx));
				bool levelOk;

				blitStencilToColor2DArray(renderCtx, *depthStencilTex, width, height, levelNdx);
				glu::readPixels(renderCtx, 0, 0, readLevel);

				if (levelNdx == ptrnLevel)
				{
					TextureLevel reference(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
					renderTestPatternReference(reference);

					levelOk = compareStencilToRed(m_testCtx.getLog(), reference, readLevel);
				}
				else
					levelOk = compareRedChannel(m_testCtx.getLog(), readLevel, levelNdx);

				if (!levelOk)
				{
					allLevelsOk = false;
					break;
				}
			}

			m_testCtx.setTestResult(allLevelsOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
									allLevelsOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}

private:
	const deUint32 m_format;
};

class UploadTexCubeCase : public TestCase
{
public:
	UploadTexCubeCase (Context& context, const char* name, deUint32 format)
		: TestCase	(context, name, glu::getTextureFormatName(format))
		, m_format	(format)
	{
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
		const glw::Functions&		gl					= renderCtx.getFunctions();
		const int					size				= 64;
		const int					renderWidth			= 128;
		const int					renderHeight		= 128;
		vector<float>				texCoord;
		glu::Framebuffer			fbo					(renderCtx);
		glu::Renderbuffer			colorBuf			(renderCtx);
		glu::Texture				depthStencilTex		(renderCtx);
		tcu::TextureCube			texData				(glu::mapGLInternalFormat(m_format), size);
		tcu::TextureLevel			result				(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), renderWidth, renderHeight);

		checkDepthStencilFormatSupport(m_context, m_format);

		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
		{
			const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
			const int				stencilVal	= 42*faceNdx;

			texData.allocLevel(face, 0);
			tcu::clearStencil(texData.getLevelFace(0, face), stencilVal);
		}

		glu::TextureTestUtil::computeQuadTexCoordCube(texCoord, tcu::CUBEFACE_NEGATIVE_X, Vec2(-1.5f, -1.3f), Vec2(1.3f, 1.4f));

		gl.bindTexture(GL_TEXTURE_CUBE_MAP, *depthStencilTex);
		gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, m_format, size, size);

		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
			glu::texSubImage2D(renderCtx, glu::getGLCubeFace(tcu::CubeFace(faceNdx)), 0, 0, 0, texData.getLevelFace(0, tcu::CubeFace(faceNdx)));

		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, renderWidth, renderHeight);

		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
		checkFramebufferStatus(gl);

		blitStencilToColorCube(renderCtx, *depthStencilTex, &texCoord[0], renderWidth, renderHeight);
		glu::readPixels(renderCtx, 0, 0, result);

		{
			using namespace glu::TextureTestUtil;

			tcu::TextureCube		redTex			(TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT8), size);
			const ReferenceParams	sampleParams	(TEXTURETYPE_CUBE, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE,
																					tcu::Sampler::CLAMP_TO_EDGE,
																					tcu::Sampler::CLAMP_TO_EDGE,
																					tcu::Sampler::NEAREST,
																					tcu::Sampler::NEAREST));
			tcu::LookupPrecision	lookupPrec;
			tcu::LodPrecision		lodPrec;
			bool					compareOk;

			lookupPrec.colorMask		= tcu::BVec4(true, true, true, true);
			lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(IVec4(8, 8, 8, 8));
			lookupPrec.coordBits		= tcu::IVec3(22, 22, 22);
			lookupPrec.uvwBits			= tcu::IVec3(5, 5, 0);
			lodPrec.lodBits				= 7;
			lodPrec.derivateBits		= 16;

			stencilToUnorm8(texData, redTex);

			compareOk = verifyTextureResult(m_testCtx, result, redTex, &texCoord[0], sampleParams, lookupPrec, lodPrec, tcu::PixelFormat(8, 8, 8, 8));

			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
									compareOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}

private:
	const deUint32 m_format;
};

class RenderTex2DCase : public TestCase
{
public:
	RenderTex2DCase (Context& context, const char* name, deUint32 format)
		: TestCase	(context, name, glu::getTextureFormatName(format))
		, m_format	(format)
	{
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
		const glw::Functions&		gl				= renderCtx.getFunctions();
		const int					width			= 117;
		const int					height			= 193;
		glu::Framebuffer			fbo				(renderCtx);
		glu::Renderbuffer			colorBuf		(renderCtx);
		glu::Texture				depthStencilTex	(renderCtx);
		TextureLevel				result			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
		TextureLevel				reference		(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);

		checkDepthStencilFormatSupport(m_context, m_format);

		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);

		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);

		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
		checkFramebufferStatus(gl);

		drawTestPattern(renderCtx, width, height);

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
		checkFramebufferStatus(gl);

		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
		glu::readPixels(renderCtx, 0, 0, result.getAccess());

		renderTestPatternReference(reference);

		{
			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
									compareOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}

private:
	const deUint32 m_format;
};

class ClearTex2DCase : public TestCase
{
public:
	ClearTex2DCase (Context& context, const char* name, deUint32 format)
		: TestCase	(context, name, glu::getTextureFormatName(format))
		, m_format	(format)
	{
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
		const glw::Functions&		gl				= renderCtx.getFunctions();
		const int					width			= 125;
		const int					height			= 117;
		const int					cellSize		= 8;
		glu::Framebuffer			fbo				(renderCtx);
		glu::Renderbuffer			colorBuf		(renderCtx);
		glu::Texture				depthStencilTex	(renderCtx);
		TextureLevel				result			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
		TextureLevel				reference		(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);

		checkDepthStencilFormatSupport(m_context, m_format);

		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);

		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);

		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
		checkFramebufferStatus(gl);

		gl.enable(GL_SCISSOR_TEST);

		for (int y = 0; y < height; y += cellSize)
		{
			for (int x = 0; x < width; x += cellSize)
			{
				const int		clearW		= de::min(cellSize, width-x);
				const int		clearH		= de::min(cellSize, height-y);
				const int		stencil		= int((deInt32Hash(x) ^ deInt32Hash(y)) & 0xff);

				gl.clearStencil(stencil);
				gl.scissor(x, y, clearW, clearH);
				gl.clear(GL_STENCIL_BUFFER_BIT);

				tcu::clearStencil(tcu::getSubregion(reference.getAccess(), x, y, clearW, clearH), stencil);
			}
		}

		gl.disable(GL_SCISSOR_TEST);

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
		checkFramebufferStatus(gl);

		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
		glu::readPixels(renderCtx, 0, 0, result.getAccess());

		{
			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
									compareOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}

private:
	const deUint32 m_format;
};

class CompareModeCase : public TestCase
{
public:
	CompareModeCase (Context& context, const char* name, deUint32 format)
		: TestCase	(context, name, glu::getTextureFormatName(format))
		, m_format	(format)
	{
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
		const glw::Functions&		gl					= renderCtx.getFunctions();
		const int					width				= 64;
		const int					height				= 64;
		glu::Framebuffer			fbo					(renderCtx);
		glu::Renderbuffer			colorBuf			(renderCtx);
		glu::Texture				depthStencilTex		(renderCtx);
		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height);
		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);

		checkDepthStencilFormatSupport(m_context, m_format);

		m_testCtx.getLog() << TestLog::Message << "NOTE: Texture compare mode has no effect when reading stencil values." << TestLog::EndMessage;

		renderTestPatternReference(uploadLevel);
		renderTestPatternReference(stencilOnlyLevel);

		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
		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);
		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);

		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
		checkFramebufferStatus(gl);

		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
		glu::readPixels(renderCtx, 0, 0, readLevel);

		{
			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
									compareOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}

private:
	const deUint32 m_format;
};

class BaseLevelCase : public TestCase
{
public:
	BaseLevelCase (Context& context, const char* name, deUint32 format)
		: TestCase	(context, name, glu::getTextureFormatName(format))
		, m_format	(format)
	{
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
		const glw::Functions&		gl					= renderCtx.getFunctions();
		const int					width				= 128;
		const int					height				= 128;
		const int					levelNdx			= 2;
		const int					levelWidth			= width>>levelNdx;
		const int					levelHeight			= height>>levelNdx;
		glu::Framebuffer			fbo					(renderCtx);
		glu::Renderbuffer			colorBuf			(renderCtx);
		glu::Texture				depthStencilTex		(renderCtx);
		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), levelWidth, levelHeight);
		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), levelWidth, levelHeight);
		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), levelWidth, levelHeight);

		checkDepthStencilFormatSupport(m_context, m_format);

		m_testCtx.getLog() << TestLog::Message << "GL_TEXTURE_BASE_LEVEL = " << levelNdx << TestLog::EndMessage;

		renderTestPatternReference(uploadLevel);
		renderTestPatternReference(stencilOnlyLevel);

		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
		gl.texStorage2D(GL_TEXTURE_2D, deLog2Floor32(de::max(width, height))+1, m_format, width, height);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, levelNdx);
		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, levelNdx, 0, 0, uploadLevel);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, levelWidth, levelHeight);

		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
		checkFramebufferStatus(gl);

		blitStencilToColor2D(renderCtx, *depthStencilTex, levelWidth, levelHeight);
		glu::readPixels(renderCtx, 0, 0, readLevel);

		{
			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
									compareOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}

private:
	const deUint32 m_format;
};

} // anonymous

StencilTexturingTests::StencilTexturingTests (Context& context)
	: TestCaseGroup(context, "stencil_texturing", "Stencil texturing tests")
{
}

StencilTexturingTests::~StencilTexturingTests (void)
{
}

void StencilTexturingTests::init (void)
{
	// .format
	{
		tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Formats");
		addChild(formatGroup);

		formatGroup->addChild(new UploadTex2DCase		(m_context, "depth32f_stencil8_2d",			GL_DEPTH32F_STENCIL8));
		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "depth32f_stencil8_2d_array",	GL_DEPTH32F_STENCIL8));
		formatGroup->addChild(new UploadTexCubeCase		(m_context, "depth32f_stencil8_cube",		GL_DEPTH32F_STENCIL8));
		formatGroup->addChild(new UploadTex2DCase		(m_context, "depth24_stencil8_2d",			GL_DEPTH24_STENCIL8));
		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "depth24_stencil8_2d_array",	GL_DEPTH24_STENCIL8));
		formatGroup->addChild(new UploadTexCubeCase		(m_context, "depth24_stencil8_cube",		GL_DEPTH24_STENCIL8));

		// OES_texture_stencil8
		formatGroup->addChild(new UploadTex2DCase		(m_context, "stencil_index8_2d",			GL_STENCIL_INDEX8));
		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "stencil_index8_2d_array",		GL_STENCIL_INDEX8));
		formatGroup->addChild(new UploadTexCubeCase		(m_context, "stencil_index8_cube",			GL_STENCIL_INDEX8));
	}

	// .render
	{
		tcu::TestCaseGroup* const readRenderGroup = new tcu::TestCaseGroup(m_testCtx, "render", "Read rendered stencil values");
		addChild(readRenderGroup);

		readRenderGroup->addChild(new ClearTex2DCase	(m_context, "depth32f_stencil8_clear",	GL_DEPTH32F_STENCIL8));
		readRenderGroup->addChild(new RenderTex2DCase	(m_context, "depth32f_stencil8_draw",	GL_DEPTH32F_STENCIL8));
		readRenderGroup->addChild(new ClearTex2DCase	(m_context, "depth24_stencil8_clear",	GL_DEPTH24_STENCIL8));
		readRenderGroup->addChild(new RenderTex2DCase	(m_context, "depth24_stencil8_draw",	GL_DEPTH24_STENCIL8));
	}

	// .misc
	{
		tcu::TestCaseGroup* const miscGroup = new tcu::TestCaseGroup(m_testCtx, "misc", "Misc cases");
		addChild(miscGroup);

		miscGroup->addChild(new CompareModeCase	(m_context, "compare_mode_effect",	GL_DEPTH24_STENCIL8));
		miscGroup->addChild(new BaseLevelCase	(m_context, "base_level",			GL_DEPTH24_STENCIL8));
	}
}

} // Functional
} // gles31
} // deqp
