/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */ /*!
 * \file
 * \brief
 */ /*-------------------------------------------------------------------*/

/**
 */ /*!
 * \file  gl4cSparseTextureTests.cpp
 * \brief Conformance tests for the GL_ARB_sparse_texture functionality.
 */ /*-------------------------------------------------------------------*/

#include "gl4cSparseTextureTests.hpp"
#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <string.h>
#include <vector>

using namespace glw;
using namespace glu;

namespace gl4cts
{

typedef std::pair<GLint, GLint> IntPair;

/** Verifies last query error and generate proper log message
 *
 * @param funcName         Verified function name
 * @param target           Target for which texture is binded
 * @param pname            Parameter name
 * @param error            Generated error code
 * @param expectedError    Expected error code
 *
 * @return Returns true if queried value is as expected, returns false otherwise
 */
bool SparseTextureUtils::verifyQueryError(std::stringstream& log, const char* funcName, GLint target, GLint pname,
										  GLint error, GLint expectedError)
{
	if (error != expectedError)
	{
		log << "QueryError [" << funcName << " return wrong error code"
			<< ", target: " << target << ", pname: " << pname << ", expected: " << expectedError
			<< ", returned: " << error << "] - ";

		return false;
	}

	return true;
}

/** Verifies last operation error and generate proper log message
 *
 * @param funcName         Verified function name
 * @param mesage           Error message
 * @param error            Generated error code
 * @param expectedError    Expected error code
 *
 * @return Returns true if queried value is as expected, returns false otherwise
 */
bool SparseTextureUtils::verifyError(std::stringstream& log, const char* funcName, GLint error, GLint expectedError)
{
	if (error != expectedError)
	{
		log << "Error [" << funcName << " return wrong error code "
			<< ", expectedError: " << expectedError << ", returnedError: " << error << "] - ";

		return false;
	}

	return true;
}

/** Get minimal depth value for target
 *
 * @param target   Texture target
 *
 * @return Returns depth value
 */
GLint SparseTextureUtils::getTargetDepth(GLint target)
{
	GLint depth;

	if (target == GL_TEXTURE_3D || target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY ||
		target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE || target == GL_TEXTURE_CUBE_MAP)
	{
		depth = 1;
	}
	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
		depth = 6;
	else
		depth = 0;

	return depth;
}

/** Queries for virtual page sizes
 *
 * @param gl           GL functions
 * @param target       Texture target
 * @param format       Texture internal format
 * @param pageSizeX    Texture page size reference for X dimension
 * @param pageSizeY    Texture page size reference for X dimension
 * @param pageSizeZ    Texture page size reference for X dimension
 **/
void SparseTextureUtils::getTexturePageSizes(const glw::Functions& gl, glw::GLint target, glw::GLint format,
											 glw::GLint& pageSizeX, glw::GLint& pageSizeY, glw::GLint& pageSizeZ)
{
	gl.getInternalformativ(target, format, GL_VIRTUAL_PAGE_SIZE_X_ARB, 1, &pageSizeX);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ error occurred for GL_VIRTUAL_PAGE_SIZE_X_ARB");

	gl.getInternalformativ(target, format, GL_VIRTUAL_PAGE_SIZE_Y_ARB, 1, &pageSizeY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ error occurred for GL_VIRTUAL_PAGE_SIZE_Y_ARB");

	gl.getInternalformativ(target, format, GL_VIRTUAL_PAGE_SIZE_Z_ARB, 1, &pageSizeZ);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ error occurred for GL_VIRTUAL_PAGE_SIZE_Z_ARB");
}

/** Calculate texture size for specific mipmap
 *
 * @param target  GL functions
 * @param state   Texture current state
 * @param level   Texture mipmap level
 * @param width   Texture output width
 * @param height  Texture output height
 * @param depth   Texture output depth
 **/
void SparseTextureUtils::getTextureLevelSize(GLint target, TextureState& state, GLint level, GLint& width,
											 GLint& height, GLint& depth)
{
	width = state.width / (int)pow(2, level);
	if (target == GL_TEXTURE_1D || target == GL_TEXTURE_1D_ARRAY)
		height = 1;
	else
		height = state.height / (int)pow(2, level);

	if (target == GL_TEXTURE_3D)
		depth = state.depth / (int)pow(2, level);
	else if (target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
		depth = state.depth;
	else
		depth = 1;
}

/* Texture static fields */
const GLuint Texture::m_invalid_id = -1;

/** Bind texture to target
 *
 * @param gl       GL API functions
 * @param id       Id of texture
 * @param tex_type Type of texture
 **/
void Texture::Bind(const Functions& gl, GLuint id, GLenum target)
{
	gl.bindTexture(target, id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
}

/** Generate texture instance
 *
 * @param gl     GL functions
 * @param out_id Id of texture
 **/
void Texture::Generate(const Functions& gl, GLuint& out_id)
{
	GLuint id = m_invalid_id;

	gl.genTextures(1, &id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");

	if (m_invalid_id == id)
	{
		TCU_FAIL("Invalid id");
	}

	out_id = id;
}

/** Delete texture instance
 *
 * @param gl    GL functions
 * @param id    Id of texture
 **/
void Texture::Delete(const Functions& gl, GLuint& id)
{
	gl.deleteTextures(1, &id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
}

/** Allocate storage for texture
 *
 * @param gl              GL functions
 * @param target          Texture target
 * @param levels          Number of levels
 * @param internal_format Internal format of texture
 * @param width           Width of texture
 * @param height          Height of texture
 * @param depth           Depth of texture
 **/
void Texture::Storage(const Functions& gl, GLenum target, GLsizei levels, GLenum internal_format, GLuint width,
					  GLuint height, GLuint depth)
{
	switch (target)
	{
	case GL_TEXTURE_1D:
		gl.texStorage1D(target, levels, internal_format, width);
		break;
	case GL_TEXTURE_1D_ARRAY:
		gl.texStorage2D(target, levels, internal_format, width, depth);
		break;
	case GL_TEXTURE_2D:
	case GL_TEXTURE_RECTANGLE:
	case GL_TEXTURE_CUBE_MAP:
		gl.texStorage2D(target, levels, internal_format, width, height);
		break;
	case GL_TEXTURE_3D:
	case GL_TEXTURE_2D_ARRAY:
	case GL_TEXTURE_CUBE_MAP_ARRAY:
		gl.texStorage3D(target, levels, internal_format, width, height, depth);
		break;
	case GL_TEXTURE_2D_MULTISAMPLE:
		gl.texStorage2DMultisample(target, levels /* samples */, internal_format, width, height, GL_TRUE);
		break;
	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
		gl.texStorage3DMultisample(target, levels /* samples */, internal_format, width, height, depth, GL_TRUE);
		break;
	default:
		TCU_FAIL("Invliad enum");
	}
}

/** Get texture data
 *
 * @param gl       GL functions
 * @param target   Texture target
 * @param format   Format of data
 * @param type     Type of data
 * @param out_data Buffer for data
 **/
void Texture::GetData(const glw::Functions& gl, glw::GLint level, glw::GLenum target, glw::GLenum format,
					  glw::GLenum type, glw::GLvoid* out_data)
{
	gl.getTexImage(target, level, format, type, out_data);
}

/** Set contents of texture
 *
 * @param gl              GL functions
 * @param target          Texture target
 * @param level           Mipmap level
 * @param x               X offset
 * @param y               Y offset
 * @param z               Z offset
 * @param width           Width of texture
 * @param height          Height of texture
 * @param depth           Depth of texture
 * @param format          Format of data
 * @param type            Type of data
 * @param pixels          Buffer with image data
 **/
void Texture::SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y,
					   glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format,
					   glw::GLenum type, const glw::GLvoid* pixels)
{
	switch (target)
	{
	case GL_TEXTURE_1D:
		gl.texSubImage1D(target, level, x, width, format, type, pixels);
		break;
	case GL_TEXTURE_1D_ARRAY:
		gl.texSubImage2D(target, level, x, y, width, depth, format, type, pixels);
		break;
	case GL_TEXTURE_2D:
	case GL_TEXTURE_RECTANGLE:
		gl.texSubImage2D(target, level, x, y, width, height, format, type, pixels);
		break;
	case GL_TEXTURE_CUBE_MAP:
		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, x, y, width, height, format, type, pixels);
		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, x, y, width, height, format, type, pixels);
		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, x, y, width, height, format, type, pixels);
		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, x, y, width, height, format, type, pixels);
		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, x, y, width, height, format, type, pixels);
		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, x, y, width, height, format, type, pixels);
		break;
	case GL_TEXTURE_3D:
	case GL_TEXTURE_2D_ARRAY:
	case GL_TEXTURE_CUBE_MAP_ARRAY:
		gl.texSubImage3D(target, level, x, y, z, width, height, depth, format, type, pixels);
		break;
	default:
		TCU_FAIL("Invliad enum");
	}
}

