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

#include "es3fDepthStencilTests.hpp"
#include "glsFragmentOpUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"
#include "tcuSurface.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTextureUtil.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deMemory.h"
#include "deString.h"
#include "rrFragmentOperations.hpp"
#include "sglrReferenceUtils.hpp"

#include <algorithm>
#include <sstream>

#include "glw.h"

namespace deqp
{
namespace gles3
{
namespace Functional
{

using std::vector;
using tcu::IVec2;
using tcu::Vec2;
using tcu::Vec4;
using tcu::TestLog;
using std::ostringstream;

enum
{
	VIEWPORT_WIDTH			= 4*3*4,
	VIEWPORT_HEIGHT			= 4*12,

	NUM_RANDOM_CASES		= 25,
	NUM_RANDOM_SUB_CASES	= 10
};

namespace DepthStencilCaseUtil
{

struct StencilParams
{
	deUint32	function;
	int			reference;
	deUint32	compareMask;

	deUint32	stencilFailOp;
	deUint32	depthFailOp;
	deUint32	depthPassOp;

	deUint32	writeMask;

	StencilParams (void)
		: function		(0)
		, reference		(0)
		, compareMask	(0)
		, stencilFailOp	(0)
		, depthFailOp	(0)
		, depthPassOp	(0)
		, writeMask		(0)
	{
	}
};

struct DepthStencilParams
{
	rr::FaceType	visibleFace;			//!< Quad visible face.

	bool			stencilTestEnabled;
	StencilParams	stencil[rr::FACETYPE_LAST];

	bool			depthTestEnabled;
	deUint32		depthFunc;
	float			depth;
	bool			depthWriteMask;

	DepthStencilParams (void)
		: visibleFace			(rr::FACETYPE_LAST)
		, stencilTestEnabled	(false)
		, depthTestEnabled		(false)
		, depthFunc				(0)
		, depth					(0.0f)
		, depthWriteMask		(false)
	{
	}
};

tcu::TestLog& operator<< (tcu::TestLog& log, const StencilParams& params)
{
	log << TestLog::Message << "  func = " << glu::getCompareFuncStr(params.function) << "\n"
							<< "  ref = " << params.reference << "\n"
							<< "  compare mask = " << tcu::toHex(params.compareMask) << "\n"
							<< "  stencil fail = " << glu::getStencilOpStr(params.stencilFailOp) << "\n"
							<< "  depth fail = " << glu::getStencilOpStr(params.depthFailOp) << "\n"
							<< "  depth pass = " << glu::getStencilOpStr(params.depthPassOp) << "\n"
							<< "  write mask = " << tcu::toHex(params.writeMask) << "\n"
		<< TestLog::EndMessage;
	return log;
}

tcu::TestLog& operator<< (tcu::TestLog& log, const DepthStencilParams& params)
{
	log << TestLog::Message << "Stencil test: " << (params.stencilTestEnabled ? "enabled" : "disabled") << TestLog::EndMessage;
	if (params.stencilTestEnabled)
	{
		log << TestLog::Message << "Front-face stencil state: " << TestLog::EndMessage;
		log << params.stencil[rr::FACETYPE_FRONT];

		log << TestLog::Message << "Back-face stencil state: " << TestLog::EndMessage;
		log << params.stencil[rr::FACETYPE_BACK];
	}

	log << TestLog::Message << "Depth test: " << (params.depthTestEnabled ? "enabled" : "disabled") << TestLog::EndMessage;
	if (params.depthTestEnabled)
	{
		log << TestLog::Message << "  func = " << glu::getCompareFuncStr(params.depthFunc) << "\n"
								   "  depth value = " << params.depth << "\n"
								   "  write mask = " << (params.depthWriteMask ? "true" : "false") << "\n"
			<< TestLog::EndMessage;
	}

	log << TestLog::Message << "Triangles are " << (params.visibleFace == rr::FACETYPE_FRONT ? "front" : "back") << "-facing" << TestLog::EndMessage;

	return log;
}

struct ClearCommand
{
	rr::WindowRectangle	rect;
	deUint32			buffers;
	tcu::Vec4			color;
	int					stencil;
	// \note No depth here - don't use clears for setting depth values; use quad rendering instead. Cleared depths are in [0, 1] to begin with,
	//		 whereas rendered depths are given in [-1, 1] and then mapped to [0, 1]; this discrepancy could cause precision issues in depth tests.

	ClearCommand (void)
		: rect		(0, 0, 0, 0)
		, buffers	(0)
		, stencil	(0)
	{
	}

	ClearCommand (const rr::WindowRectangle&	rect_,
				  deUint32						buffers_,
				  const tcu::Vec4&				color_,
				  int							stencil_)
		: rect		(rect_)
		, buffers	(buffers_)
		, color		(color_)
		, stencil	(stencil_)
	{
	}
};

struct RenderCommand
{
	DepthStencilParams		params;
	rr::WindowRectangle		rect;
	tcu::Vec4				color;
	tcu::BVec4				colorMask;

	RenderCommand (void)
		: rect(0, 0, 0, 0)
	{
	}
};

struct RefRenderCommand
{
	gls::FragmentOpUtil::IntegerQuad	quad;
	rr::FragmentOperationState			state;
};

struct TestRenderTarget
{
	int		width;
	int		height;
	int		depthBits;
	int		stencilBits;

	TestRenderTarget (int width_,
					  int height_,
					  int depthBits_,
					  int stencilBits_)
		: width			(width_)
		, height		(height_)
		, depthBits		(depthBits_)
		, stencilBits	(stencilBits_)
	{
	}

