/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES Utilities
 * ------------------------------------------------
 *
 * 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 OpenGL State Reset.
 *//*--------------------------------------------------------------------*/

#include "gluStateReset.hpp"
#include "gluContextInfo.hpp"
#include "gluRenderContext.hpp"
#include "tcuRenderTarget.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deUniquePtr.hpp"

namespace glu
{
namespace
{
enum
{
	MAX_ERROR_COUNT = 10
};

void resetErrors (const glw::Functions& gl)
{
	size_t errorNdx = 0;

	for (errorNdx = 0; errorNdx < MAX_ERROR_COUNT; errorNdx++)
	{
		if (gl.getError() == GL_NONE)
			break;
	}

	if (errorNdx == MAX_ERROR_COUNT)
		TCU_FAIL("Couldn't reset error state");
}

}

void resetStateES (const RenderContext& renderCtx, const ContextInfo& ctxInfo)
{
	const glw::Functions&	gl	= renderCtx.getFunctions();
	const ContextType		type	= renderCtx.getType();

	// Reset error state
	resetErrors(gl);

	DE_ASSERT(isContextTypeES(type));

	// Vertex attrib array state.
	{
		int numVertexAttribArrays = 0;
		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays);

		gl.bindBuffer	(GL_ARRAY_BUFFER,			0);
		gl.bindBuffer	(GL_ELEMENT_ARRAY_BUFFER,	0);

		if (contextSupports(type, ApiType::es(3,0)))
		{
			gl.bindVertexArray	(0);
			gl.disable			(GL_PRIMITIVE_RESTART_FIXED_INDEX);
		}

		if (contextSupports(type, ApiType::es(3,1)))
			gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);

		for (int ndx = 0; ndx < numVertexAttribArrays; ndx++)
		{
			gl.disableVertexAttribArray	(ndx);
			gl.vertexAttribPointer		(ndx, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);

			if (contextSupports(type, ApiType::es(3,0)))
				gl.vertexAttribDivisor(ndx, 0);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex attrib array state reset failed");
	}

	// Transformation state.
	{
		const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();

		gl.viewport		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
		gl.depthRangef	(0.0f, 1.0f);

		if (contextSupports(type, ApiType::es(3,0)))
			gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Transformation state reset failed");
	}

	// Rasterization state
	{
		gl.lineWidth	(1.0f);
		gl.disable		(GL_CULL_FACE);
		gl.cullFace		(GL_BACK);
		gl.frontFace	(GL_CCW);
		gl.polygonOffset(0.0f, 0.0f);
		gl.disable		(GL_POLYGON_OFFSET_FILL);

		if (contextSupports(type, ApiType::es(3,0)))
			gl.disable(GL_RASTERIZER_DISCARD);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Rasterization state reset failed");
	}

	// Multisampling state
	{
		gl.disable			(GL_SAMPLE_ALPHA_TO_COVERAGE);
		gl.disable			(GL_SAMPLE_COVERAGE);
		gl.sampleCoverage	(1.0f, GL_FALSE);

		if (contextSupports(type, ApiType::es(3,1)))
		{
			int numSampleMaskWords = 0;
			gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &numSampleMaskWords);

			gl.disable(GL_SAMPLE_MASK);

			for (int ndx = 0; ndx < numSampleMaskWords; ndx++)
				gl.sampleMaski(ndx, ~0u);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Multisampling state reset failed");
	}

	// Texture state.
	// \todo [2013-04-08 pyry] Reset all levels?
	{
		const float	borderColor[]		= { 0.0f, 0.0f, 0.0f, 0.0f };
		int			numTexUnits			= 0;
		const bool	supportsBorderClamp	= ctxInfo.isExtensionSupported("GL_EXT_texture_border_clamp") || contextSupports(type, ApiType::es(3,2));

		gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits);