/** Constructor.
 *
 *  @param context     Rendering context
 */
TextureParameterQueriesTestCase::TextureParameterQueriesTestCase(deqp::Context& context)
	: TestCase(
		  context, "TextureParameterQueries",
		  "Implements all glTexParameter* and glGetTexParameter* queries tests described in CTS_ARB_sparse_texture")
{
	/* Left blank intentionally */
}

/** Stub init method */
void TextureParameterQueriesTestCase::init()
{
	mSupportedTargets.push_back(GL_TEXTURE_2D);
	mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
	mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
	mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
	mSupportedTargets.push_back(GL_TEXTURE_3D);
	mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);

	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
	{
		mNotSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
		mNotSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
	}
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult TextureParameterQueriesTestCase::iterate()
{
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
		return STOP;
	}

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

	bool result = true;

	GLuint texture;

	//Iterate through supported targets

	for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
		 ++iter)
	{
		const GLint& target = *iter;

		mLog.str("");

		Texture::Generate(gl, texture);
		Texture::Bind(gl, texture, target);

		result = testTextureSparseARB(gl, target) && testVirtualPageSizeIndexARB(gl, target) &&
				 testNumSparseLevelsARB(gl, target);

		Texture::Delete(gl, texture);

		if (!result)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail [positive tests]"
							   << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}
	}

	//Iterate through not supported targets
	for (std::vector<glw::GLint>::const_iterator iter = mNotSupportedTargets.begin();
		 iter != mNotSupportedTargets.end(); ++iter)
	{
		const GLint& target = *iter;

		mLog.str("");

		Texture::Generate(gl, texture);
		Texture::Bind(gl, texture, target);

		result = testTextureSparseARB(gl, target, GL_INVALID_VALUE);

		Texture::Delete(gl, texture);

		if (!result)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail [positive tests]"
							   << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail on negative tests");
			return STOP;
		}
	}

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

/** Testing texParameter* functions for binded texture and GL_TEXTURE_SPARSE_ARB parameter name
 *
 * @param gl               GL API functions
 * @param target           Target for which texture is binded
 * @param expectedError    Expected error code (default value GL_NO_ERROR)
 *
 * @return Returns true if queried value is as expected, returns false otherwise
 */
bool TextureParameterQueriesTestCase::testTextureSparseARB(const Functions& gl, GLint target, GLint expectedError)
{
	const GLint pname = GL_TEXTURE_SPARSE_ARB;

	bool result = true;

	GLint   testValueInt;
	GLuint  testValueUInt;
	GLfloat testValueFloat;

	mLog << "Testing TEXTURE_SPARSE_ARB for target: " << target << " - ";

	//Check getTexParameter* default value
	if (expectedError == GL_NO_ERROR)
		result = checkGetTexParameter(gl, target, pname, GL_FALSE);

	//Check getTexParameter* for manually set values
	if (result)
	{
		//Query to set parameter
		gl.texParameteri(target, pname, GL_TRUE);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
			result = checkGetTexParameter(gl, target, pname, GL_TRUE);

			//If no error verification reset TEXTURE_SPARSE_ARB value
			gl.texParameteri(target, pname, GL_FALSE);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteri", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		gl.texParameterf(target, pname, GL_TRUE);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf error occurred.");
			result = checkGetTexParameter(gl, target, pname, GL_TRUE);

			gl.texParameteri(target, pname, GL_FALSE);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterf", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		testValueInt = GL_TRUE;
		gl.texParameteriv(target, pname, &testValueInt);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteriv error occurred.");
			result = checkGetTexParameter(gl, target, pname, GL_TRUE);

			gl.texParameteri(target, pname, GL_FALSE);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteriv", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		testValueFloat = (GLfloat)GL_TRUE;
		gl.texParameterfv(target, pname, &testValueFloat);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterfv error occurred.");
			result = checkGetTexParameter(gl, target, pname, GL_TRUE);

			gl.texParameteri(target, pname, GL_FALSE);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterfv", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		testValueInt = GL_TRUE;
		gl.texParameterIiv(target, pname, &testValueInt);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterIiv error occurred.");
			result = checkGetTexParameter(gl, target, pname, GL_TRUE);

			gl.texParameteri(target, pname, GL_FALSE);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIiv", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		testValueUInt = GL_TRUE;
		gl.texParameterIuiv(target, pname, &testValueUInt);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterIuiv error occurred.");
			result = checkGetTexParameter(gl, target, pname, GL_TRUE);

			gl.texParameteri(target, pname, GL_FALSE);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIuiv", target, pname, gl.getError(),
														  expectedError);
	}

	return result;
}

/** Testing texParameter* functions for binded texture and GL_VIRTUAL_PAGE_SIZE_INDEX_ARB parameter name
 *
 * @param gl               GL API functions
 * @param target           Target for which texture is binded
 * @param expectedError    Expected error code (default value GL_NO_ERROR)
 *
 * @return Returns true if queried value is as expected, returns false otherwise
 */