	TestRenderTarget (void)
		: width			(0)
		, height		(0)
		, depthBits		(0)
		, stencilBits	(0)
	{
	}
};

void getStencilTestValues (int stencilBits, int numValues, int* values)
{
	int numLowest		= numValues/2;
	int	numHighest		= numValues-numLowest;
	int	maxVal			= (1<<stencilBits)-1;

	for (int ndx = 0; ndx < numLowest; ndx++)
		values[ndx] = ndx;

	for (int ndx = 0; ndx < numHighest; ndx++)
		values[numValues-ndx-1] = maxVal-ndx;
}

void generateBaseClearAndDepthCommands (const TestRenderTarget& target, vector<ClearCommand>& clearCommands, vector<RenderCommand>& renderCommands)
{
	DE_ASSERT(clearCommands.empty());
	DE_ASSERT(renderCommands.empty());

	const int		numL0CellsX		= 4;
	const int		numL0CellsY		= 4;
	const int		numL1CellsX		= 3;
	const int		numL1CellsY		= 1;
	int				cellL0Width		= target.width/numL0CellsX;
	int				cellL0Height	= target.height/numL0CellsY;
	int				cellL1Width		= cellL0Width/numL1CellsX;
	int				cellL1Height	= cellL0Height/numL1CellsY;

	int				stencilValues[numL0CellsX*numL0CellsY];
	float			depthValues[numL1CellsX*numL1CellsY];

	if (cellL0Width <= 0 || cellL1Width <= 0 || cellL0Height <= 0 || cellL1Height <= 0)
		throw tcu::NotSupportedError("Too small render target");

	// Fullscreen clear to black.
	clearCommands.push_back(ClearCommand(rr::WindowRectangle(0, 0, target.width, target.height), GL_COLOR_BUFFER_BIT, Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0));

	// Compute stencil values: numL0CellsX*numL0CellsY combinations of lowest and highest bits.
	getStencilTestValues(target.stencilBits, numL0CellsX*numL0CellsY, &stencilValues[0]);

	// Compute depth values
	{
		int		numValues		= DE_LENGTH_OF_ARRAY(depthValues);
		float	depthStep		= 2.0f/(float)(numValues-1);

		for (int ndx = 0; ndx < numValues; ndx++)
			depthValues[ndx] = -1.0f + depthStep*(float)ndx;
	}

	for (int y0 = 0; y0 < numL0CellsY; y0++)
	{
		for (int x0 = 0; x0 < numL0CellsX; x0++)
		{
			int stencilValue = stencilValues[y0*numL0CellsX + x0];

			for (int y1 = 0; y1 < numL1CellsY; y1++)
			{
				for (int x1 = 0; x1 < numL1CellsX; x1++)
				{
					int					x			= x0*cellL0Width + x1*cellL1Width;
					int					y			= y0*cellL0Height + y1*cellL1Height;
					rr::WindowRectangle	cellL1Rect	(x, y, cellL1Width, cellL1Height);

					clearCommands.push_back(ClearCommand(cellL1Rect, GL_STENCIL_BUFFER_BIT, Vec4(0), stencilValue));

					RenderCommand renderCmd;
					renderCmd.params.visibleFace		= rr::FACETYPE_FRONT;
					renderCmd.params.depth				= depthValues[y1*numL1CellsX + x1];
					renderCmd.params.depthTestEnabled	= true;
					renderCmd.params.depthFunc			= GL_ALWAYS;
					renderCmd.params.depthWriteMask		= true;
					renderCmd.colorMask					= tcu::BVec4(false);
					renderCmd.rect						= cellL1Rect;

					renderCommands.push_back(renderCmd);
				}
			}
		}
	}
}

void generateDepthVisualizeCommands (const TestRenderTarget& target, vector<RenderCommand>& commands)
{
	const float			epsilon			= -0.05f;
	static const float	depthSteps[]	= {-1.0f, -0.5f, 0.0f, 0.5f, 1.0f};
	int					numSteps		= DE_LENGTH_OF_ARRAY(depthSteps);
	const float			colorStep		= 1.0f / (float)(numSteps-1);

	for (int ndx = 0; ndx < numSteps; ndx++)
	{
		RenderCommand cmd;

		cmd.params.visibleFace		= rr::FACETYPE_FRONT;
		cmd.rect					= rr::WindowRectangle(0, 0, target.width, target.height);
		cmd.color					= Vec4(0.0f, 0.0f, colorStep*(float)ndx, 0.0f);
		cmd.colorMask				= tcu::BVec4(false, false, true, false);
		cmd.params.depth			= depthSteps[ndx]+epsilon;
		cmd.params.depthTestEnabled	= true;
		cmd.params.depthFunc		= GL_LESS;
		cmd.params.depthWriteMask	= false;

		commands.push_back(cmd);
	}
}

void generateStencilVisualizeCommands (const TestRenderTarget& target, vector<RenderCommand>& commands)
{
	const int	numValues		= 4*4;
	float		colorStep		= 1.0f / numValues; // 0 is reserved for non-matching.
	int			stencilValues[numValues];

	getStencilTestValues(target.stencilBits, numValues, &stencilValues[0]);

	for (int ndx = 0; ndx < numValues; ndx++)
	{
		RenderCommand cmd;

		cmd.params.visibleFace							= rr::FACETYPE_FRONT;
		cmd.rect										= rr::WindowRectangle(0, 0, target.width, target.height);
		cmd.color										= Vec4(0.0f, colorStep*float(ndx+1), 0.0f, 0.0f);
		cmd.colorMask									= tcu::BVec4(false, true, false, false);
		cmd.params.stencilTestEnabled					= true;

		cmd.params.stencil[rr::FACETYPE_FRONT].function			= GL_EQUAL;
		cmd.params.stencil[rr::FACETYPE_FRONT].reference		= stencilValues[ndx];
		cmd.params.stencil[rr::FACETYPE_FRONT].compareMask		= ~0u;
		cmd.params.stencil[rr::FACETYPE_FRONT].stencilFailOp	= GL_KEEP;
		cmd.params.stencil[rr::FACETYPE_FRONT].depthFailOp		= GL_KEEP;
		cmd.params.stencil[rr::FACETYPE_FRONT].depthPassOp		= GL_KEEP;
		cmd.params.stencil[rr::FACETYPE_FRONT].writeMask		= 0u;

		cmd.params.stencil[rr::FACETYPE_BACK] = cmd.params.stencil[rr::FACETYPE_FRONT];

		commands.push_back(cmd);
	}
}

void translateStencilState (const StencilParams& src, rr::StencilState& dst)
{
	dst.func		= sglr::rr_util::mapGLTestFunc(src.function);
	dst.ref			= src.reference;
	dst.compMask	= src.compareMask;
	dst.sFail		= sglr::rr_util::mapGLStencilOp(src.stencilFailOp);
	dst.dpFail		= sglr::rr_util::mapGLStencilOp(src.depthFailOp);
	dst.dpPass		= sglr::rr_util::mapGLStencilOp(src.depthPassOp);
	dst.writeMask	= src.writeMask;
}

void translateCommand (const RenderCommand& src, RefRenderCommand& dst, const TestRenderTarget& renderTarget)
{
	const float		far				= 1.0f;
	const float		near			= 0.0f;
	bool			hasDepth		= renderTarget.depthBits > 0;
	bool			hasStencil		= renderTarget.stencilBits > 0;
	bool			isFrontFacing	= src.params.visibleFace == rr::FACETYPE_FRONT;

	dst.quad.posA = IVec2(isFrontFacing ? src.rect.left : (src.rect.left+src.rect.width-1), src.rect.bottom);
	dst.quad.posB = IVec2(isFrontFacing ? (src.rect.left+src.rect.width-1) : src.rect.left, src.rect.bottom+src.rect.height-1);

	std::fill(DE_ARRAY_BEGIN(dst.quad.color), DE_ARRAY_END(dst.quad.color), src.color);
	std::fill(DE_ARRAY_BEGIN(dst.quad.depth), DE_ARRAY_END(dst.quad.depth), ((far-near)/2.0f) * src.params.depth + (near+far)/2.0f);

	dst.state.colorMask = src.colorMask;

	dst.state.scissorTestEnabled		= false;
	dst.state.stencilTestEnabled		= hasStencil && src.params.stencilTestEnabled;
	dst.state.depthTestEnabled			= hasDepth && src.params.depthTestEnabled;
	dst.state.blendMode					= rr::BLENDMODE_NONE;
	dst.state.numStencilBits			= renderTarget.stencilBits;

	if (dst.state.depthTestEnabled)
	{
		dst.state.depthFunc					= sglr::rr_util::mapGLTestFunc(src.params.depthFunc);
		dst.state.depthMask					= src.params.depthWriteMask;
	}

	if (dst.state.stencilTestEnabled)
	{
		translateStencilState(src.params.stencil[rr::FACETYPE_BACK],	dst.state.stencilStates[rr::FACETYPE_BACK]);
		translateStencilState(src.params.stencil[rr::FACETYPE_FRONT],	dst.state.stencilStates[rr::FACETYPE_FRONT]);
	}
}

void render (const vector<ClearCommand>& clears, int viewportX, int viewportY)
{
	glEnable(GL_SCISSOR_TEST);

	for (int ndx = 0; ndx < (int)clears.size(); ndx++)
	{
		const ClearCommand& clear = clears[ndx];

		if (clear.buffers & GL_COLOR_BUFFER_BIT)	glClearColor(clear.color.x(), clear.color.y(), clear.color.z(), clear.color.w());
		if (clear.buffers & GL_STENCIL_BUFFER_BIT)	glClearStencil(clear.stencil);

		DE_ASSERT(clear.buffers == (clear.buffers & (GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))); // \note Don't use clear for depths.

		glScissor(clear.rect.left+viewportX, clear.rect.bottom+viewportY, clear.rect.width, clear.rect.height);
		glClear(clear.buffers);
	}

	glDisable(GL_SCISSOR_TEST);
}

void render (gls::FragmentOpUtil::QuadRenderer& renderer, const RenderCommand& command, int viewportX, int viewportY)
{
	if (command.params.stencilTestEnabled)
	{
		glEnable(GL_STENCIL_TEST);

		for (int face = 0; face < rr::FACETYPE_LAST; face++)
		{
			deUint32				glFace	= face == rr::FACETYPE_BACK ? GL_BACK : GL_FRONT;
			const StencilParams&	sParams	= command.params.stencil[face];

			glStencilFuncSeparate(glFace, sParams.function, sParams.reference, sParams.compareMask);
			glStencilOpSeparate(glFace, sParams.stencilFailOp, sParams.depthFailOp, sParams.depthPassOp);
			glStencilMaskSeparate(glFace, sParams.writeMask);
		}
	}
	else
		glDisable(GL_STENCIL_TEST);

	if (command.params.depthTestEnabled)
	{
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(command.params.depthFunc);
		glDepthMask(command.params.depthWriteMask ? GL_TRUE : GL_FALSE);
	}
	else
		glDisable(GL_DEPTH_TEST);

	glColorMask(command.colorMask[0] ? GL_TRUE : GL_FALSE,
				command.colorMask[1] ? GL_TRUE : GL_FALSE,
				command.colorMask[2] ? GL_TRUE : GL_FALSE,
				command.colorMask[3] ? GL_TRUE : GL_FALSE);
	glViewport(command.rect.left+viewportX, command.rect.bottom+viewportY, command.rect.width, command.rect.height);

	gls::FragmentOpUtil::Quad quad;

	bool isFrontFacing = command.params.visibleFace == rr::FACETYPE_FRONT;
	quad.posA = Vec2(isFrontFacing ? -1.0f :  1.0f, -1.0f);
	quad.posB = Vec2(isFrontFacing ?  1.0f : -1.0f,  1.0f);

	std::fill(DE_ARRAY_BEGIN(quad.color), DE_ARRAY_END(quad.color), command.color);
	std::fill(DE_ARRAY_BEGIN(quad.depth), DE_ARRAY_END(quad.depth), command.params.depth);

	renderer.render(quad);
	GLU_CHECK();
}

void renderReference (const vector<ClearCommand>& clears, const tcu::PixelBufferAccess& dstColor, const tcu::PixelBufferAccess& dstStencil, int stencilBits)
{
	for (int ndx = 0; ndx < (int)clears.size(); ndx++)
	{
		const ClearCommand& clear = clears[ndx];

		if (clear.buffers & GL_COLOR_BUFFER_BIT)
			tcu::clear(tcu::getSubregion(dstColor, clear.rect.left, clear.rect.bottom, clear.rect.width, clear.rect.height), clear.color);

		if (clear.buffers & GL_STENCIL_BUFFER_BIT && stencilBits > 0)
		{
			int maskedVal = clear.stencil & ((1<<stencilBits)-1);
			tcu::clearStencil(tcu::getSubregion(dstStencil, clear.rect.left, clear.rect.bottom, clear.rect.width, clear.rect.height), maskedVal);
		}

		DE_ASSERT(clear.buffers == (clear.buffers & (GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))); // \note Don't use clear for depths.
	}
}

} // DepthStencilCaseUtil

using namespace DepthStencilCaseUtil;

class DepthStencilCase : public TestCase
{
public:
							DepthStencilCase		(Context& context, const char* name, const char* desc, const std::vector<DepthStencilParams>& cases);
							~DepthStencilCase		(void);

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