		for (int ndx = 0; ndx < numTexUnits; ndx++)
		{
			gl.activeTexture(GL_TEXTURE0 + ndx);

			// Reset 2D texture.
			gl.bindTexture(GL_TEXTURE_2D, 0);
			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,		GL_NEAREST_MIPMAP_LINEAR);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,			GL_REPEAT);

			if (contextSupports(type, ApiType::es(3,0)))
			{
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
				gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD,			-1000.0f);
				gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD,			1000.0f);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL,		0);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,		1000);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
			}

			if (contextSupports(type, ApiType::es(3,1)))
				gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);

			if (supportsBorderClamp)
				gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);

			// Reset cube map texture.
			gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_LINEAR);
			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);

			if (contextSupports(type, ApiType::es(3,0)))
			{
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
				gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD,		-1000.0f);
				gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD,		1000.0f);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL,	0);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,		1000);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
			}

			if (contextSupports(type, ApiType::es(3,1)))
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);

			if (supportsBorderClamp)
				gl.texParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);

			if (contextSupports(type, ApiType::es(3,0)))
			{
				// Reset 2D array texture.
				gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
				gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_LINEAR);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		GL_REPEAT);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
				gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
				gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

				if (supportsBorderClamp)
					gl.texParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);
			}

			if (contextSupports(type, ApiType::es(3,1)))
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);

			if (contextSupports(type, ApiType::es(3,0)))
			{
				// Reset 3D texture.
				gl.bindTexture(GL_TEXTURE_3D, 0);
				gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,		GL_NEAREST_MIPMAP_LINEAR);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,			GL_REPEAT);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
				gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD,			-1000.0f);
				gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD,			1000.0f);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL,		0);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,		1000);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

				if (supportsBorderClamp)
					gl.texParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);
			}

			if (contextSupports(type, ApiType::es(3,1)))
				gl.texParameteri(GL_TEXTURE_3D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);

			if (contextSupports(type, ApiType::es(3,1)))
			{
				// Reset multisample textures.
				gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_R,	GL_RED);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_G,	GL_GREEN);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_B,	GL_BLUE);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_A,	GL_ALPHA);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL,	0);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL,	1000);
			}

			if (ctxInfo.isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
			{
				gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
			}

			if (ctxInfo.isExtensionSupported("GL_EXT_texture_cube_map_array"))
			{
				// Reset cube array texture.
				gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER,		GL_NEAREST_MIPMAP_LINEAR);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S,			GL_REPEAT);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T,			GL_REPEAT);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
				gl.texParameterf(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_LOD,			-1000.0f);
				gl.texParameterf(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LOD,			1000.0f);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL,		0);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

				if (supportsBorderClamp)
					gl.texParameterfv(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);
			}
		}

		gl.activeTexture(GL_TEXTURE0);

		if (contextSupports(type, ApiType::es(3,0)))
		{
			for (int ndx = 0; ndx < numTexUnits; ndx++)
				gl.bindSampler(ndx, 0);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state reset failed");
	}

	// Resetting state using non-indexed variants should be enough, but some
	// implementations have bugs so we need to make sure indexed state gets
	// set back to initial values.
	if (ctxInfo.isExtensionSupported("GL_EXT_draw_buffers_indexed"))
	{
		int numDrawBuffers = 0;

		gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &numDrawBuffers);

		for (int drawBufferNdx = 0; drawBufferNdx < numDrawBuffers; drawBufferNdx++)
		{
			gl.disablei			(GL_BLEND, drawBufferNdx);
			gl.blendFunci		(drawBufferNdx, GL_ONE, GL_ZERO);
			gl.blendEquationi	(drawBufferNdx, GL_FUNC_ADD);
			gl.colorMaski		(drawBufferNdx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to reset indexed draw buffer state");
	}

	// Pixel operations.
	{
		const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();

		gl.disable		(GL_SCISSOR_TEST);
		gl.scissor		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());

		gl.disable		(GL_STENCIL_TEST);
		gl.stencilFunc	(GL_ALWAYS, 0, ~0u);
		gl.stencilOp	(GL_KEEP, GL_KEEP, GL_KEEP);

		gl.disable		(GL_DEPTH_TEST);
		gl.depthFunc	(GL_LESS);

		gl.disable		(GL_BLEND);
		gl.blendFunc	(GL_ONE, GL_ZERO);
		gl.blendEquation(GL_FUNC_ADD);
		gl.blendColor	(0.0f, 0.0f, 0.0f, 0.0f);

		gl.enable		(GL_DITHER);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed");
	}

	// Framebuffer control.
	{
		gl.colorMask		(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		gl.depthMask		(GL_TRUE);
		gl.stencilMask		(~0u);

		gl.clearColor		(0.0f, 0.0f, 0.0f, 0.0f);
		gl.clearDepthf		(1.0f);
		gl.clearStencil		(0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer control state reset failed");
	}

	// Framebuffer state.
	{
		// \note Actually spec explictly says 0 but on some platforms (iOS) no default framebuffer exists.
		const deUint32		defaultFbo		= renderCtx.getDefaultFramebuffer();
		const deUint32		drawBuffer		= defaultFbo != 0 ? GL_COLOR_ATTACHMENT0 : GL_BACK;
		const deUint32		readBuffer		= defaultFbo != 0 ? GL_COLOR_ATTACHMENT0 : GL_BACK;

		gl.bindFramebuffer(GL_FRAMEBUFFER, defaultFbo);

		if (contextSupports(type, ApiType::es(3,0)))
		{
			gl.drawBuffers	(1, &drawBuffer);
			gl.readBuffer	(readBuffer);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer state reset failed");
	}

	// Renderbuffer state.
	{
		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Renderbuffer state reset failed");
	}

	// Pixel transfer state.
	{
		gl.pixelStorei(GL_UNPACK_ALIGNMENT,		4);
		gl.pixelStorei(GL_PACK_ALIGNMENT,		4);

		if (contextSupports(type, ApiType::es(3,0)))
		{
			gl.pixelStorei(GL_UNPACK_IMAGE_HEIGHT,	0);
			gl.pixelStorei(GL_UNPACK_SKIP_IMAGES,	0);
			gl.pixelStorei(GL_UNPACK_ROW_LENGTH,	0);
			gl.pixelStorei(GL_UNPACK_SKIP_ROWS,		0);
			gl.pixelStorei(GL_UNPACK_SKIP_PIXELS,	0);

			gl.pixelStorei(GL_PACK_ROW_LENGTH,		0);
			gl.pixelStorei(GL_PACK_SKIP_ROWS,		0);
			gl.pixelStorei(GL_PACK_SKIP_PIXELS,		0);

			gl.bindBuffer(GL_PIXEL_PACK_BUFFER,		0);
			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER,	0);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel transfer state reset failed");
	}

	// Program object state.
	{
		gl.useProgram(0);

		if (contextSupports(type, ApiType::es(3,0)))
		{
			int maxUniformBufferBindings = 0;
			gl.getIntegerv	(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
			gl.bindBuffer	(GL_UNIFORM_BUFFER,	0);

			for (int ndx = 0; ndx < maxUniformBufferBindings; ndx++)
				gl.bindBufferBase(GL_UNIFORM_BUFFER, ndx, 0);
		}

		if (contextSupports(type, ApiType::es(3,1)))
		{
			gl.bindProgramPipeline(0);

			{
				int maxAtomicCounterBufferBindings = 0;
				gl.getIntegerv	(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxAtomicCounterBufferBindings);
				gl.bindBuffer	(GL_ATOMIC_COUNTER_BUFFER, 0);

				for (int ndx = 0; ndx < maxAtomicCounterBufferBindings; ndx++)
					gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, ndx, 0);
			}

			{
				int maxShaderStorageBufferBindings = 0;
				gl.getIntegerv	(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
				gl.bindBuffer	(GL_SHADER_STORAGE_BUFFER, 0);

				for (int ndx = 0; ndx < maxShaderStorageBufferBindings; ndx++)
					gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, ndx, 0);
			}
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Program object state reset failed");
	}

	// Vertex shader state.
	{
		int numVertexAttribArrays = 0;
		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays);

		for (int ndx = 0; ndx < numVertexAttribArrays; ndx++)
			gl.vertexAttrib4f(ndx, 0.0f, 0.0f, 0.0f, 1.0f);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex shader state reset failed");
	}

	// Transform feedback state.
	if (contextSupports(type, ApiType::es(3,0)))
	{
		int				numTransformFeedbackSeparateAttribs	= 0;
		glw::GLboolean	transformFeedbackActive				= 0;
		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,	&numTransformFeedbackSeparateAttribs);
		gl.getBooleanv(GL_TRANSFORM_FEEDBACK_ACTIVE,				&transformFeedbackActive);

		if (transformFeedbackActive)
			gl.endTransformFeedback();

		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);

		for (int ndx = 0; ndx < numTransformFeedbackSeparateAttribs; ndx++)
			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ndx, 0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Transform feedback state reset failed");
	}

	// Asynchronous query state.
	if (contextSupports(type, ApiType::es(3,0)))
	{
		static const deUint32 targets[] = { GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN };

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(targets); i++)
		{
			int queryActive = 0;
			gl.getQueryiv(targets[i], GL_CURRENT_QUERY, &queryActive);

			if (queryActive != 0)
				gl.endQuery(targets[i]);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Asynchronous query state reset failed");
	}

	// Hints.
	{
		gl.hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);

		if (contextSupports(type, ApiType::es(3,0)))
			gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_DONT_CARE);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Hints reset failed");
	}

	// Compute.
	if (contextSupports(type, ApiType::es(3,1)))
	{
		gl.bindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Compute dispatch state reset failed");
	}

	// Buffer copy state.
	if (contextSupports(type, ApiType::es(3,0)))
	{
		gl.bindBuffer(GL_COPY_READ_BUFFER,	0);
		gl.bindBuffer(GL_COPY_WRITE_BUFFER,	0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer copy state reset failed");
	}

	// Images.
	if (contextSupports(type, ApiType::es(3,1)))
	{
		int numImageUnits = 0;
		gl.getIntegerv(GL_MAX_IMAGE_UNITS, &numImageUnits);

		for (int ndx = 0; ndx < numImageUnits; ndx++)
			gl.bindImageTexture(ndx, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Image state reset failed");
	}

	// Sample shading state.
	if (contextSupports(type, ApiType::es(3,1)) && ctxInfo.isExtensionSupported("GL_OES_sample_shading"))
	{
		gl.minSampleShading(0.0f);
		gl.disable(GL_SAMPLE_SHADING);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Sample shading state reset failed");
	}

	// Debug state
	if (ctxInfo.isExtensionSupported("GL_KHR_debug"))
	{
		const bool entrypointsPresent =	gl.debugMessageControl	!= DE_NULL	&&
										gl.debugMessageCallback	!= DE_NULL	&&
										gl.popDebugGroup		!= DE_NULL;

		// some drivers advertise GL_KHR_debug but give out null pointers. Silently ignore.
		if (entrypointsPresent)
		{
			int stackDepth = 0;
			gl.getIntegerv(GL_DEBUG_GROUP_STACK_DEPTH, &stackDepth);
			for (int ndx = 1; ndx < stackDepth; ++ndx)
				gl.popDebugGroup();

			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);
			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, DE_NULL, false);
			gl.debugMessageCallback(DE_NULL, DE_NULL);

			if (type.getFlags() & glu::CONTEXT_DEBUG)
				gl.enable(GL_DEBUG_OUTPUT);
			else
				gl.disable(GL_DEBUG_OUTPUT);
			gl.disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

			GLU_EXPECT_NO_ERROR(gl.getError(), "Debug state reset failed");
		}
	}

	// Primitive bounding box state.
	if (ctxInfo.isExtensionSupported("GL_EXT_primitive_bounding_box"))
	{
		gl.primitiveBoundingBox(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Primitive bounding box state reset failed");
	}

	// Tessellation state
	if (ctxInfo.isExtensionSupported("GL_EXT_tessellation_shader"))
	{
		gl.patchParameteri(GL_PATCH_VERTICES, 3);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Tessellation patch vertices state reset failed");
	}

	// Advanced coherent blending
	if (ctxInfo.isExtensionSupported("GL_KHR_blend_equation_advanced_coherent"))
	{
		gl.enable(GL_BLEND_ADVANCED_COHERENT_KHR);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Blend equation advanced coherent state reset failed");
	}

	// Texture buffer
	if (ctxInfo.isExtensionSupported("GL_EXT_texture_buffer"))
	{
		gl.bindTexture(GL_TEXTURE_BUFFER, 0);
		gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture buffer state reset failed");
	}
}