bool TextureParameterQueriesTestCase::testVirtualPageSizeIndexARB(const Functions& gl, GLint target,
																  GLint expectedError)
{
	const GLint pname = GL_VIRTUAL_PAGE_SIZE_INDEX_ARB;

	bool result = true;

	GLint   testValueInt;
	GLuint  testValueUInt;
	GLfloat testValueFloat;

	mLog << "Testing VIRTUAL_PAGE_SIZE_INDEX_ARB for target: " << target << " - ";

	//Check getTexParameter* default value
	if (expectedError == GL_NO_ERROR)
		result = checkGetTexParameter(gl, target, pname, 0);

	//Check getTexParameter* for manually set values
	if (result)
	{
		gl.texParameteri(target, pname, 1);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
			result = checkGetTexParameter(gl, target, pname, 1);

			//If no error verification reset TEXTURE_SPARSE_ARB value
			gl.texParameteri(target, pname, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteri", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		gl.texParameterf(target, pname, 2.0f);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf error occurred");
			result = checkGetTexParameter(gl, target, pname, 2);

			gl.texParameteri(target, pname, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterf", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		testValueInt = 8;
		gl.texParameteriv(target, pname, &testValueInt);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteriv error occurred");
			result = checkGetTexParameter(gl, target, pname, 8);

			gl.texParameteri(target, pname, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteriv", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		testValueFloat = 10.0f;
		gl.texParameterfv(target, pname, &testValueFloat);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterfv error occurred");
			result = checkGetTexParameter(gl, target, pname, 10);

			gl.texParameteri(target, pname, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterfv", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		testValueInt = 6;
		gl.texParameterIiv(target, pname, &testValueInt);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterIiv error occurred");
			result = checkGetTexParameter(gl, target, pname, 6);

			gl.texParameteri(target, pname, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIiv", target, pname, gl.getError(),
														  expectedError);
	}

	if (result)
	{
		testValueUInt = 16;
		gl.texParameterIuiv(target, pname, &testValueUInt);
		if (expectedError == GL_NO_ERROR)
		{
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterIuiv error occurred");
			result = checkGetTexParameter(gl, target, pname, 16);

			gl.texParameteri(target, pname, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
		}
		else
			result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIuiv", target, pname, gl.getError(),
														  expectedError);
	}

	return result;
}

/** Testing getTexParameter* functions for binded texture and GL_NUM_SPARSE_LEVELS_ARB parameter name
 *
 * @param gl               GL API functions
 * @param target           Target for which texture is binded
 * @param expectedError    Expected error code (default value GL_NO_ERROR)
 *
 * @return Returns true if no error code was generated, throws exception otherwise
 */
bool TextureParameterQueriesTestCase::testNumSparseLevelsARB(const Functions& gl, GLint target)
{
	const GLint pname = GL_NUM_SPARSE_LEVELS_ARB;

	bool result = true;

	GLint   value_int;
	GLuint  value_uint;
	GLfloat value_float;

	mLog << "Testing NUM_SPARSE_LEVELS_ARB for target: " << target << " - ";

	gl.getTexParameteriv(target, pname, &value_int);
	result = SparseTextureUtils::verifyError(mLog, "glGetTexParameteriv", gl.getError(), GL_NO_ERROR);

	if (result)
	{
		gl.getTexParameterfv(target, pname, &value_float);
		result = SparseTextureUtils::verifyError(mLog, "glGetTexParameterfv", gl.getError(), GL_NO_ERROR);

		if (result)
		{
			gl.getTexParameterIiv(target, pname, &value_int);
			result = SparseTextureUtils::verifyError(mLog, "glGetGexParameterIiv", gl.getError(), GL_NO_ERROR);

			if (result)
			{
				gl.getTexParameterIuiv(target, pname, &value_uint);
				result = SparseTextureUtils::verifyError(mLog, "getTexParameterIuiv", gl.getError(), GL_NO_ERROR);
			}
		}
	}

	return result;
}

/** Checking if getTexParameter* for binded texture returns value as expected
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param pname        Parameter name
 * @param expected     Expected value (int because function is designed to query only int and boolean parameters)
 *
 * @return Returns true if queried value is as expected, returns false otherwise
 */
bool TextureParameterQueriesTestCase::checkGetTexParameter(const Functions& gl, GLint target, GLint pname,
														   GLint expected)
{
	bool result = true;

	GLint   value_int;
	GLuint  value_uint;
	GLfloat value_float;

	mLog << "Testing GetTexParameter for target: " << target << " - ";

	gl.getTexParameteriv(target, pname, &value_int);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv error occurred");
	if (value_int != expected)
	{
		mLog << "glGetTexParameteriv return wrong value"
			 << ", target: " << target << ", pname: " << pname << ", expected: " << expected
			 << ", returned: " << value_int << " - ";

		result = false;
	}

	gl.getTexParameterfv(target, pname, &value_float);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv error occurred");
	if ((GLint)value_float != expected)
	{
		mLog << "glGetTexParameterfv return wrong value"
			 << ", target: " << target << ", pname: " << pname << ", expected: " << expected
			 << ", returned: " << (GLint)value_float << " - ";

		result = false;
	}

	gl.getTexParameterIiv(target, pname, &value_int);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetGexParameterIiv error occurred");
	if (value_int != expected)
	{
		mLog << "glGetGexParameterIiv return wrong value"
			 << ", target: " << target << ", pname: " << pname << ", expected: " << expected
			 << ", returned: " << value_int << " - ";

		result = false;
	}

	gl.getTexParameterIuiv(target, pname, &value_uint);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetGexParameterIui error occurred");
	if ((GLint)value_uint != expected)
	{
		mLog << "glGetGexParameterIui return wrong value"
			 << ", target: " << target << ", pname: " << pname << ", expected: " << expected
			 << ", returned: " << (GLint)value_uint << " - ";

		result = false;
	}

	return result;
}

/** Constructor.
 *
 *  @param context     Rendering context
 */
InternalFormatQueriesTestCase::InternalFormatQueriesTestCase(deqp::Context& context)
	: TestCase(context, "InternalFormatQueries",
			   "Implements GetInternalformat query tests described in CTS_ARB_sparse_texture")
{
	/* Left blank intentionally */
}

/** Stub init method */
void InternalFormatQueriesTestCase::init()
{
	mSupportedTargets.push_back(GL_TEXTURE_2D);
	mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
	mSupportedTargets.push_back(GL_TEXTURE_3D);
	mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
	mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
	mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);

	mSupportedInternalFormats.push_back(GL_R8);
	mSupportedInternalFormats.push_back(GL_R8_SNORM);
	mSupportedInternalFormats.push_back(GL_R16);
	mSupportedInternalFormats.push_back(GL_R16_SNORM);
	mSupportedInternalFormats.push_back(GL_RG8);
	mSupportedInternalFormats.push_back(GL_RG8_SNORM);
	mSupportedInternalFormats.push_back(GL_RG16);
	mSupportedInternalFormats.push_back(GL_RG16_SNORM);
	mSupportedInternalFormats.push_back(GL_RGB565);
	mSupportedInternalFormats.push_back(GL_RGBA8);
	mSupportedInternalFormats.push_back(GL_RGBA8_SNORM);
	mSupportedInternalFormats.push_back(GL_RGB10_A2);
	mSupportedInternalFormats.push_back(GL_RGB10_A2UI);
	mSupportedInternalFormats.push_back(GL_RGBA16);
	mSupportedInternalFormats.push_back(GL_RGBA16_SNORM);
	mSupportedInternalFormats.push_back(GL_R16F);
	mSupportedInternalFormats.push_back(GL_RG16F);
	mSupportedInternalFormats.push_back(GL_RGBA16F);
	mSupportedInternalFormats.push_back(GL_R32F);
	mSupportedInternalFormats.push_back(GL_RG32F);
	mSupportedInternalFormats.push_back(GL_RGBA32F);
	mSupportedInternalFormats.push_back(GL_R11F_G11F_B10F);
	mSupportedInternalFormats.push_back(GL_RGB9_E5);
	mSupportedInternalFormats.push_back(GL_R8I);
	mSupportedInternalFormats.push_back(GL_R8UI);
	mSupportedInternalFormats.push_back(GL_R16I);
	mSupportedInternalFormats.push_back(GL_R16UI);
	mSupportedInternalFormats.push_back(GL_R32I);
	mSupportedInternalFormats.push_back(GL_R32UI);
	mSupportedInternalFormats.push_back(GL_RG8I);
	mSupportedInternalFormats.push_back(GL_RG8UI);
	mSupportedInternalFormats.push_back(GL_RG16I);
	mSupportedInternalFormats.push_back(GL_RG16UI);
	mSupportedInternalFormats.push_back(GL_RG32I);
	mSupportedInternalFormats.push_back(GL_RG32UI);
	mSupportedInternalFormats.push_back(GL_RGBA8I);
	mSupportedInternalFormats.push_back(GL_RGBA8UI);
	mSupportedInternalFormats.push_back(GL_RGBA16I);
	mSupportedInternalFormats.push_back(GL_RGBA16UI);
	mSupportedInternalFormats.push_back(GL_RGBA32I);
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult InternalFormatQueriesTestCase::iterate()
{
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
		return STOP;
	}

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

	bool result = true;

	mLog << "Testing getInternalformativ - ";

	for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
		 ++iter)
	{
		const GLint& target = *iter;

		for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
			 formIter != mSupportedInternalFormats.end(); ++formIter)
		{
			const GLint& format = *formIter;
			GLint		 value;

			gl.getInternalformativ(target, format, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, 1, &value);
			GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ error occurred for GL_NUM_VIRTUAL_PAGE_SIZES_ARB");
			if (value == 0)
			{
				mLog << "getInternalformativ for GL_NUM_VIRTUAL_PAGE_SIZES_ARB, target: " << target
					 << ", format: " << format << " returns wrong value: " << value << " - ";

				result = false;
			}

			if (result)
			{
				GLint pageSizeX;
				GLint pageSizeY;
				GLint pageSizeZ;
				SparseTextureUtils::getTexturePageSizes(gl, target, format, pageSizeX, pageSizeY, pageSizeZ);
			}
			else
			{
				m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
				return STOP;
			}
		}
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	return STOP;
}

/** Constructor.
 *
 *  @param context     Rendering context
 */
SimpleQueriesTestCase::SimpleQueriesTestCase(deqp::Context& context)
	: TestCase(context, "SimpleQueries", "Implements Get* queries tests described in CTS_ARB_sparse_texture")
{
	/* Left blank intentionally */
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult SimpleQueriesTestCase::iterate()
{
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
		return STOP;
	}

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

	testSipmleQueries(gl, GL_MAX_SPARSE_TEXTURE_SIZE_ARB);
	testSipmleQueries(gl, GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB);
	testSipmleQueries(gl, GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB);
	testSipmleQueries(gl, GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB);

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

void SimpleQueriesTestCase::testSipmleQueries(const Functions& gl, GLint pname)
{
	std::stringstream log;
	log << "Testing simple query for pname: " << pname << " - ";

	bool result = true;

	GLint	 value_int;
	GLint64   value_int64;
	GLfloat   value_float;
	GLdouble  value_double;
	GLboolean value_bool;

	gl.getIntegerv(pname, &value_int);
	result = SparseTextureUtils::verifyError(log, "getIntegerv", gl.getError(), GL_NO_ERROR);

	if (result)
	{
		gl.getInteger64v(pname, &value_int64);
		result = SparseTextureUtils::verifyError(log, "getInteger64v", gl.getError(), GL_NO_ERROR);

		if (result)
		{
			gl.getFloatv(pname, &value_float);
			result = SparseTextureUtils::verifyError(log, "getFloatv", gl.getError(), GL_NO_ERROR);

			if (result)
			{
				gl.getDoublev(pname, &value_double);
				result = SparseTextureUtils::verifyError(log, "getDoublev", gl.getError(), GL_NO_ERROR);

				if (result)
				{
					gl.getBooleanv(pname, &value_bool);
					result = SparseTextureUtils::verifyError(log, "getBooleanv", gl.getError(), GL_NO_ERROR);
				}
			}
		}
	}

	if (!result)
	{
		TCU_FAIL(log.str().c_str());
	}
}

/** Constructor.
 *
 *  @param context     Rendering context
 */
SparseTextureAllocationTestCase::SparseTextureAllocationTestCase(deqp::Context& context)
	: TestCase(context, "SparseTextureAllocation", "Verifies TexStorage* functionality added in CTS_ARB_sparse_texture")
{
	/* Left blank intentionally */
}

/** Constructor.
 *
 *  @param context     Rendering context
 */
SparseTextureAllocationTestCase::SparseTextureAllocationTestCase(deqp::Context& context, const char* name,
																 const char* description)
	: TestCase(context, name, description)
{
	/* Left blank intentionally */
}

/** Initializes the test group contents. */
void SparseTextureAllocationTestCase::init()
{
	mSupportedTargets.push_back(GL_TEXTURE_2D);
	mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
	mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
	mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
	mSupportedTargets.push_back(GL_TEXTURE_3D);
	mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);

	mFullArrayTargets.push_back(GL_TEXTURE_2D_ARRAY);
	mFullArrayTargets.push_back(GL_TEXTURE_CUBE_MAP);
	mFullArrayTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);

	mSupportedInternalFormats.push_back(GL_R8);
	mSupportedInternalFormats.push_back(GL_R8_SNORM);
	mSupportedInternalFormats.push_back(GL_R16);
	mSupportedInternalFormats.push_back(GL_R16_SNORM);
	mSupportedInternalFormats.push_back(GL_RG8);
	mSupportedInternalFormats.push_back(GL_RG8_SNORM);
	mSupportedInternalFormats.push_back(GL_RG16);
	mSupportedInternalFormats.push_back(GL_RG16_SNORM);
	mSupportedInternalFormats.push_back(GL_RGB565);
	mSupportedInternalFormats.push_back(GL_RGBA8);
	mSupportedInternalFormats.push_back(GL_RGBA8_SNORM);
	mSupportedInternalFormats.push_back(GL_RGB10_A2);
	mSupportedInternalFormats.push_back(GL_RGB10_A2UI);
	mSupportedInternalFormats.push_back(GL_RGBA16);
	mSupportedInternalFormats.push_back(GL_RGBA16_SNORM);
	mSupportedInternalFormats.push_back(GL_R16F);
	mSupportedInternalFormats.push_back(GL_RG16F);
	mSupportedInternalFormats.push_back(GL_RGBA16F);
	mSupportedInternalFormats.push_back(GL_R32F);
	mSupportedInternalFormats.push_back(GL_RG32F);
	mSupportedInternalFormats.push_back(GL_RGBA32F);
	mSupportedInternalFormats.push_back(GL_R11F_G11F_B10F);
	mSupportedInternalFormats.push_back(GL_RGB9_E5);
	mSupportedInternalFormats.push_back(GL_R8I);
	mSupportedInternalFormats.push_back(GL_R8UI);
	mSupportedInternalFormats.push_back(GL_R16I);
	mSupportedInternalFormats.push_back(GL_R16UI);
	mSupportedInternalFormats.push_back(GL_R32I);
	mSupportedInternalFormats.push_back(GL_R32UI);
	mSupportedInternalFormats.push_back(GL_RG8I);
	mSupportedInternalFormats.push_back(GL_RG8UI);
	mSupportedInternalFormats.push_back(GL_RG16I);
	mSupportedInternalFormats.push_back(GL_RG16UI);
	mSupportedInternalFormats.push_back(GL_RG32I);
	mSupportedInternalFormats.push_back(GL_RG32UI);
	mSupportedInternalFormats.push_back(GL_RGBA8I);
	mSupportedInternalFormats.push_back(GL_RGBA8UI);
	mSupportedInternalFormats.push_back(GL_RGBA16I);
	mSupportedInternalFormats.push_back(GL_RGBA16UI);
	mSupportedInternalFormats.push_back(GL_RGBA32I);
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult SparseTextureAllocationTestCase::iterate()
{
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
		return STOP;
	}

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

	bool result = true;

	for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
		 ++iter)
	{
		const GLint& target = *iter;

		for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
			 formIter != mSupportedInternalFormats.end(); ++formIter)
		{
			const GLint& format = *formIter;

			mLog.str("");
			mLog << "Testing sparse texture allocation for target: " << target << ", format: " << format << " - ";

			result = positiveTesting(gl, target, format) && verifyTexParameterErrors(gl, target, format) &&
					 verifyTexStorageVirtualPageSizeIndexError(gl, target, format) &&
					 verifyTexStorageFullArrayCubeMipmapsError(gl, target, format) &&
					 verifyTexStorageInvalidValueErrors(gl, target, format);

			if (!result)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
				return STOP;
			}
		}
	}

	for (std::vector<glw::GLint>::const_iterator iter = mFullArrayTargets.begin(); iter != mFullArrayTargets.end();
		 ++iter)
	{
		const GLint& target = *iter;

		for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
			 formIter != mSupportedInternalFormats.end(); ++formIter)
		{
			const GLint& format = *formIter;

			mLog.str("");
			mLog << "Testing sparse texture allocation for target [full array]: " << target << ", format: " << format
				 << " - ";

			result = verifyTexStorageFullArrayCubeMipmapsError(gl, target, format);

			if (!result)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
				return STOP;
			}
		}
	}

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