	IterateResult			iterate					(void);

private:
							DepthStencilCase		(const DepthStencilCase& other);
	DepthStencilCase&		operator=				(const DepthStencilCase& other);

	std::vector<DepthStencilParams>					m_cases;

	TestRenderTarget								m_renderTarget;
	std::vector<ClearCommand>						m_baseClears;
	std::vector<RenderCommand>						m_baseDepthRenders;
	std::vector<RenderCommand>						m_visualizeCommands;
	std::vector<RefRenderCommand>					m_refBaseDepthRenders;
	std::vector<RefRenderCommand>					m_refVisualizeCommands;

	gls::FragmentOpUtil::QuadRenderer*				m_renderer;
	tcu::Surface*									m_refColorBuffer;
	tcu::TextureLevel*								m_refDepthBuffer;
	tcu::TextureLevel*								m_refStencilBuffer;
	gls::FragmentOpUtil::ReferenceQuadRenderer*		m_refRenderer;

	int												m_iterNdx;
};

DepthStencilCase::DepthStencilCase (Context& context, const char* name, const char* desc, const std::vector<DepthStencilParams>& cases)
	: TestCase				(context, name, desc)
	, m_cases				(cases)
	, m_renderer			(DE_NULL)
	, m_refColorBuffer		(DE_NULL)
	, m_refDepthBuffer		(DE_NULL)
	, m_refStencilBuffer	(DE_NULL)
	, m_refRenderer			(DE_NULL)
	, m_iterNdx				(0)
{
}

DepthStencilCase::~DepthStencilCase (void)
{
	delete m_renderer;
	delete m_refColorBuffer;
	delete m_refDepthBuffer;
	delete m_refStencilBuffer;
	delete m_refRenderer;
}

void DepthStencilCase::init (void)
{
	DE_ASSERT(!m_renderer && !m_refColorBuffer && !m_refDepthBuffer && !m_refStencilBuffer && !m_refRenderer);

	// Compute render target.
	int viewportW	= de::min<int>(m_context.getRenderTarget().getWidth(), VIEWPORT_WIDTH);
	int viewportH	= de::min<int>(m_context.getRenderTarget().getHeight(), VIEWPORT_HEIGHT);
	m_renderTarget	= TestRenderTarget(viewportW, viewportH, m_context.getRenderTarget().getDepthBits(), m_context.getRenderTarget().getStencilBits());

	// Compute base clears & visualization commands.
	generateBaseClearAndDepthCommands(m_renderTarget, m_baseClears, m_baseDepthRenders);
	generateDepthVisualizeCommands(m_renderTarget, m_visualizeCommands);
	generateStencilVisualizeCommands(m_renderTarget, m_visualizeCommands);

	// Translate to ref commands.
	m_refBaseDepthRenders.resize(m_baseDepthRenders.size());
	for (int ndx = 0; ndx < (int)m_baseDepthRenders.size(); ndx++)
		translateCommand(m_baseDepthRenders[ndx], m_refBaseDepthRenders[ndx], m_renderTarget);

	m_refVisualizeCommands.resize(m_visualizeCommands.size());
	for (int ndx = 0; ndx < (int)m_visualizeCommands.size(); ndx++)
		translateCommand(m_visualizeCommands[ndx], m_refVisualizeCommands[ndx], m_renderTarget);

	m_renderer			= new gls::FragmentOpUtil::QuadRenderer(m_context.getRenderContext(), glu::GLSL_VERSION_300_ES);
	m_refColorBuffer	= new tcu::Surface(viewportW, viewportH);
	m_refDepthBuffer	= new tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT),			viewportW, viewportH);
	m_refStencilBuffer	= new tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT32),	viewportW, viewportH);
	m_refRenderer		= new gls::FragmentOpUtil::ReferenceQuadRenderer();

	m_iterNdx			= 0;
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}