void resetStateGLCore (const RenderContext& renderCtx, const ContextInfo& ctxInfo)
{
	const glw::Functions&	gl		= renderCtx.getFunctions();
	const ContextType		type	= renderCtx.getType();

	// Reset error state
	resetErrors(gl);

	// Vertex attrib array state.
	{
		gl.bindVertexArray	(0);
		gl.bindBuffer		(GL_ARRAY_BUFFER,			0);
		gl.bindBuffer		(GL_ELEMENT_ARRAY_BUFFER,	0);

		if (contextSupports(type, ApiType::core(3,1)))
		{
			gl.disable				(GL_PRIMITIVE_RESTART);
			gl.primitiveRestartIndex(0);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex attrib array state reset failed");
	}

	// Transformation state.
	{
		const tcu::RenderTarget&	renderTarget		= renderCtx.getRenderTarget();
		int							numUserClipPlanes	= 0;

		gl.getIntegerv(GL_MAX_CLIP_DISTANCES, &numUserClipPlanes);

		gl.viewport		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
		gl.depthRange	(0.0, 1.0);

		for (int ndx = 0; ndx < numUserClipPlanes; ndx++)
			gl.disable(GL_CLIP_DISTANCE0+ndx);

		if (contextSupports(type, ApiType::core(3,2)))
			gl.disable(GL_DEPTH_CLAMP);

		//gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Transformation state reset failed");
	}

	// Coloring
	{
		gl.clampColor(GL_CLAMP_READ_COLOR, GL_FIXED_ONLY);

		if (contextSupports(type, ApiType::core(3,2)))
			gl.provokingVertex(GL_LAST_VERTEX_CONVENTION);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Coloring state reset failed");
	}

	// Rasterization state
	{
		gl.disable			(GL_RASTERIZER_DISCARD);
		gl.pointSize		(1.0f);
		gl.pointParameterf	(GL_POINT_FADE_THRESHOLD_SIZE,	1.0f);
		gl.pointParameteri	(GL_POINT_SPRITE_COORD_ORIGIN,	GL_UPPER_LEFT);
		gl.lineWidth		(1.0f);
		gl.disable			(GL_LINE_SMOOTH);
		gl.disable			(GL_CULL_FACE);
		gl.cullFace			(GL_BACK);
		gl.frontFace		(GL_CCW);
		gl.disable			(GL_POLYGON_SMOOTH);
		gl.polygonOffset	(0.0f, 0.0f);
		gl.disable			(GL_POLYGON_OFFSET_POINT);
		gl.disable			(GL_POLYGON_OFFSET_LINE);
		gl.disable			(GL_POLYGON_OFFSET_FILL);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Rasterization state reset failed");
	}

	// Multisampling state
	{
		gl.enable			(GL_MULTISAMPLE);
		gl.disable			(GL_SAMPLE_ALPHA_TO_COVERAGE);
		gl.disable			(GL_SAMPLE_ALPHA_TO_ONE);
		gl.disable			(GL_SAMPLE_COVERAGE);
		gl.sampleCoverage	(1.0f, GL_FALSE);

		if (contextSupports(type, ApiType::core(3,2)))
		{
			int numSampleMaskWords = 0;
			gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &numSampleMaskWords);

			gl.disable(GL_SAMPLE_MASK);

			for (int ndx = 0; ndx < numSampleMaskWords; ndx++)
				gl.sampleMaski(ndx, ~0u);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Multisampling state reset failed");
	}

	// Texture state.
	// \todo [2013-04-08 pyry] Reset all levels?
	{
		const float	borderColor[]	= { 0.0f, 0.0f, 0.0f, 0.0f };
		int			numTexUnits		= 0;
		gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits);

		gl.bindBuffer(GL_TEXTURE_BUFFER, 0);

		for (int ndx = 0; ndx < numTexUnits; ndx++)
		{
			gl.activeTexture(GL_TEXTURE0 + ndx);

			// Reset 1D texture.
			gl.bindTexture		(GL_TEXTURE_1D, 0);
			gl.texImage1D		(GL_TEXTURE_1D, 0, GL_RGBA, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
			gl.texParameterfv	(GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_MIN_LOD,			-1000.0f);
			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_MAX_LOD,			1000.0f);
			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_BASE_LEVEL,		0);
			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL,		1000);
			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_LOD_BIAS,		0.0f);
			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

			if (contextSupports(type, ApiType::core(3,3)))
			{
				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
			}

			// Reset 2D texture.
			gl.bindTexture		(GL_TEXTURE_2D, 0);
			gl.texImage2D		(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
			gl.texParameterfv	(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD,			-1000.0f);
			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD,			1000.0f);
			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL,		0);
			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,		1000);
			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS,		0.0f);
			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

			if (contextSupports(type, ApiType::core(3,3)))
			{
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
			}

			// Reset cube map texture.
			gl.bindTexture		(GL_TEXTURE_CUBE_MAP, 0);
			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			gl.texParameterfv	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD,		-1000.0f);
			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD,		1000.0f);
			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL,	0);
			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,		1000);
			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_LOD_BIAS,		0.0f);
			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

			if (contextSupports(type, ApiType::core(3,3)))
			{
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
			}

			// Reset 1D array texture.
			gl.bindTexture		(GL_TEXTURE_1D_ARRAY, 0);
			gl.texImage2D		(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			gl.texParameterfv	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_LOD_BIAS,		0.0f);
			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

			if (contextSupports(type, ApiType::core(3,3)))
			{
				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
			}

			// Reset 2D array texture.
			gl.bindTexture		(GL_TEXTURE_2D_ARRAY, 0);
			gl.texImage3D		(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			gl.texParameterfv	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		GL_REPEAT);
			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_LOD_BIAS,		0.0f);
			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

			if (contextSupports(type, ApiType::core(3,3)))
			{
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
			}

			// Reset 3D texture.
			gl.bindTexture		(GL_TEXTURE_3D, 0);
			gl.texImage3D		(GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
			gl.texParameterfv	(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,			GL_REPEAT);
			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD,			-1000.0f);
			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD,			1000.0f);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL,		0);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,		1000);
			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_LOD_BIAS,		0.0f);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);

			if (contextSupports(type, ApiType::core(3,3)))
			{
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
			}

			if (contextSupports(type, ApiType::core(3,1)))
			{
				// Reset rectangle texture.
				gl.bindTexture		(GL_TEXTURE_RECTANGLE, 0);
				gl.texImage2D		(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
				gl.texParameterfv	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_BASE_LEVEL,	0);
				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAX_LEVEL,	1000);
				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
				// \todo [2013-06-17 pyry] Drivers don't accept GL_MIN_LOD, GL_MAX_LOD for rectangle textures. Is that okay?

				if (contextSupports(type, ApiType::core(3,3)))
				{
					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_R,	GL_RED);
					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_G,	GL_GREEN);
					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_B,	GL_BLUE);
					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_A,	GL_ALPHA);
				}

				// Reset buffer texture.
				gl.bindTexture	(GL_TEXTURE_BUFFER, 0);
				gl.texBuffer	(GL_TEXTURE_BUFFER, GL_R8, 0);
				// \todo [2013-05-04 pyry] Which parameters apply to buffer textures?
			}

			if (contextSupports(type, ApiType::core(3,2)))
			{
				// Reset 2D multisample texture.
				gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE, 0);
				gl.texImage2DMultisample	(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_TRUE);

				// Reset 2D multisample array texture.
				gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
				gl.texImage3DMultisample	(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, GL_RGBA8, 0, 0, 0, GL_TRUE);
			}
		}

		gl.activeTexture(GL_TEXTURE0);

		if (contextSupports(type, ApiType::core(3,3)))
		{
			for (int ndx = 0; ndx < numTexUnits; ndx++)
				gl.bindSampler(ndx, 0);

			gl.disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state reset failed");
	}

	// Pixel operations.
	{
		const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();

		gl.disable		(GL_SCISSOR_TEST);
		gl.scissor		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());

		gl.disable		(GL_STENCIL_TEST);
		gl.stencilFunc	(GL_ALWAYS, 0, ~0u);
		gl.stencilOp	(GL_KEEP, GL_KEEP, GL_KEEP);

		gl.disable		(GL_DEPTH_TEST);
		gl.depthFunc	(GL_LESS);

		gl.disable		(GL_BLEND);
		gl.blendFunc	(GL_ONE, GL_ZERO);
		gl.blendEquation(GL_FUNC_ADD);
		gl.blendColor	(0.0f, 0.0f, 0.0f, 0.0f);

		gl.disable		(GL_FRAMEBUFFER_SRGB);
		gl.enable		(GL_DITHER);

		gl.disable		(GL_COLOR_LOGIC_OP);
		gl.logicOp		(GL_COPY);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed");
	}

	// Framebuffer control.
	{
		gl.colorMask		(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		gl.depthMask		(GL_TRUE);
		gl.stencilMask		(~0u);

		gl.clearColor		(0.0f, 0.0f, 0.0f, 0.0f);
		gl.clearDepth		(1.0);
		gl.clearStencil		(0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer control state reset failed");
	}

	// Framebuffer state.
	{
		// \todo [2013-04-05 pyry] Single-buffered rendering: use GL_FRONT
		deUint32	framebuffer		= renderCtx.getDefaultFramebuffer();
		deUint32	drawReadBuffer	= framebuffer == 0 ? GL_BACK : GL_COLOR_ATTACHMENT0;

		gl.bindFramebuffer	(GL_FRAMEBUFFER, renderCtx.getDefaultFramebuffer());
		gl.drawBuffer		(drawReadBuffer);
		gl.readBuffer		(drawReadBuffer);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer state reset failed");
	}

	// Renderbuffer state.
	{
		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Renderbuffer state reset failed");
	}

	// Pixel transfer state.
	{
		gl.pixelStorei	(GL_UNPACK_SWAP_BYTES,		GL_FALSE);
		gl.pixelStorei	(GL_UNPACK_LSB_FIRST,		GL_FALSE);
		gl.pixelStorei	(GL_UNPACK_IMAGE_HEIGHT,	0);
		gl.pixelStorei	(GL_UNPACK_SKIP_IMAGES,		0);
		gl.pixelStorei	(GL_UNPACK_ROW_LENGTH,		0);
		gl.pixelStorei	(GL_UNPACK_SKIP_ROWS,		0);
		gl.pixelStorei	(GL_UNPACK_SKIP_PIXELS,		0);
		gl.pixelStorei	(GL_UNPACK_ALIGNMENT,		4);

		gl.pixelStorei	(GL_PACK_SWAP_BYTES,		GL_FALSE);
		gl.pixelStorei	(GL_PACK_LSB_FIRST,			GL_FALSE);
		gl.pixelStorei	(GL_PACK_IMAGE_HEIGHT,		0);
		gl.pixelStorei	(GL_PACK_SKIP_IMAGES,		0);
		gl.pixelStorei	(GL_PACK_ROW_LENGTH,		0);
		gl.pixelStorei	(GL_PACK_SKIP_ROWS,			0);
		gl.pixelStorei	(GL_PACK_SKIP_PIXELS,		0);
		gl.pixelStorei	(GL_PACK_ALIGNMENT,			4);

		gl.bindBuffer	(GL_PIXEL_PACK_BUFFER,		0);
		gl.bindBuffer	(GL_PIXEL_UNPACK_BUFFER,	0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel transfer state reset failed");
	}

	// Program object state.
	{
		gl.useProgram(0);

		if (contextSupports(type, ApiType::core(3,1)))
		{
			int maxUniformBufferBindings = 0;
			gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);

			gl.bindBuffer(GL_UNIFORM_BUFFER, 0);

			for (int ndx = 0; ndx < maxUniformBufferBindings; ndx++)
				gl.bindBufferBase(GL_UNIFORM_BUFFER, ndx, 0);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Program object state reset failed");
	}

	// Vertex shader state.
	{
		int numVertexAttribArrays = 0;
		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays);

		for (int ndx = 0; ndx < numVertexAttribArrays; ndx++)
			gl.vertexAttrib4f(ndx, 0.0f, 0.0f, 0.0f, 1.0f);

		gl.disable(GL_VERTEX_PROGRAM_POINT_SIZE);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex shader state reset failed");
	}

	// Transform feedback state.
	{
		int numTransformFeedbackSeparateAttribs = 0;
		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &numTransformFeedbackSeparateAttribs);

		if (contextSupports(type, ApiType::core(4,0)))
		{
			glw::GLboolean transformFeedbackActive = 0;
			gl.getBooleanv(GL_TRANSFORM_FEEDBACK_ACTIVE, &transformFeedbackActive);

			if (transformFeedbackActive)
				gl.endTransformFeedback();
		}

		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);

		for (int ndx = 0; ndx < numTransformFeedbackSeparateAttribs; ndx++)
			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ndx, 0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Transform feedback state reset failed");
	}

	// Asynchronous query state.
	{
		deUint32	queryTargets[8];
		int			numTargets		= 0;

		queryTargets[numTargets++] = GL_PRIMITIVES_GENERATED;
		queryTargets[numTargets++] = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
		queryTargets[numTargets++] = GL_SAMPLES_PASSED;

		DE_ASSERT(numTargets <= DE_LENGTH_OF_ARRAY(queryTargets));

		for (int i = 0; i < numTargets; i++)
		{
			int queryActive = 0;
			gl.getQueryiv(queryTargets[i], GL_CURRENT_QUERY, &queryActive);

			if (queryActive != 0)
				gl.endQuery(queryTargets[i]);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Asynchronous query state reset failed");
	}

	// Hints.
	{
		gl.hint(GL_LINE_SMOOTH_HINT,				GL_DONT_CARE);
		gl.hint(GL_POLYGON_SMOOTH_HINT,				GL_DONT_CARE);
		gl.hint(GL_TEXTURE_COMPRESSION_HINT,		GL_DONT_CARE);
		gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT,	GL_DONT_CARE);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Hints reset failed");
	}

	// Buffer copy state.
	if (contextSupports(type, ApiType::core(3,1)))
	{
		gl.bindBuffer(GL_COPY_READ_BUFFER,	0);
		gl.bindBuffer(GL_COPY_WRITE_BUFFER,	0);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer copy state reset failed");
	}

	// Debug state
	if (ctxInfo.isExtensionSupported("GL_KHR_debug"))
	{
		const bool entrypointsPresent =	gl.debugMessageControl	!= DE_NULL	&&
										gl.debugMessageCallback	!= DE_NULL;

		// some drivers advertise GL_KHR_debug but give out null pointers. Silently ignore.
		if (entrypointsPresent)
		{
			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);
			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, DE_NULL, false);
			gl.debugMessageCallback(DE_NULL, DE_NULL);

			if (type.getFlags() & glu::CONTEXT_DEBUG)
				gl.enable(GL_DEBUG_OUTPUT);
			else
				gl.disable(GL_DEBUG_OUTPUT);
		}
	}
}

void resetState (const RenderContext& renderCtx, const ContextInfo& ctxInfo)
{
	if (isContextTypeES(renderCtx.getType()))
		resetStateES(renderCtx, ctxInfo);
	else if (isContextTypeGLCore(renderCtx.getType()))
		resetStateGLCore(renderCtx, ctxInfo);
	else
		throw tcu::InternalError("State reset requested for unsupported context type");
}

} // glu