/** Testing if texStorage* functionality added in ARB_sparse_texture extension works properly for given target and internal format
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 *
 * @return Returns true if no errors occurred, false otherwise.
 **/
bool SparseTextureAllocationTestCase::positiveTesting(const Functions& gl, GLint target, GLint format)
{
	mLog << "Positive Testing - ";

	GLuint texture;

	Texture::Generate(gl, texture);
	Texture::Bind(gl, texture, target);

	GLint pageSizeX;
	GLint pageSizeY;
	GLint pageSizeZ;
	GLint depth = SparseTextureUtils::getTargetDepth(target);
	SparseTextureUtils::getTexturePageSizes(gl, target, format, pageSizeX, pageSizeY, pageSizeZ);

	gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
	if (!SparseTextureUtils::verifyError(mLog, "texParameteri", gl.getError(), GL_NO_ERROR))
	{
		Texture::Delete(gl, texture);
		return false;
	}

	//The <width> and <height> has to be equal for cube map textures
	if (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY)
	{
		if (pageSizeX > pageSizeY)
			pageSizeY = pageSizeX;
		else if (pageSizeX < pageSizeY)
			pageSizeX = pageSizeY;
	}

	Texture::Storage(gl, target, 1, format, pageSizeX, pageSizeY, depth * pageSizeZ);
	if (!SparseTextureUtils::verifyError(mLog, "Texture::Storage", gl.getError(), GL_NO_ERROR))
	{
		Texture::Delete(gl, texture);
		return false;
	}

	Texture::Delete(gl, texture);
	return true;
}

/** Verifies if texParameter* generate proper errors for given target and internal format.
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 *
 * @return Returns true if errors are as expected, false otherwise.
 */
bool SparseTextureAllocationTestCase::verifyTexParameterErrors(const Functions& gl, GLint target, GLint format)
{
	mLog << "Verify TexParameter errors - ";

	bool result = true;

	GLuint texture;
	GLint  depth;

	Texture::Generate(gl, texture);
	Texture::Bind(gl, texture, target);

	depth = SparseTextureUtils::getTargetDepth(target);

	Texture::Storage(gl, target, 1, format, 8, 8, depth);
	if (!SparseTextureUtils::verifyError(mLog, "TexStorage", gl.getError(), GL_NO_ERROR))
	{
		Texture::Delete(gl, texture);
		return false;
	}

	GLint immutableFormat;

	gl.getTexParameteriv(target, GL_TEXTURE_IMMUTABLE_FORMAT, &immutableFormat);
	if (!SparseTextureUtils::verifyQueryError(mLog, "getTexParameteriv", target, GL_TEXTURE_IMMUTABLE_FORMAT,
											  gl.getError(), GL_NO_ERROR))
	{
		Texture::Delete(gl, texture);
		return false;
	}

	// Test error only if texture is immutable format, otherwise skip
	if (immutableFormat == GL_TRUE)
	{
		std::vector<IntPair> params;
		params.push_back(IntPair(GL_TEXTURE_SPARSE_ARB, GL_TRUE));
		params.push_back(IntPair(GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, 1));

		for (std::vector<IntPair>::const_iterator iter = params.begin(); iter != params.end(); ++iter)
		{
			const IntPair& param = *iter;

			if (result)
			{
				gl.texParameteri(target, param.first, param.second);
				result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteri", target, param.first,
															  gl.getError(), GL_INVALID_OPERATION);
			}

			if (result)
			{
				gl.texParameterf(target, param.first, (GLfloat)param.second);
				result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterf", target, param.first,
															  gl.getError(), GL_INVALID_OPERATION);
			}

			if (result)
			{
				GLint value = param.second;
				gl.texParameteriv(target, param.first, &value);
				result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteriv", target, param.first,
															  gl.getError(), GL_INVALID_OPERATION);
			}

			if (result)
			{
				GLfloat value = (GLfloat)param.second;
				gl.texParameterfv(target, param.first, &value);
				result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterfv", target, param.first,
															  gl.getError(), GL_INVALID_OPERATION);
			}

			if (result)
			{
				GLint value = param.second;
				gl.texParameterIiv(target, param.first, &value);
				result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIiv", target, param.first,
															  gl.getError(), GL_INVALID_OPERATION);
			}

			if (result)
			{
				GLuint value = param.second;
				gl.texParameterIuiv(target, param.first, &value);
				result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIuiv", target, param.first,
															  gl.getError(), GL_INVALID_OPERATION);
			}
		}
	}

	Texture::Delete(gl, texture);
	return result;
}