void DepthStencilCase::deinit (void)
{
	delete m_renderer;
	delete m_refColorBuffer;
	delete m_refDepthBuffer;
	delete m_refStencilBuffer;
	delete m_refRenderer;

	m_renderer			= DE_NULL;
	m_refColorBuffer	= DE_NULL;
	m_refDepthBuffer	= DE_NULL;
	m_refStencilBuffer	= DE_NULL;
	m_refRenderer		= DE_NULL;

	m_baseClears.clear();
	m_baseDepthRenders.clear();
	m_visualizeCommands.clear();
	m_refBaseDepthRenders.clear();
	m_refVisualizeCommands.clear();
}

DepthStencilCase::IterateResult DepthStencilCase::iterate (void)
{
	de::Random				rnd				(deStringHash(getName()) ^ deInt32Hash(m_iterNdx));
	int						viewportX		= rnd.getInt(0, m_context.getRenderTarget().getWidth()-m_renderTarget.width);
	int						viewportY		= rnd.getInt(0, m_context.getRenderTarget().getHeight()-m_renderTarget.height);
	RenderCommand			testCmd;

	tcu::Surface			renderedImg		(m_renderTarget.width, m_renderTarget.height);
	tcu::RGBA				threshold		= m_context.getRenderTarget().getPixelFormat().getColorThreshold();

	// Fill in test command for this iteration.
	testCmd.color		= Vec4(1.0f, 0.0f, 0.0f, 1.0f);
	testCmd.colorMask	= tcu::BVec4(true);
	testCmd.rect		= rr::WindowRectangle(0, 0, m_renderTarget.width, m_renderTarget.height);
	testCmd.params		= m_cases[m_iterNdx];

	if (m_iterNdx == 0)
	{
		m_testCtx.getLog() << TestLog::Message << "Channels:\n"
													"  RED: passing pixels\n"
													"  GREEN: stencil values\n"
													"  BLUE: depth values"
							<< TestLog::EndMessage;
	}

	if (m_cases.size() > 1)
		m_testCtx.getLog() << TestLog::Message << "Iteration " << m_iterNdx << "..." << TestLog::EndMessage;

	m_testCtx.getLog() << m_cases[m_iterNdx];

	// Submit render commands to gl GL.

	// Base clears.
	render(m_baseClears, viewportX, viewportY);

	// Base depths.
	for (vector<RenderCommand>::const_iterator cmd = m_baseDepthRenders.begin(); cmd != m_baseDepthRenders.end(); ++cmd)
		render(*m_renderer, *cmd, viewportX, viewportY);

	// Test command.
	render(*m_renderer, testCmd, viewportX, viewportY);

	// Visualization commands.
	for (vector<RenderCommand>::const_iterator cmd = m_visualizeCommands.begin(); cmd != m_visualizeCommands.end(); ++cmd)
		render(*m_renderer, *cmd, viewportX, viewportY);

	// Re-enable all write masks.
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	glDepthMask(GL_TRUE);
	glStencilMask(~0u);

	// Ask GPU to start rendering.
	glFlush();

	// Render reference while GPU is doing work.
	{
		RefRenderCommand refTestCmd;
		translateCommand(testCmd, refTestCmd, m_renderTarget);

		// Base clears.
		renderReference(m_baseClears, m_refColorBuffer->getAccess(), m_refStencilBuffer->getAccess(), m_renderTarget.stencilBits);

		// Base depths.
		for (vector<RefRenderCommand>::const_iterator cmd = m_refBaseDepthRenders.begin(); cmd != m_refBaseDepthRenders.end(); ++cmd)
			m_refRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()),
								  gls::FragmentOpUtil::getMultisampleAccess(m_refDepthBuffer->getAccess()),
								  gls::FragmentOpUtil::getMultisampleAccess(m_refStencilBuffer->getAccess()),
								  cmd->quad, cmd->state);

		// Test command.
		m_refRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()),
							  gls::FragmentOpUtil::getMultisampleAccess(m_refDepthBuffer->getAccess()),
							  gls::FragmentOpUtil::getMultisampleAccess(m_refStencilBuffer->getAccess()),
							  refTestCmd.quad, refTestCmd.state);

		// Visualization commands.
		for (vector<RefRenderCommand>::const_iterator cmd = m_refVisualizeCommands.begin(); cmd != m_refVisualizeCommands.end(); ++cmd)
			m_refRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()),
								  gls::FragmentOpUtil::getMultisampleAccess(m_refDepthBuffer->getAccess()),
								  gls::FragmentOpUtil::getMultisampleAccess(m_refStencilBuffer->getAccess()),
								  cmd->quad, cmd->state);
	}

	// Read rendered image.
	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());

	m_iterNdx += 1;

	// Compare to reference.
	bool	isLastIter	= m_iterNdx >= (int)m_cases.size();
	bool	compareOk	= tcu::pixelThresholdCompare(m_testCtx.getLog(), "CompareResult", "Image Comparison Result", *m_refColorBuffer, renderedImg, threshold,
													 tcu::COMPARE_LOG_RESULT);

	m_testCtx.getLog() << TestLog::Message << (compareOk ? "  Passed." : "  FAILED!") << TestLog::EndMessage;
	if (!compareOk)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");

	if (compareOk && !isLastIter)
		return CONTINUE;
	else
		return STOP;
}