/** Verifies if texStorage* generate proper error for given target and internal format when
 *  VIRTUAL_PAGE_SIZE_INDEX_ARB value is greater than NUM_VIRTUAL_PAGE_SIZES_ARB.
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 *
 * @return Returns true if errors are as expected, false otherwise.
 */
bool SparseTextureAllocationTestCase::verifyTexStorageVirtualPageSizeIndexError(const Functions& gl, GLint target,
																				GLint format)
{
	mLog << "Verify VirtualPageSizeIndex errors - ";

	GLuint texture;
	GLint  depth;
	GLint  numPageSizes;

	Texture::Generate(gl, texture);
	Texture::Bind(gl, texture, target);

	gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
	if (!SparseTextureUtils::verifyQueryError(mLog, "texParameteri", target, GL_TEXTURE_SPARSE_ARB, gl.getError(),
											  GL_NO_ERROR))
	{
		Texture::Delete(gl, texture);
		return false;
	}

	gl.getInternalformativ(target, format, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, 1, &numPageSizes);
	if (!SparseTextureUtils::verifyQueryError(mLog, "getInternalformativ", target, GL_NUM_VIRTUAL_PAGE_SIZES_ARB,
											  gl.getError(), GL_NO_ERROR))
	{
		Texture::Delete(gl, texture);
		return false;
	}

	numPageSizes += 1;
	gl.texParameteri(target, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, numPageSizes);
	if (!SparseTextureUtils::verifyQueryError(mLog, "texParameteri", target, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB,
											  gl.getError(), GL_NO_ERROR))
	{
		Texture::Delete(gl, texture);
		return false;
	}

	depth = SparseTextureUtils::getTargetDepth(target);

	Texture::Storage(gl, target, 1, format, 8, 8, depth);
	if (!SparseTextureUtils::verifyError(mLog, "TexStorage", gl.getError(), GL_INVALID_OPERATION))
	{
		Texture::Delete(gl, texture);
		return false;
	}

	Texture::Delete(gl, texture);
	return true;
}

/** Verifies if texStorage* generate proper errors for given target and internal format and
 *  SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB value set to FALSE.
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 *
 * @return Returns true if errors are as expected, false otherwise.
 */
bool SparseTextureAllocationTestCase::verifyTexStorageFullArrayCubeMipmapsError(const Functions& gl, GLint target,
																				GLint format)
{
	mLog << "Verify FullArrayCubeMipmaps errors - ";

	bool result = true;

	GLuint texture;
	GLint  depth;

	depth = SparseTextureUtils::getTargetDepth(target);

	GLboolean fullArrayCubeMipmaps;

	gl.getBooleanv(GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB, &fullArrayCubeMipmaps);
	if (!SparseTextureUtils::verifyQueryError(
			mLog, "getBooleanv", target, GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB, gl.getError(), GL_NO_ERROR))
		return false;

	if (fullArrayCubeMipmaps == GL_FALSE &&
		(target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY))
	{
		Texture::Generate(gl, texture);
		Texture::Bind(gl, texture, target);

		GLint pageSizeX;
		GLint pageSizeY;
		GLint pageSizeZ;
		SparseTextureUtils::getTexturePageSizes(gl, target, format, pageSizeX, pageSizeY, pageSizeZ);

		gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);

		GLint levels = 4;
		GLint width  = pageSizeX * (int)pow(2, levels - 1);
		GLint height = pageSizeY * (int)pow(2, levels - 1);

		// Check 2 different cases:
		// 1) wrong width
		// 2) wrong height
		if (target == GL_TEXTURE_CUBE_MAP ||  target == GL_TEXTURE_CUBE_MAP_ARRAY)
		{
			GLint widthHeight = de::max(width, height);
			GLint pageSize = de::max(pageSizeX, pageSizeY);
			Texture::Storage(gl, target, levels, format, widthHeight + pageSize, widthHeight + pageSize, depth);
			result =
				SparseTextureUtils::verifyError(mLog, "TexStorage [wrong width]", gl.getError(), GL_INVALID_OPERATION);
		}
		else
		{
			Texture::Storage(gl, target, levels, format, width + pageSizeX, height, depth);
			result =
				SparseTextureUtils::verifyError(mLog, "TexStorage [wrong width]", gl.getError(), GL_INVALID_OPERATION);

			if (result)
			{
				Texture::Storage(gl, target, levels, format, width, height + pageSizeY, depth);
				result = SparseTextureUtils::verifyError(mLog, "TexStorage [wrong height]", gl.getError(),
															GL_INVALID_OPERATION);
			}
		}

		Texture::Delete(gl, texture);
	}

	return result;
}

/** Verifies if texStorage* generate proper errors for given target and internal format when
 *  texture size are set greater than allowed.
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 *
 * @return Returns true if errors are as expected, false otherwise.
 */
bool SparseTextureAllocationTestCase::verifyTexStorageInvalidValueErrors(const Functions& gl, GLint target,
																		 GLint format)
{
	mLog << "Verify Invalid Value errors - ";

	GLuint texture;

	Texture::Generate(gl, texture);
	Texture::Bind(gl, texture, target);

	GLint  pageSizeX;
	GLint  pageSizeY;
	GLint  pageSizeZ;
	SparseTextureUtils::getTexturePageSizes(gl, target, format, pageSizeX, pageSizeY, pageSizeZ);

	gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);

	GLint width  = pageSizeX;
	GLint height = pageSizeY;
	GLint depth  = SparseTextureUtils::getTargetDepth(target) * pageSizeZ;

	if (target == GL_TEXTURE_3D)
	{
		GLint max3DTextureSize;

		gl.getIntegerv(GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB, &max3DTextureSize);
		if (!SparseTextureUtils::verifyQueryError(mLog, "getIntegerv", target, GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB,
												  gl.getError(), GL_NO_ERROR))
		{
			Texture::Delete(gl, texture);
			return false;
		}

		// Check 3 different cases:
		// 1) wrong width
		// 2) wrong height
		// 3) wrong depth
		Texture::Storage(gl, target, 1, format, width + max3DTextureSize, height, depth);
		if (!SparseTextureUtils::verifyError(mLog, "TexStorage [GL_TEXTURE_3D wrong width]", gl.getError(),
											 GL_INVALID_VALUE))
		{
			Texture::Delete(gl, texture);
			return false;
		}

		Texture::Storage(gl, target, 1, format, width, height + max3DTextureSize, depth);
		if (!SparseTextureUtils::verifyError(mLog, "TexStorage [GL_TEXTURE_3D wrong height]", gl.getError(),
											 GL_INVALID_VALUE))
		{
			Texture::Delete(gl, texture);
			return false;
		}

		// Check for GL_NV_deep_texture3D support, if so we'll need to check
		// against the depth limit instead of the generic 3D texture size limit
		if (m_context.getContextInfo().isExtensionSupported("GL_NV_deep_texture3D"))
		{

			// Ensure that width and height are within the valid bounds for a
			// deep texture
			GLint maxTextureWidthHeight;
			gl.getIntegerv(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV, &maxTextureWidthHeight);

			if (width < maxTextureWidthHeight && height < maxTextureWidthHeight)
			{
				gl.getIntegerv(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV, &max3DTextureSize);
			}
		}

		Texture::Storage(gl, target, 1, format, width, height, depth + max3DTextureSize);
		if (!SparseTextureUtils::verifyError(mLog, "TexStorage [GL_TEXTURE_3D wrong depth]", gl.getError(),
											 GL_INVALID_VALUE))
		{
			Texture::Delete(gl, texture);
			return false;
		}
	}
	else
	{
		GLint maxTextureSize;

		gl.getIntegerv(GL_MAX_SPARSE_TEXTURE_SIZE_ARB, &maxTextureSize);
		if (!SparseTextureUtils::verifyQueryError(mLog, "getIntegerv", target, GL_MAX_SPARSE_TEXTURE_SIZE_ARB,
												  gl.getError(), GL_NO_ERROR))
		{
			Texture::Delete(gl, texture);
			return false;
		}

		// Check 3 different cases:
		// 1) wrong width
		// 2) wrong height
		Texture::Storage(gl, target, 1, format, width + maxTextureSize, height, depth);
		if (!SparseTextureUtils::verifyError(mLog, "TexStorage [!GL_TEXTURE_3D wrong width]", gl.getError(),
											 GL_INVALID_VALUE))
		{
			Texture::Delete(gl, texture);
			return false;
		}

		if (target != GL_TEXTURE_1D_ARRAY)
		{
			Texture::Storage(gl, target, 1, format, width, height + maxTextureSize, depth);
			if (!SparseTextureUtils::verifyError(mLog, "TexStorage [!GL_TEXTURE_3D wrong height]", gl.getError(),
												 GL_INVALID_VALUE))
			{
				Texture::Delete(gl, texture);
				return false;
			}
		}

		GLint maxArrayTextureLayers;

		gl.getIntegerv(GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB, &maxArrayTextureLayers);
		if (!SparseTextureUtils::verifyQueryError(mLog, "getIntegerv", target, GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB,
												  gl.getError(), GL_NO_ERROR))
		{
			Texture::Delete(gl, texture);
			return false;
		}

		if (target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
		{
			Texture::Storage(gl, target, 1, format, width, height, depth + maxArrayTextureLayers);
			if (!SparseTextureUtils::verifyError(mLog, "TexStorage [ARRAY wrong depth]", gl.getError(),
												 GL_INVALID_VALUE))
			{
				Texture::Delete(gl, texture);
				return false;
			}
		}
	}

	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
	{
		if (pageSizeX > 1)
		{
			Texture::Storage(gl, target, 1, format, pageSizeX + 1, height, depth);
			if (!SparseTextureUtils::verifyError(mLog, "TexStorage [wrong width]", gl.getError(), GL_INVALID_VALUE))
			{
				Texture::Delete(gl, texture);
				return false;
			}
		}

		if (pageSizeY > 1)
		{
			Texture::Storage(gl, target, 1, format, width, pageSizeY + 1, depth);
			if (!SparseTextureUtils::verifyError(mLog, "TexStorage [wrong height]", gl.getError(), GL_INVALID_VALUE))
			{
				Texture::Delete(gl, texture);
				return false;
			}
		}

		if (pageSizeZ > 1)
		{
			Texture::Storage(gl, target, 1, format, width, height, pageSizeZ + 1);
			if (!SparseTextureUtils::verifyError(mLog, "TexStorage [wrong depth]", gl.getError(), GL_INVALID_VALUE))
			{
				Texture::Delete(gl, texture);
				return false;
			}
		}
	}

	Texture::Delete(gl, texture);
	return true;
}

/** Constructor.
 *
 *  @param context     Rendering context
 */
SparseTextureCommitmentTestCase::SparseTextureCommitmentTestCase(deqp::Context& context)
	: TestCase(context, "SparseTextureCommitment",
			   "Verifies TexPageCommitmentARB functionality added in CTS_ARB_sparse_texture")
	, mState()
{
	/* Left blank intentionally */
}

/** Constructor.
 *
 *  @param context     Rendering context
 *  @param name        Test name
 *  @param description Test description
 */
SparseTextureCommitmentTestCase::SparseTextureCommitmentTestCase(deqp::Context& context, const char* name,
																 const char* description)
	: TestCase(context, name, description), mState()
{
	/* Left blank intentionally */
}

/** Initializes the test case. */
void SparseTextureCommitmentTestCase::init()
{
	mSupportedTargets.push_back(GL_TEXTURE_2D);
	mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
	mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
	mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
	mSupportedTargets.push_back(GL_TEXTURE_3D);
	mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);

	mSupportedInternalFormats.push_back(GL_R8);
	mSupportedInternalFormats.push_back(GL_R8_SNORM);
	mSupportedInternalFormats.push_back(GL_R16);
	mSupportedInternalFormats.push_back(GL_R16_SNORM);
	mSupportedInternalFormats.push_back(GL_RG8);
	mSupportedInternalFormats.push_back(GL_RG8_SNORM);
	mSupportedInternalFormats.push_back(GL_RG16);
	mSupportedInternalFormats.push_back(GL_RG16_SNORM);
	mSupportedInternalFormats.push_back(GL_RGB565);
	mSupportedInternalFormats.push_back(GL_RGBA8);
	mSupportedInternalFormats.push_back(GL_RGBA8_SNORM);
	mSupportedInternalFormats.push_back(GL_RGB10_A2);
	mSupportedInternalFormats.push_back(GL_RGB10_A2UI);
	mSupportedInternalFormats.push_back(GL_RGBA16);
	mSupportedInternalFormats.push_back(GL_RGBA16_SNORM);
	mSupportedInternalFormats.push_back(GL_R16F);
	mSupportedInternalFormats.push_back(GL_RG16F);
	mSupportedInternalFormats.push_back(GL_RGBA16F);
	mSupportedInternalFormats.push_back(GL_R32F);
	mSupportedInternalFormats.push_back(GL_RG32F);
	mSupportedInternalFormats.push_back(GL_RGBA32F);
	mSupportedInternalFormats.push_back(GL_R11F_G11F_B10F);
	mSupportedInternalFormats.push_back(GL_RGB9_E5);
	mSupportedInternalFormats.push_back(GL_R8I);
	mSupportedInternalFormats.push_back(GL_R8UI);
	mSupportedInternalFormats.push_back(GL_R16I);
	mSupportedInternalFormats.push_back(GL_R16UI);
	mSupportedInternalFormats.push_back(GL_R32I);
	mSupportedInternalFormats.push_back(GL_R32UI);
	mSupportedInternalFormats.push_back(GL_RG8I);
	mSupportedInternalFormats.push_back(GL_RG8UI);
	mSupportedInternalFormats.push_back(GL_RG16I);
	mSupportedInternalFormats.push_back(GL_RG16UI);
	mSupportedInternalFormats.push_back(GL_RG32I);
	mSupportedInternalFormats.push_back(GL_RG32UI);
	mSupportedInternalFormats.push_back(GL_RGBA8I);
	mSupportedInternalFormats.push_back(GL_RGBA8UI);
	mSupportedInternalFormats.push_back(GL_RGBA16I);
	mSupportedInternalFormats.push_back(GL_RGBA16UI);
	mSupportedInternalFormats.push_back(GL_RGBA32I);
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult SparseTextureCommitmentTestCase::iterate()
{
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
		return STOP;
	}

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

	bool result = true;

	GLuint texture;

	for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
		 ++iter)
	{
		const GLint& target = *iter;

		for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
			 formIter != mSupportedInternalFormats.end(); ++formIter)
		{
			const GLint& format = *formIter;

			if (!caseAllowed(target, format))
				continue;

			mLog.str("");
			mLog << "Testing sparse texture commitment for target: " << target << ", format: " << format << " - ";

			//Checking if written data into not committed region generates no error
			sparseAllocateTexture(gl, target, format, texture, 3);
			for (int l = 0; l < mState.levels; ++l)
				writeDataToTexture(gl, target, format, texture, l);

			//Checking if written data into committed region is as expected
			for (int l = 0; l < mState.levels; ++l)
			{
				if (commitTexturePage(gl, target, format, texture, l))
				{
					writeDataToTexture(gl, target, format, texture, l);
					result = verifyTextureData(gl, target, format, texture, l);
				}

				if (!result)
					break;
			}

			Texture::Delete(gl, texture);

			//verify errors
			result = result && verifyInvalidOperationErrors(gl, target, format, texture);
			result = result && verifyInvalidValueErrors(gl, target, format, texture);

			if (!result)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
				return STOP;
			}
		}
	}

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

/** Bind texPageCommitmentARB function
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 * @param xOffset      Texture commitment x offset
 * @param yOffset      Texture commitment y offset
 * @param zOffset      Texture commitment z offset
 * @param width        Texture commitment width
 * @param height       Texture commitment height
 * @param depth        Texture commitment depth
 * @param commit       Commit or de-commit indicator
 **/
void SparseTextureCommitmentTestCase::texPageCommitment(const glw::Functions& gl, glw::GLint target, glw::GLint format,
														glw::GLuint& texture, GLint level, GLint xOffset, GLint yOffset,
														GLint zOffset, GLint width, GLint height, GLint depth,
														GLboolean commit)
{
	DE_UNREF(format);
	Texture::Bind(gl, texture, target);

	gl.texPageCommitmentARB(target, level, xOffset, yOffset, zOffset, width, height, depth, commit);
}

/** Check if specific combination of target and format is allowed
 *
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 *
 * @return Returns true if target/format combination is allowed, false otherwise.
 */
bool SparseTextureCommitmentTestCase::caseAllowed(GLint target, GLint format)
{
	DE_UNREF(target);
	DE_UNREF(format);
	return true;
}

/** Preparing texture
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 *
 * @return Returns true if no error occurred, otherwise throws an exception.
 */