DepthStencilTests::DepthStencilTests (Context& context)
	: TestCaseGroup(context, "depth_stencil", "Depth and Stencil Op Tests")
{
}

DepthStencilTests::~DepthStencilTests (void)
{
}

static void randomDepthStencilState (de::Random& rnd, DepthStencilParams& params)
{
	const float stencilTestProbability	= 0.8f;
	const float depthTestProbability	= 0.7f;

	static const deUint32 compareFuncs[] =
	{
		GL_NEVER,
		GL_ALWAYS,
		GL_LESS,
		GL_LEQUAL,
		GL_EQUAL,
		GL_GEQUAL,
		GL_GREATER,
		GL_NOTEQUAL
	};

	static const deUint32 stencilOps[] =
	{
		GL_KEEP,
		GL_ZERO,
		GL_REPLACE,
		GL_INCR,
		GL_DECR,
		GL_INVERT,
		GL_INCR_WRAP,
		GL_DECR_WRAP
	};

	static const float depthValues[] = { -1.0f, -0.8f, -0.6f, -0.4f, -0.2f, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f };

	params.visibleFace			= rnd.getBool() ? rr::FACETYPE_FRONT : rr::FACETYPE_BACK;
	params.stencilTestEnabled	= rnd.getFloat() < stencilTestProbability;
	params.depthTestEnabled		= !params.stencilTestEnabled || (rnd.getFloat() < depthTestProbability);

	if (params.stencilTestEnabled)
	{
		for (int ndx = 0; ndx < 2; ndx++)
		{
			params.stencil[ndx].function		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(compareFuncs), DE_ARRAY_END(compareFuncs));
			params.stencil[ndx].reference		= rnd.getInt(-2, 260);
			params.stencil[ndx].compareMask		= rnd.getUint32();
			params.stencil[ndx].stencilFailOp	= rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
			params.stencil[ndx].depthFailOp		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
			params.stencil[ndx].depthPassOp		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
			params.stencil[ndx].writeMask		= rnd.getUint32();
		}
	}

	if (params.depthTestEnabled)
	{
		params.depthFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(compareFuncs), DE_ARRAY_END(compareFuncs));
		params.depth			= rnd.choose<float>(DE_ARRAY_BEGIN(depthValues), DE_ARRAY_END(depthValues));
		params.depthWriteMask	= rnd.getBool();
	}
}