bool SparseTextureCommitmentTestCase::prepareTexture(const Functions& gl, GLint target, GLint format, GLuint& texture)
{
	Texture::Generate(gl, texture);
	Texture::Bind(gl, texture, target);

	mState.minDepth = SparseTextureUtils::getTargetDepth(target);
	SparseTextureUtils::getTexturePageSizes(gl, target, format, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ);

	//The <width> and <height> has to be equal for cube map textures
	if (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY)
	{
		if (mState.pageSizeX > mState.pageSizeY)
			mState.pageSizeY = mState.pageSizeX;
		else if (mState.pageSizeX < mState.pageSizeY)
			mState.pageSizeX = mState.pageSizeY;
	}

	mState.width  = 2 * mState.pageSizeX;
	mState.height = 2 * mState.pageSizeY;
	mState.depth  = 2 * mState.pageSizeZ * mState.minDepth;

	mState.format = glu::mapGLInternalFormat(format);

	return true;
}

/** Allocating sparse texture memory using texStorage* function
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 * @param levels       Texture mipmaps level
 *
 * @return Returns true if no error occurred, otherwise throws an exception.
 */
bool SparseTextureCommitmentTestCase::sparseAllocateTexture(const Functions& gl, GLint target, GLint format,
															GLuint& texture, GLint levels)
{
	mLog << "Sparse Allocate [levels: " << levels << "] - ";

	prepareTexture(gl, target, format, texture);

	gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB");

	// GL_TEXTURE_RECTANGLE can have only one level
	mState.levels = target == GL_TEXTURE_RECTANGLE ? 1 : levels;

	Texture::Storage(gl, target, mState.levels, format, mState.width, mState.height, mState.depth);
	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");

	return true;
}

/** Allocating texture memory using texStorage* function
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 * @param levels       Texture mipmaps level
 *
 * @return Returns true if no error occurred, otherwise throws an exception.
 */
bool SparseTextureCommitmentTestCase::allocateTexture(const Functions& gl, GLint target, GLint format, GLuint& texture,
													  GLint levels)
{
	mLog << "Allocate [levels: " << levels << "] - ";

	prepareTexture(gl, target, format, texture);

	//GL_TEXTURE_RECTANGLE can have only one level
	if (target != GL_TEXTURE_RECTANGLE)
		mState.levels = levels;
	else
		mState.levels = 1;

	Texture::Storage(gl, target, mState.levels, format, mState.width, mState.height, mState.depth);
	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");

	return true;
}

/** Writing data to generated texture
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 *
 * @return Returns true if no error occurred, otherwise throws an exception.
 */
bool SparseTextureCommitmentTestCase::writeDataToTexture(const Functions& gl, GLint target, GLint format,
														 GLuint& texture, GLint level)
{
	DE_UNREF(format);
	DE_UNREF(texture);

	mLog << "Fill texture [level: " << level << "] - ";

	if (level > mState.levels - 1)
		TCU_FAIL("Invalid level");

	TransferFormat transferFormat = glu::getTransferFormat(mState.format);

	GLint width;
	GLint height;
	GLint depth;
	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);

	if (width > 0 && height > 0 && depth >= mState.minDepth)
	{
		GLint texSize = width * height * depth * mState.format.getPixelSize();

		std::vector<GLubyte> vecData;
		vecData.resize(texSize);
		GLubyte* data = vecData.data();

		deMemset(data, 16 + 16 * level, texSize);

		Texture::SubImage(gl, target, level, 0, 0, 0, width, height, depth, transferFormat.format,
						  transferFormat.dataType, (GLvoid*)data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "SubImage");
	}

	return true;
}

/** Verify if data stored in texture is as expected
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 * @param level        Texture mipmap level
 *
 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
 */
bool SparseTextureCommitmentTestCase::verifyTextureData(const Functions& gl, GLint target, GLint format,
														GLuint& texture, GLint level)
{
	DE_UNREF(format);
	DE_UNREF(texture);

	mLog << "Verify Texture [level: " << level << "] - ";

	if (level > mState.levels - 1)
		TCU_FAIL("Invalid level");

	TransferFormat transferFormat = glu::getTransferFormat(mState.format);

	GLint width;
	GLint height;
	GLint depth;
	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);

	//Committed region is limited to 1/2 of width
	GLint widthCommitted = width / 2;

	if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
		return true;

	bool result = true;

	if (target != GL_TEXTURE_CUBE_MAP)
	{
		GLint texSize = width * height * depth * mState.format.getPixelSize();

		std::vector<GLubyte> vecExpData;
		std::vector<GLubyte> vecOutData;
		vecExpData.resize(texSize);
		vecOutData.resize(texSize);
		GLubyte* exp_data = vecExpData.data();
		GLubyte* out_data = vecOutData.data();

		deMemset(exp_data, 16 + 16 * level, texSize);
		deMemset(out_data, 255, texSize);

		Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");

		//Verify only committed region
		for (GLint x = 0; x < widthCommitted; ++x)
			for (GLint y = 0; y < height; ++y)
				for (GLint z = 0; z < depth; ++z)
				{
					int		 pixelSize	 = mState.format.getPixelSize();
					GLubyte* dataRegion	= exp_data + ((x + y * width) * pixelSize);
					GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
					if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
						result = false;
				}
	}
	else
	{
		std::vector<GLint> subTargets;

		subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
		subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
		subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
		subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
		subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
		subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);

		GLint texSize = width * height * mState.format.getPixelSize();

		std::vector<GLubyte> vecExpData;
		std::vector<GLubyte> vecOutData;
		vecExpData.resize(texSize);
		vecOutData.resize(texSize);
		GLubyte* exp_data = vecExpData.data();
		GLubyte* out_data = vecOutData.data();

		deMemset(exp_data, 16 + 16 * level, texSize);
		deMemset(out_data, 255, texSize);

		for (size_t i = 0; i < subTargets.size(); ++i)
		{
			GLint subTarget = subTargets[i];

			mLog << "Verify Subtarget [subtarget: " << subTarget << "] - ";

			deMemset(out_data, 255, texSize);

			Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");

			//Verify only committed region
			for (GLint x = 0; x < widthCommitted; ++x)
				for (GLint y = 0; y < height; ++y)
					for (GLint z = 0; z < depth; ++z)
					{
						int		 pixelSize	 = mState.format.getPixelSize();
						GLubyte* dataRegion	= exp_data + ((x + y * width) * pixelSize);
						GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
						if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
							result = false;
					}

			if (!result)
				break;
		}
	}

	return result;
}

/** Commit texture page using texPageCommitment function
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 * @param level        Texture mipmap level
 *
 * @return Returns true if commitment is done properly, false if commitment is not allowed or throws exception if error occurred.
 */
bool SparseTextureCommitmentTestCase::commitTexturePage(const Functions& gl, GLint target, GLint format,
														GLuint& texture, GLint level)
{
	mLog << "Commit Region [level: " << level << "] - ";

	if (level > mState.levels - 1)
		TCU_FAIL("Invalid level");

	// Avoid not allowed commitments
	if (!isInPageSizesRange(target, level) || !isPageSizesMultiplication(target, level))
	{
		mLog << "Skip commitment [level: " << level << "] - ";
		return false;
	}

	GLint width;
	GLint height;
	GLint depth;
	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);

	if (target == GL_TEXTURE_CUBE_MAP)
		depth = 6 * depth;

	GLint widthCommitted = width / 2;

	Texture::Bind(gl, texture, target);
	texPageCommitment(gl, target, format, texture, level, 0, 0, 0, widthCommitted, height, depth, GL_TRUE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texPageCommitment");

	return true;
}

/** Check if current texture size for level is greater or equal page size in a corresponding direction
 *
 * @param target  Target for which texture is binded
 * @param level   Texture mipmap level
 *
 * @return Returns true if the texture size condition is fulfilled, false otherwise.
 */
bool SparseTextureCommitmentTestCase::isInPageSizesRange(GLint target, GLint level)
{
	GLint width;
	GLint height;
	GLint depth;
	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);

	if (target == GL_TEXTURE_CUBE_MAP)
		depth = 6 * depth;

	GLint widthCommitted = width / 2;
	if (widthCommitted >= mState.pageSizeX && height >= mState.pageSizeY &&
		(mState.minDepth == 0 || depth >= mState.pageSizeZ))
	{
		return true;
	}

	return false;
}

/** Check if current texture size for level is page size multiplication in a corresponding direction
 *
 * @param target  Target for which texture is binded
 * @param level   Texture mipmap level
 *
 * @return Returns true if the texture size condition is fulfilled, false otherwise.
 */
bool SparseTextureCommitmentTestCase::isPageSizesMultiplication(GLint target, GLint level)
{
	GLint width;
	GLint height;
	GLint depth;
	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);

	if (target == GL_TEXTURE_CUBE_MAP)
		depth = 6 * depth;

	GLint widthCommitted = width / 2;
	if ((widthCommitted % mState.pageSizeX) == 0 && (height % mState.pageSizeY) == 0 && (depth % mState.pageSizeZ) == 0)
	{
		return true;
	}

	return false;
}

/** Verifies if gltexPageCommitment generates INVALID_OPERATION error in expected use cases
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 *
 * @return Returns true if no error occurred, otherwise throws an exception.
 */
bool SparseTextureCommitmentTestCase::verifyInvalidOperationErrors(const Functions& gl, GLint target, GLint format,
																   GLuint& texture)
{
	mLog << "Verify INVALID_OPERATION Errors - ";

	bool result = true;

	// Case 1 - texture is not GL_TEXTURE_IMMUTABLE_FORMAT
	Texture::Generate(gl, texture);
	Texture::Bind(gl, texture, target);

	gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB");

	GLint immutableFormat;

	gl.getTexParameteriv(target, GL_TEXTURE_IMMUTABLE_FORMAT, &immutableFormat);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv error occurred for GL_TEXTURE_IMMUTABLE_FORMAT");

	if (immutableFormat == GL_FALSE)
	{
		texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ,
						  GL_TRUE);
		result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [GL_TEXTURE_IMMUTABLE_FORMAT texture]",
												 gl.getError(), GL_INVALID_OPERATION);
		if (!result)
			goto verifing_invalid_operation_end;
	}

	Texture::Delete(gl, texture);

	// Case 2 - texture is not TEXTURE_SPARSE_ARB
	allocateTexture(gl, target, format, texture, 1);

	texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ,
					  GL_TRUE);
	result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [not TEXTURE_SPARSE_ARB texture]", gl.getError(),
											 GL_INVALID_OPERATION);
	if (!result)
		goto verifing_invalid_operation_end;

	// Sparse allocate texture
	Texture::Delete(gl, texture);
	sparseAllocateTexture(gl, target, format, texture, 1);

	// Case 3 - commitment sizes greater than expected
	texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.width + mState.pageSizeX, mState.height,
					  mState.depth, GL_TRUE);
	result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment width greater than expected]",
											 gl.getError(), GL_INVALID_OPERATION);
	if (!result)
		goto verifing_invalid_operation_end;

	texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.width, mState.height + mState.pageSizeY,
					  mState.depth, GL_TRUE);
	result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment height greater than expected]",
											 gl.getError(), GL_INVALID_OPERATION);
	if (!result)
		goto verifing_invalid_operation_end;

	if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
	{
		texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.width, mState.height,
						  mState.depth + mState.pageSizeZ, GL_TRUE);
		result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment depth greater than expected]",
												 gl.getError(), GL_INVALID_OPERATION);
		if (!result)
			goto verifing_invalid_operation_end;
	}

	// Case 4 - commitment sizes not multiple of corresponding page sizes
	if (mState.pageSizeX > 1)
	{
		texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, 1, mState.pageSizeY, mState.pageSizeZ, GL_TRUE);
		result =
			SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment width not multiple of page sizes X]",
											gl.getError(), GL_INVALID_OPERATION);
		if (!result)
			goto verifing_invalid_operation_end;
	}

	if (mState.pageSizeY > 1)
	{
		texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.pageSizeX, 1, mState.pageSizeZ, GL_TRUE);
		result =
			SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment height not multiple of page sizes Y]",
											gl.getError(), GL_INVALID_OPERATION);
		if (!result)
			goto verifing_invalid_operation_end;
	}

	if (mState.pageSizeZ > 1)
	{
		if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
		{
			texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.pageSizeX, mState.pageSizeY,
							  mState.minDepth, GL_TRUE);
			result = SparseTextureUtils::verifyError(
				mLog, "texPageCommitment [commitment depth not multiple of page sizes Z]", gl.getError(),
				GL_INVALID_OPERATION);
			if (!result)
				goto verifing_invalid_operation_end;
		}
	}

verifing_invalid_operation_end:

	Texture::Delete(gl, texture);

	return result;
}

/** Verifies if texPageCommitment generates INVALID_VALUE error in expected use cases
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 *
 * @return Returns true if no error occurred, otherwise throws an exception.
 */
bool SparseTextureCommitmentTestCase::verifyInvalidValueErrors(const Functions& gl, GLint target, GLint format,
															   GLuint& texture)
{
	mLog << "Verify INVALID_VALUE Errors - ";

	bool result = true;

	sparseAllocateTexture(gl, target, format, texture, 1);

	// Case 1 - commitment offset not multiple of page size in corresponding dimension
	if (mState.pageSizeX > 1)
	{
		texPageCommitment(gl, target, format, texture, 0, 1, 0, 0, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ,
						  GL_TRUE);
		result =
			SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment offsetX not multiple of page size X]",
											gl.getError(), GL_INVALID_VALUE);
		if (!result)
			goto verifing_invalid_value_end;
	}
	if (mState.pageSizeY > 1)
	{
		texPageCommitment(gl, target, format, texture, 0, 0, 1, 0, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ,
						  GL_TRUE);
		result =
			SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment offsetY not multiple of page size Y]",
											gl.getError(), GL_INVALID_VALUE);
		if (!result)
			goto verifing_invalid_value_end;
	}
	if ((target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
		(mState.minDepth % mState.pageSizeZ))
	{
		texPageCommitment(gl, target, format, texture, 0, 0, 0, mState.minDepth, mState.pageSizeX, mState.pageSizeY,
						  mState.pageSizeZ, GL_TRUE);
		result =
			SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment offsetZ not multiple of page size Z]",
											gl.getError(), GL_INVALID_VALUE);
		if (!result)
			goto verifing_invalid_value_end;
	}

verifing_invalid_value_end:

	Texture::Delete(gl, texture);

	return result;
}

/** Constructor.
 *
 *  @param context     Rendering context
 */
SparseDSATextureCommitmentTestCase::SparseDSATextureCommitmentTestCase(deqp::Context& context)
	: SparseTextureCommitmentTestCase(context, "SparseDSATextureCommitment",
									  "Verifies texturePageCommitmentEXT functionality added in CTS_ARB_sparse_texture")
{
	/* Left blank intentionally */
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult SparseDSATextureCommitmentTestCase::iterate()
{
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
		return STOP;
	}

	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_direct_state_access"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_EXT_direct_state_access extension is not supported.");
		return STOP;
	}

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

	bool result = true;

	GLuint texture;

	for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
		 ++iter)
	{
		const GLint& target = *iter;

		for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
			 formIter != mSupportedInternalFormats.end(); ++formIter)
		{
			const GLint& format = *formIter;

			mLog.str("");
			mLog << "Testing DSA sparse texture commitment for target: " << target << ", format: " << format << " - ";

			//Checking if written data into committed region is as expected
			sparseAllocateTexture(gl, target, format, texture, 3);
			for (int l = 0; l < mState.levels; ++l)
			{
				if (commitTexturePage(gl, target, format, texture, l))
				{
					writeDataToTexture(gl, target, format, texture, l);
					result = verifyTextureData(gl, target, format, texture, l);
				}

				if (!result)
					break;
			}

			Texture::Delete(gl, texture);

			//verify errors
			result = result && verifyInvalidOperationErrors(gl, target, format, texture);
			result = result && verifyInvalidValueErrors(gl, target, format, texture);

			if (!result)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
				return STOP;
			}
		}
	}

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

/** Bind DSA texturePageCommitmentEXT function
 *
 * @param gl           GL API functions
 * @param target       Target for which texture is binded
 * @param format       Texture internal format
 * @param texture      Texture object
 * @param xOffset      Texture commitment x offset
 * @param yOffset      Texture commitment y offset
 * @param zOffset      Texture commitment z offset
 * @param width        Texture commitment width
 * @param height       Texture commitment height
 * @param depth        Texture commitment depth
 * @param commit       Commit or de-commit indicator
 **/
void SparseDSATextureCommitmentTestCase::texPageCommitment(const glw::Functions& gl, glw::GLint target,
														   glw::GLint format, glw::GLuint& texture, GLint level,
														   GLint xOffset, GLint yOffset, GLint zOffset, GLint width,
														   GLint height, GLint depth, GLboolean commit)
{
	DE_UNREF(target);
	DE_UNREF(format);
	gl.texturePageCommitmentEXT(texture, level, xOffset, yOffset, zOffset, width, height, depth, commit);
}

/** Constructor.
 *
 *  @param context Rendering context.
 */
SparseTextureTests::SparseTextureTests(deqp::Context& context)
	: TestCaseGroup(context, "sparse_texture_tests", "Verify conformance of CTS_ARB_sparse_texture implementation")
{
}

/** Initializes the test group contents. */
void SparseTextureTests::init()
{
	addChild(new TextureParameterQueriesTestCase(m_context));
	addChild(new InternalFormatQueriesTestCase(m_context));
	addChild(new SimpleQueriesTestCase(m_context));
	addChild(new SparseTextureAllocationTestCase(m_context));
	addChild(new SparseTextureCommitmentTestCase(m_context));
	addChild(new SparseDSATextureCommitmentTestCase(m_context));
}

} /* gl4cts namespace */