void DepthStencilTests::init (void)
{
	static const struct
	{
		const char*	name;
		deUint32	func;
	} compareFuncs[] =
	{
		{ "never",		GL_NEVER	},
		{ "always",		GL_ALWAYS	},
		{ "less",		GL_LESS		},
		{ "lequal",		GL_LEQUAL	},
		{ "equal",		GL_EQUAL	},
		{ "gequal",		GL_GEQUAL	},
		{ "greater",	GL_GREATER	},
		{ "notequal",	GL_NOTEQUAL	}
	};

	static const struct
	{
		const char*	name;
		deUint32	op;
	} stencilOps[] =
	{
		{ "keep",		GL_KEEP			},
		{ "zero",		GL_ZERO			},
		{ "replace",	GL_REPLACE		},
		{ "incr",		GL_INCR			},
		{ "decr",		GL_DECR			},
		{ "invert",		GL_INVERT		},
		{ "incr_wrap",	GL_INCR_WRAP	},
		{ "decr_wrap",	GL_DECR_WRAP	}
	};

	static const struct
	{
		rr::FaceType	visibleFace;
		deUint32		sFail;
		deUint32		dFail;
		deUint32		dPass;
		int				stencilRef;
		deUint32		compareMask;
		deUint32		writeMask;
		float			depth;
	} functionCases[] =
	{
		{ rr::FACETYPE_BACK,	GL_DECR,		GL_INCR,	GL_INVERT,		4,	~0u, ~0u,	-0.7f },
		{ rr::FACETYPE_FRONT,	GL_DECR,		GL_INCR,	GL_INVERT,		2,	~0u, ~0u,	0.0f },
		{ rr::FACETYPE_BACK,	GL_DECR,		GL_INCR,	GL_INVERT,		1,	~0u, ~0u,	0.2f },
		{ rr::FACETYPE_FRONT,	GL_DECR_WRAP,	GL_INVERT,	GL_REPLACE,		4,	~0u, ~0u,	1.0f }
	};

	// All combinations of depth stencil functions.
	{
		tcu::TestCaseGroup* functionsGroup = new tcu::TestCaseGroup(m_testCtx, "stencil_depth_funcs", "Combinations of Depth and Stencil Functions");
		addChild(functionsGroup);

		for (int stencilFunc = 0; stencilFunc < DE_LENGTH_OF_ARRAY(compareFuncs)+1; stencilFunc++)
		{
			// One extra: depth test disabled.
			for (int depthFunc = 0; depthFunc < DE_LENGTH_OF_ARRAY(compareFuncs)+1; depthFunc++)
			{
				DepthStencilParams	params;
				ostringstream		name;
				bool				hasStencilFunc	= de::inBounds(stencilFunc, 0, DE_LENGTH_OF_ARRAY(compareFuncs));
				bool				hasDepthFunc	= de::inBounds(depthFunc, 0, DE_LENGTH_OF_ARRAY(compareFuncs));

				if (hasStencilFunc)
					name << "stencil_" << compareFuncs[stencilFunc].name << "_";
				else
					name << "no_stencil_";

				if (hasDepthFunc)
					name << "depth_" << compareFuncs[depthFunc].name;
				else
					name << "no_depth";

				params.depthFunc			= hasDepthFunc ? compareFuncs[depthFunc].func : 0;
				params.depthTestEnabled		= hasDepthFunc;
				params.depthWriteMask		= true;

				params.stencilTestEnabled	= hasStencilFunc;

				vector<DepthStencilParams> cases;
				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(functionCases); ndx++)
				{
					rr::FaceType	visible		= functionCases[ndx].visibleFace;
					rr::FaceType	notVisible	= visible == rr::FACETYPE_FRONT ? rr::FACETYPE_BACK : rr::FACETYPE_FRONT;

					params.depth								= functionCases[ndx].depth;
					params.visibleFace							= visible;

					params.stencil[visible].function			= hasStencilFunc ? compareFuncs[stencilFunc].func : 0;
					params.stencil[visible].reference			= functionCases[ndx].stencilRef;
					params.stencil[visible].stencilFailOp		= functionCases[ndx].sFail;
					params.stencil[visible].depthFailOp			= functionCases[ndx].dFail;
					params.stencil[visible].depthPassOp			= functionCases[ndx].dPass;
					params.stencil[visible].compareMask			= functionCases[ndx].compareMask;
					params.stencil[visible].writeMask			= functionCases[ndx].writeMask;

					params.stencil[notVisible].function			= GL_ALWAYS;
					params.stencil[notVisible].reference		= 0;
					params.stencil[notVisible].stencilFailOp	= GL_REPLACE;
					params.stencil[notVisible].depthFailOp		= GL_REPLACE;
					params.stencil[notVisible].depthPassOp		= GL_REPLACE;
					params.stencil[notVisible].compareMask		= 0u;
					params.stencil[notVisible].writeMask		= ~0u;


					cases.push_back(params);
				}

				functionsGroup->addChild(new DepthStencilCase(m_context, name.str().c_str(), "", cases));
			}
		}
	}

	static const struct
	{
		rr::FaceType	visibleFace;
		deUint32		func;
		int				ref;
		deUint32		compareMask;
		deUint32		writeMask;
	} opCombinationCases[] =
	{
		{ rr::FACETYPE_BACK,	GL_LESS,		4,		~0u,	~0u	},
		{ rr::FACETYPE_FRONT,	GL_GREATER,		2,		~0u,	~0u	},
		{ rr::FACETYPE_BACK,	GL_EQUAL,		3,		~2u,	~0u	},
		{ rr::FACETYPE_FRONT,	GL_NOTEQUAL,	1,		~0u,	~1u	}
	};

	// All combinations of stencil ops.
	{
		tcu::TestCaseGroup* opCombinationGroup = new tcu::TestCaseGroup(m_testCtx, "stencil_ops", "Stencil Op Combinations");
		addChild(opCombinationGroup);

		for (int sFail = 0; sFail < DE_LENGTH_OF_ARRAY(stencilOps); sFail++)
		{
			for (int dFail = 0; dFail < DE_LENGTH_OF_ARRAY(stencilOps); dFail++)
			{
				for (int dPass = 0; dPass < DE_LENGTH_OF_ARRAY(stencilOps); dPass++)
				{
					DepthStencilParams	params;
					ostringstream		name;

					name << stencilOps[sFail].name << "_" << stencilOps[dFail].name << "_" << stencilOps[dPass].name;

					params.depthFunc			= GL_LEQUAL;
					params.depth				= 0.0f;
					params.depthTestEnabled		= true;
					params.depthWriteMask		= true;

					params.stencilTestEnabled	= true;

					vector<DepthStencilParams> cases;
					for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(opCombinationCases); ndx++)
					{
						rr::FaceType	visible		= opCombinationCases[ndx].visibleFace;
						rr::FaceType	notVisible	= visible == rr::FACETYPE_FRONT ? rr::FACETYPE_BACK : rr::FACETYPE_FRONT;

						params.visibleFace							= visible;

						params.stencil[visible].function			= opCombinationCases[ndx].func;
						params.stencil[visible].reference			= opCombinationCases[ndx].ref;
						params.stencil[visible].stencilFailOp		= stencilOps[sFail].op;
						params.stencil[visible].depthFailOp			= stencilOps[dFail].op;
						params.stencil[visible].depthPassOp			= stencilOps[dPass].op;
						params.stencil[visible].compareMask			= opCombinationCases[ndx].compareMask;
						params.stencil[visible].writeMask			= opCombinationCases[ndx].writeMask;

						params.stencil[notVisible].function			= GL_ALWAYS;
						params.stencil[notVisible].reference		= 0;
						params.stencil[notVisible].stencilFailOp	= GL_REPLACE;
						params.stencil[notVisible].depthFailOp		= GL_REPLACE;
						params.stencil[notVisible].depthPassOp		= GL_REPLACE;
						params.stencil[notVisible].compareMask		= 0u;
						params.stencil[notVisible].writeMask		= ~0u;


						cases.push_back(params);
					}

					opCombinationGroup->addChild(new DepthStencilCase(m_context, name.str().c_str(), "", cases));
				}
			}
		}
	}

	// Write masks
	{
		tcu::TestCaseGroup* writeMaskGroup = new tcu::TestCaseGroup(m_testCtx, "write_mask", "Depth and Stencil Write Masks");
		addChild(writeMaskGroup);

		// Depth mask
		{
			DepthStencilParams params;

			params.depthFunc			= GL_LEQUAL;
			params.depth				= 0.0f;
			params.depthTestEnabled		= true;
			params.stencilTestEnabled	= true;

			params.stencil[rr::FACETYPE_FRONT].function			= GL_NOTEQUAL;
			params.stencil[rr::FACETYPE_FRONT].reference		= 1;
			params.stencil[rr::FACETYPE_FRONT].stencilFailOp	= GL_INVERT;
			params.stencil[rr::FACETYPE_FRONT].depthFailOp		= GL_INCR;
			params.stencil[rr::FACETYPE_FRONT].depthPassOp		= GL_DECR;
			params.stencil[rr::FACETYPE_FRONT].compareMask		= ~0u;
			params.stencil[rr::FACETYPE_FRONT].writeMask		= ~0u;

			params.stencil[rr::FACETYPE_BACK].function			= GL_ALWAYS;
			params.stencil[rr::FACETYPE_BACK].reference			= 0;
			params.stencil[rr::FACETYPE_BACK].stencilFailOp		= GL_REPLACE;
			params.stencil[rr::FACETYPE_BACK].depthFailOp		= GL_INVERT;
			params.stencil[rr::FACETYPE_BACK].depthPassOp		= GL_INCR;
			params.stencil[rr::FACETYPE_BACK].compareMask		= ~0u;
			params.stencil[rr::FACETYPE_BACK].writeMask		= ~0u;

			vector<DepthStencilParams> cases;

			// Case 1: front, depth write enabled
			params.visibleFace		= rr::FACETYPE_FRONT;
			params.depthWriteMask	= true;
			cases.push_back(params);

			// Case 2: front, depth write disabled
			params.visibleFace		= rr::FACETYPE_FRONT;
			params.depthWriteMask	= false;
			cases.push_back(params);

			// Case 3: back, depth write enabled
			params.visibleFace		= rr::FACETYPE_BACK;
			params.depthWriteMask	= true;
			cases.push_back(params);

			// Case 4: back, depth write disabled
			params.visibleFace		= rr::FACETYPE_BACK;
			params.depthWriteMask	= false;
			cases.push_back(params);

			writeMaskGroup->addChild(new DepthStencilCase(m_context, "depth", "Depth Write Mask", cases));
		}

		// Stencil write masks.
		{
			static const struct
			{
				rr::FaceType	visibleFace;
				deUint32		frontWriteMask;
				deUint32		backWriteMask;
			} stencilWmaskCases[] =
			{
				{ rr::FACETYPE_FRONT,	~0u,	0u		},
				{ rr::FACETYPE_FRONT,	0u,		~0u		},
				{ rr::FACETYPE_FRONT,	0xfu,	0xf0u	},
				{ rr::FACETYPE_FRONT,	0x2u,	0x4u	},
				{ rr::FACETYPE_BACK,	0u,		~0u		},
				{ rr::FACETYPE_BACK,	~0u,	0u		},
				{ rr::FACETYPE_BACK,	0xf0u,	0xfu	},
				{ rr::FACETYPE_BACK,	0x4u,	0x2u	}
			};

			DepthStencilParams params;

			params.depthFunc			= GL_LEQUAL;
			params.depth				= 0.0f;
			params.depthTestEnabled		= true;
			params.depthWriteMask		= true;
			params.stencilTestEnabled	= true;

			params.stencil[rr::FACETYPE_FRONT].function			= GL_NOTEQUAL;
			params.stencil[rr::FACETYPE_FRONT].reference		= 1;
			params.stencil[rr::FACETYPE_FRONT].stencilFailOp	= GL_INVERT;
			params.stencil[rr::FACETYPE_FRONT].depthFailOp		= GL_INCR;
			params.stencil[rr::FACETYPE_FRONT].depthPassOp		= GL_DECR;
			params.stencil[rr::FACETYPE_FRONT].compareMask		= ~0u;

			params.stencil[rr::FACETYPE_BACK].function			= GL_ALWAYS;
			params.stencil[rr::FACETYPE_BACK].reference			= 0;
			params.stencil[rr::FACETYPE_BACK].stencilFailOp		= GL_REPLACE;
			params.stencil[rr::FACETYPE_BACK].depthFailOp		= GL_INVERT;
			params.stencil[rr::FACETYPE_BACK].depthPassOp		= GL_INCR;
			params.stencil[rr::FACETYPE_BACK].compareMask		= ~0u;

			vector<DepthStencilParams> cases;
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilWmaskCases); ndx++)
			{
				params.visibleFace								= stencilWmaskCases[ndx].visibleFace;
				params.stencil[rr::FACETYPE_FRONT].writeMask	= stencilWmaskCases[ndx].frontWriteMask;
				params.stencil[rr::FACETYPE_BACK].writeMask	= stencilWmaskCases[ndx].backWriteMask;
				cases.push_back(params);
			}

			writeMaskGroup->addChild(new DepthStencilCase(m_context, "stencil", "Stencil Write Mask", cases));
		}

		// Depth & stencil write masks.
		{
			static const struct
			{
				bool			depthWriteMask;
				rr::FaceType	visibleFace;
				deUint32		frontWriteMask;
				deUint32		backWriteMask;
			} depthStencilWmaskCases[] =
			{
				{ false,	rr::FACETYPE_FRONT,		~0u,	0u		},
				{ false,	rr::FACETYPE_FRONT,		0u,		~0u		},
				{ false,	rr::FACETYPE_FRONT,		0xfu,	0xf0u	},
				{ true,		rr::FACETYPE_FRONT,		~0u,	0u		},
				{ true,		rr::FACETYPE_FRONT,		0u,		~0u		},
				{ true,		rr::FACETYPE_FRONT,		0xfu,	0xf0u	},
				{ false,	rr::FACETYPE_BACK,		0u,		~0u		},
				{ false,	rr::FACETYPE_BACK,		~0u,	0u		},
				{ false,	rr::FACETYPE_BACK,		0xf0u,	0xfu	},
				{ true,		rr::FACETYPE_BACK,		0u,		~0u		},
				{ true,		rr::FACETYPE_BACK,		~0u,	0u		},
				{ true,		rr::FACETYPE_BACK,		0xf0u,	0xfu	}
			};

			DepthStencilParams params;

			params.depthFunc			= GL_LEQUAL;
			params.depth				= 0.0f;
			params.depthTestEnabled		= true;
			params.depthWriteMask		= true;
			params.stencilTestEnabled	= true;

			params.stencil[rr::FACETYPE_FRONT].function			= GL_NOTEQUAL;
			params.stencil[rr::FACETYPE_FRONT].reference		= 1;
			params.stencil[rr::FACETYPE_FRONT].stencilFailOp	= GL_INVERT;
			params.stencil[rr::FACETYPE_FRONT].depthFailOp		= GL_INCR;
			params.stencil[rr::FACETYPE_FRONT].depthPassOp		= GL_DECR;
			params.stencil[rr::FACETYPE_FRONT].compareMask		= ~0u;

			params.stencil[rr::FACETYPE_BACK].function			= GL_ALWAYS;
			params.stencil[rr::FACETYPE_BACK].reference			= 0;
			params.stencil[rr::FACETYPE_BACK].stencilFailOp		= GL_REPLACE;
			params.stencil[rr::FACETYPE_BACK].depthFailOp		= GL_INVERT;
			params.stencil[rr::FACETYPE_BACK].depthPassOp		= GL_INCR;
			params.stencil[rr::FACETYPE_BACK].compareMask		= ~0u;

			vector<DepthStencilParams> cases;
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilWmaskCases); ndx++)
			{
				params.depthWriteMask							= depthStencilWmaskCases[ndx].depthWriteMask;
				params.visibleFace								= depthStencilWmaskCases[ndx].visibleFace;
				params.stencil[rr::FACETYPE_FRONT].writeMask	= depthStencilWmaskCases[ndx].frontWriteMask;
				params.stencil[rr::FACETYPE_BACK].writeMask		= depthStencilWmaskCases[ndx].backWriteMask;
				cases.push_back(params);
			}

			writeMaskGroup->addChild(new DepthStencilCase(m_context, "both", "Depth and Stencil Write Masks", cases));
		}
	}

	// Randomized cases
	{
		tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Randomized Depth and Stencil Test Cases");
		addChild(randomGroup);

		for (int caseNdx = 0; caseNdx < NUM_RANDOM_CASES; caseNdx++)
		{
			vector<DepthStencilParams>	subCases	(NUM_RANDOM_SUB_CASES);
			de::Random					rnd			(deInt32Hash(caseNdx) ^ deInt32Hash(m_testCtx.getCommandLine().getBaseSeed()));

			for (vector<DepthStencilParams>::iterator iter = subCases.begin(); iter != subCases.end(); ++iter)
				randomDepthStencilState(rnd, *iter);

			randomGroup->addChild(new DepthStencilCase(m_context, de::toString(caseNdx).c_str(), "", subCases));
		}
	}
}

} // Functional
} // gles3
} // deqp
