/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2015-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  gl4cSparseBufferTests.cpp
 * \brief Conformance tests for the GL_ARB_sparse_buffer functionality.
 */ /*-------------------------------------------------------------------*/

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

#include <string.h>
#include <vector>

#ifndef GL_SPARSE_BUFFER_PAGE_SIZE_ARB
#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8
#endif
#ifndef GL_SPARSE_STORAGE_BIT_ARB
#define GL_SPARSE_STORAGE_BIT_ARB 0x0400
#endif

namespace gl4cts
{
/** Rounds up the provided offset so that it is aligned to the specified value (eg. page size).
 *  In other words, the result value meets the following requirements:
 *
 *  1)  result value % input value  = 0
 *  2)  result value               >= offset
 *  3) (result value - offset)     <  input value
 *
 *  @param offset Offset to be used for the rounding operation.
 *  @param value  Value to align the offset to.
 *
 *  @return Result value.
 **/
unsigned int SparseBufferTestUtilities::alignOffset(const unsigned int& offset, const unsigned int& value)
{
	return offset + (value - offset % value) % value;
}

/** Builds a compute program object, using the user-specified CS code snippets.
 *
 *  @param gl                     DEQP CTS GL functions container.
 *  @param cs_body_parts          Code snippets to use for the compute shader. Must hold exactly
 *                                @param n_cs_body_parts null-terminated text strings.
 *  @param n_cs_body_parts        Number of code snippets accessible via @param cs_body_parts.
 *
 *  @return Result PO id if program has been linked successfully, 0 otherwise.
 **/
glw::GLuint SparseBufferTestUtilities::createComputeProgram(const glw::Functions& gl, const char** cs_body_parts,
															unsigned int n_cs_body_parts)
{
	glw::GLint  compile_status = GL_FALSE;
	glw::GLuint cs_id		   = 0;
	glw::GLint  link_status	= GL_FALSE;
	glw::GLuint po_id		   = 0;
	bool		result		   = true;

	if (n_cs_body_parts > 0)
	{
		cs_id = gl.createShader(GL_COMPUTE_SHADER);
	}

	po_id = gl.createProgram();

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() / glCreateShader() call(s) failed.");

	if (n_cs_body_parts > 0)
	{
		gl.attachShader(po_id, cs_id);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");

	if (n_cs_body_parts > 0)
	{
		gl.shaderSource(cs_id, n_cs_body_parts, cs_body_parts, NULL); /* length */
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");

	gl.compileShader(cs_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

	gl.getShaderiv(cs_id, GL_COMPILE_STATUS, &compile_status);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");

	char temp[1024];
	gl.getShaderInfoLog(cs_id, 1024, NULL, temp);

	if (GL_TRUE != compile_status)
	{
		result = false;

		goto end;
	}

	gl.linkProgram(po_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");

	gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");

	if (GL_TRUE != link_status)
	{
		result = false;

		goto end;
	}

end:
	if (cs_id != 0)
	{
		gl.deleteShader(cs_id);

		cs_id = 0;
	}

	if (!result)
	{
		if (po_id != 0)
		{
			gl.deleteProgram(po_id);

			po_id = 0;
		}
	} /* if (!result) */

	return po_id;
}

/** Builds a program object, using the user-specified code snippets. Can optionally configure
 *  the PO to use pre-defined attribute locations & transform feed-back varyings.
 *
 *  @param gl                     DEQP CTS GL functions container.
 *  @param fs_body_parts          Code snippets to use for the fragment shader. Must hold exactly
 *                                @param n_fs_body_parts null-terminated text strings. May only
 *                                be NULL if @param n_fs_body_parts is 0.
 *  @param n_fs_body_parts        See @param fs_body_parts definitions.
 *  @param vs_body_parts          Code snippets to use for the vertex shader. Must hold exactly
 *                                @param n_vs_body_parts null-terminated text strings. May only
 *                                be NULL if @param n_vs_body_parts is 0.
 *  @param n_vs_body_parts        See @param vs_body_parts definitions.
 *  @param attribute_names        Null-terminated attribute names to pass to the
 *                                glBindAttribLocation() call.
 *                                May only be NULL if @param n_attribute_properties is 0.
 *  @param attribute_locations    Attribute locations to pass to the glBindAttribLocation() call.
 *                                May only be NULL if @param n_attribute_properties is 0.
 *  @param n_attribute_properties See @param attribute_names and @param attribute_locations definitions.
 *  @param tf_varyings            Transform-feedback varying names to use for the
 *                                glTransformFeedbackVaryings() call. May only be NULL if
 *                                @param n_tf_varyings is 0.
 *  @param n_tf_varyings          See @param tf_varyings definition.
 *  @param tf_varying_mode        Transform feedback mode to use for the
 *                                glTransformFeedbackVaryings() call. Only used if @param n_tf_varyings
 *                                is 0.
 *
 *  @return Result PO id if program has been linked successfully, 0 otherwise.
 **/
glw::GLuint SparseBufferTestUtilities::createProgram(const glw::Functions& gl, const char** fs_body_parts,
													 unsigned int n_fs_body_parts, const char** vs_body_parts,
													 unsigned int n_vs_body_parts, const char** attribute_names,
													 const unsigned int*	   attribute_locations,
													 unsigned int			   n_attribute_properties,
													 const glw::GLchar* const* tf_varyings, unsigned int n_tf_varyings,
													 glw::GLenum tf_varying_mode)
{
	glw::GLint  compile_status = GL_FALSE;
	glw::GLuint fs_id		   = 0;
	glw::GLint  link_status	= GL_FALSE;
	glw::GLuint po_id		   = 0;
	bool		result		   = true;
	glw::GLuint vs_id		   = 0;

	if (n_fs_body_parts > 0)
	{
		fs_id = gl.createShader(GL_FRAGMENT_SHADER);
	}

	po_id = gl.createProgram();

	if (n_vs_body_parts > 0)
	{
		vs_id = gl.createShader(GL_VERTEX_SHADER);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() / glCreateShader() call(s) failed.");

	if (n_fs_body_parts > 0)
	{
		gl.attachShader(po_id, fs_id);
	}

	if (n_vs_body_parts > 0)
	{
		gl.attachShader(po_id, vs_id);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");

	if (n_fs_body_parts > 0)
	{
		gl.shaderSource(fs_id, n_fs_body_parts, fs_body_parts, NULL); /* length */
	}

	if (n_vs_body_parts > 0)
	{
		gl.shaderSource(vs_id, n_vs_body_parts, vs_body_parts, NULL); /* length */
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");

	const glw::GLuint  so_ids[] = { fs_id, vs_id };
	const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);

	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
	{
		if (so_ids[n_so_id] != 0)
		{
			gl.compileShader(so_ids[n_so_id]);

			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

			gl.getShaderiv(so_ids[n_so_id], GL_COMPILE_STATUS, &compile_status);

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");

			char temp[1024];
			gl.getShaderInfoLog(so_ids[n_so_id], 1024, NULL, temp);

			if (GL_TRUE != compile_status)
			{
				result = false;

				goto end;
			}
		} /* if (so_ids[n_so_id] != 0) */
	}	 /* for (all shader object IDs) */

	for (unsigned int n_attribute = 0; n_attribute < n_attribute_properties; ++n_attribute)
	{
		gl.bindAttribLocation(po_id, attribute_locations[n_attribute], attribute_names[n_attribute]);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation() call failed.");
	} /* for (all attributes to configure) */

	if (n_tf_varyings != 0)
	{
		gl.transformFeedbackVaryings(po_id, n_tf_varyings, tf_varyings, tf_varying_mode);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
	} /* if (n_tf_varyings != 0) */

	gl.linkProgram(po_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");

	gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");

	if (GL_TRUE != link_status)
	{
		result = false;

		goto end;
	}

end:
	if (fs_id != 0)
	{
		gl.deleteShader(fs_id);

		fs_id = 0;
	}

	if (vs_id != 0)
	{
		gl.deleteShader(vs_id);

		vs_id = 0;
	}

	if (!result)
	{

		if (po_id != 0)
		{
			gl.deleteProgram(po_id);

			po_id = 0;
		}
	} /* if (!result) */

	return po_id;
}

/** Returns a string with textual representation of the @param flags bitfield
 *  holding bits applicable to the @param flags argument of glBufferStorage()
 *  calls.
 *
 *  @param flags Flags argument, as supported by the @param flags argument of
 *               glBufferStorage() entry-point.
 *
 *  @return Described string.
 **/
std::string SparseBufferTestUtilities::getSparseBOFlagsString(glw::GLenum flags)
{
	unsigned int	  n_flags_added = 0;
	std::stringstream result_sstream;

	if ((flags & GL_CLIENT_STORAGE_BIT) != 0)
	{
		result_sstream << "GL_CLIENT_STORAGE_BIT";

		++n_flags_added;
	}

	if ((flags & GL_DYNAMIC_STORAGE_BIT) != 0)
	{
		result_sstream << ((n_flags_added) ? " | " : "") << "GL_DYNAMIC_STORAGE_BIT";

		++n_flags_added;
	}

	if ((flags & GL_MAP_COHERENT_BIT) != 0)
	{
		result_sstream << ((n_flags_added) ? " | " : "") << "GL_MAP_COHERENT_BIT";

		++n_flags_added;
	}

	if ((flags & GL_MAP_PERSISTENT_BIT) != 0)
	{
		result_sstream << ((n_flags_added) ? " | " : "") << "GL_MAP_PERSISTENT_BIT";

		++n_flags_added;
	}

	if ((flags & GL_SPARSE_STORAGE_BIT_ARB) != 0)
	{
		result_sstream << ((n_flags_added) ? " | " : "") << "GL_SPARSE_STORAGE_BIT";

		++n_flags_added;
	}

	return result_sstream.str();
}

/** Constructor.
 *
 *  @param context     Rendering context
 *  @param name        Test name
 *  @param description Test description
 */
NegativeTests::NegativeTests(deqp::Context& context)
	: TestCase(context, "NegativeTests", "Implements all negative tests described in CTS_ARB_sparse_buffer")
	, m_helper_bo_id(0)
	, m_immutable_bo_id(0)
	, m_immutable_bo_size(1024768)
	, m_sparse_bo_id(0)
{
	/* Left blank intentionally */
}

/** Stub deinit method. */
void NegativeTests::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_helper_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_helper_bo_id);

		m_helper_bo_id = 0;
	}

	if (m_immutable_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_immutable_bo_id);

		m_immutable_bo_id = 0;
	}

	if (m_sparse_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_sparse_bo_id);

		m_sparse_bo_id = 0;
	}
}

/** Stub init method */
void NegativeTests::init()
{
	/* Nothing to do here */
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult NegativeTests::iterate()
{
	glw::GLvoid*		  data_ptr  = DE_NULL;
	const glw::Functions& gl		= m_context.getRenderContext().getFunctions();
	glw::GLint			  page_size = 0;
	bool				  result	= true;

	/* Only execute if the implementation supports the GL_ARB_sparse_buffer extension */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer"))
	{
		throw tcu::NotSupportedError("GL_ARB_sparse_buffer is not supported");
	}

	/* Set up */
	gl.getIntegerv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &page_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed.");

	gl.genBuffers(1, &m_helper_bo_id);
	gl.genBuffers(1, &m_immutable_bo_id);
	gl.genBuffers(1, &m_sparse_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo_id);
	gl.bindBuffer(GL_COPY_READ_BUFFER, m_immutable_bo_id);
	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_helper_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

	gl.bufferStorage(GL_ARRAY_BUFFER, page_size * 3, /* size as per test spec */
					 DE_NULL,						 /* data */
					 GL_SPARSE_STORAGE_BIT_ARB);
	gl.bufferStorage(GL_COPY_READ_BUFFER, m_immutable_bo_size, /* size */
					 DE_NULL,								   /* data */
					 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call(s) failed.");

	/** * Verify glBufferPageCommitmentARB() returns GL_INVALID_ENUM if <target> is
	 *    set to GL_INTERLEAVED_ATTRIBS. */
	glw::GLint error_code = GL_NO_ERROR;

	gl.bufferPageCommitmentARB(GL_INTERLEAVED_ATTRIBS, 0, /* offset */
							   page_size, GL_TRUE);		  /* commit */

	error_code = gl.getError();
	if (error_code != GL_INVALID_ENUM)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Invalid <target> value passed to a glBufferPageCommitmentARB() call"
							  " did not generate a GL_INVALID_ENUM error."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/*  * Verify glBufferStorage() throws a GL_INVALID_VALUE error if <flags> is
	 *    set to (GL_SPARSE_STORAGE_BIT_ARB | GL_MAP_READ_BIT) or
	 *    (GL_SPARSE_STORAGE_BIT_ARB | GL_MAP_WRITE_BIT). */
	gl.bufferStorage(GL_ELEMENT_ARRAY_BUFFER, page_size * 3, /* size */
					 DE_NULL,								 /* data */
					 GL_SPARSE_STORAGE_BIT_ARB | GL_MAP_READ_BIT);

	error_code = gl.getError();
	if (error_code != GL_INVALID_VALUE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Invalid <flags> value set to GL_SPARSE_STORAGE_BIT_ARB | GL_MAP_READ_BIT "
							  "did not generate a GL_INVALID_VALUE error."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	gl.bufferStorage(GL_ELEMENT_ARRAY_BUFFER, page_size * 3, /* size */
					 DE_NULL,								 /* data */
					 GL_SPARSE_STORAGE_BIT_ARB | GL_MAP_WRITE_BIT);

	error_code = gl.getError();
	if (error_code != GL_INVALID_VALUE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Invalid <flags> value set to GL_SPARSE_STORAGE_BIT_ARB | GL_MAP_WRITE_BIT "
							  "did not generate a GL_INVALID_VALUE error."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/*  * Verify glBufferPageCommitmentARB() generates a GL_INVALID_OPERATION error if
	 *    it is called for an immutable BO, which has not been initialized with the
	 *    GL_SPARSE_STORAGE_BIT_ARB flag. */
	gl.bufferPageCommitmentARB(GL_COPY_READ_BUFFER, 0, /* offset */
							   page_size, GL_TRUE);	/* commit */

	error_code = gl.getError();
	if (error_code != GL_INVALID_OPERATION)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid error code generated by glBufferPageCommitmentARB() "
													   " issued against an immutable, non-sparse buffer object."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/*  * Verify glBufferPageCommitmentARB() issues a GL_INVALID_VALUE error if <offset>
	 *    is set to (0.5 * GL_SPARSE_BUFFER_PAGE_SIZE_ARB). Skip if the constant's value
	 *    is equal to 1. */
	if (page_size != 1)
	{
		gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, page_size / 2, /* offset */
								   page_size, GL_TRUE);			   /* commit */

		error_code = gl.getError();
		if (error_code != GL_INVALID_VALUE)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
							   << "Invalid error code generated by glBufferPageCommitmentARB() "
								  "whose <offset> value was set to (page size / 2)."
							   << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* if (page_size != 1) */

	/*  * Verify glBufferPageCommitmentARB() emits a GL_INVALID_VALUE error if <size>
	 *    is set to (0.5 * GL_SPARSE_BUFFER_PAGE_SIZE_ARB). Skip if the constant's value
	 *    is equal to 1. */
	if (page_size != 1)
	{
		gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,		/* offset */
								   page_size / 2, GL_TRUE); /* commit */

		error_code = gl.getError();
		if (error_code != GL_INVALID_VALUE)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
							   << "Invalid error code generated by glBufferPageCommitmentARB() "
								  "whose <size> value was set to (page size / 2)."
							   << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* if (page_size != 1) */

	/*  * Verify glBufferPageCommitmentARB() returns GL_INVALID_VALUE if <offset> is
	 *    set to -1, but all other arguments are valid. */
	gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, -1, /* offset */
							   page_size, GL_TRUE); /* commit */

	error_code = gl.getError();
	if (error_code != GL_INVALID_VALUE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid error code generated by glBufferPageCommitmentARB() "
													   "whose <offset> argument was set to -1."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/*  * Verify glBufferPageCommitmentARB() returns GL_INVALID_VALUE if <size> is
	 *    set to -1, but all other arguments are valid. */
	gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
							   -1,				   /* size */
							   GL_TRUE);		   /* commit */

	error_code = gl.getError();
	if (error_code != GL_INVALID_VALUE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid error code generated by glBufferPageCommitmentARB() "
													   "whose <size> argument was set to -1."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/*  * Verify glBufferPageCommitmentARB() returns GL_INVALID_VALUE if BO's size is
	 *    GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 3, but the <offset> is set to 0 and <size>
	 *    argument used for the call is set to GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 4. */
	gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
							   page_size * 4,	  /* size */
							   GL_TRUE);

	error_code = gl.getError();
	if (error_code != GL_INVALID_VALUE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Invalid error code generated by glBufferPageCommitmentARB() "
							  "whose <offset> was set to 0 and <size> was set to (page size * 4), "
							  "when the buffer storage size had been configured to be (page size * 3)."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/*  * Verify glBufferPageCommitmentARB() returns GL_INVALID_VALUE if BO's size is
	 *    GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 3, but the <offset> is set to
	 *    GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 1 and <size> argument used for the call
	 *    is set to GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 3. */
	gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, page_size * 1, /* offset */
							   page_size * 3,				   /* size */
							   GL_TRUE);

	error_code = gl.getError();
	if (error_code != GL_INVALID_VALUE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Invalid error code generated by glBufferPageCommitmentARB() "
							  "whose <offset> was set to (page size) and <size> was set to (page size * 3), "
							  "when the buffer storage size had been configured to be (page size * 3)."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/*  * Verify that calling glMapBuffer() or glMapBufferRange() against a sparse
	 *    buffer generates a GL_INVALID_OPERATION error. */
	data_ptr = gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);

	if (data_ptr != DE_NULL)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Non-NULL pointer returned by an invalid glMapBuffer() call, issued "
							  "against a sparse buffer object"
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	error_code = gl.getError();

	if (error_code != GL_INVALID_OPERATION)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Invalid error code generated by glMapBuffer() call, issued against "
							  "a sparse buffer object"
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	data_ptr = gl.mapBufferRange(GL_ARRAY_BUFFER, 0, /* offset */
								 page_size,			 /* length */
								 GL_MAP_READ_BIT);

	if (data_ptr != DE_NULL)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Non-NULL pointer returned by an invalid glMapBufferRange() call, issued "
							  "against a sparse buffer object"
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	error_code = gl.getError();

	if (error_code != GL_INVALID_OPERATION)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Invalid error code generated by glMapBufferRange() call, issued against "
							  "a sparse buffer object"
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");

	return STOP;
}

/** Constructor.
 *
 *  @param context     Rendering context
 *  @param name        Test name
 *  @param description Test description
 */
PageSizeGetterTest::PageSizeGetterTest(deqp::Context& context)
	: TestCase(context, "PageSizeGetterTest",
			   "Verifies GL_SPARSE_BUFFER_PAGE_SIZE_ARB pname is recognized by the getter functions")
{
	/* Left blank intentionally */
}

/** Stub deinit method. */
void PageSizeGetterTest::deinit()
{
	/* Nothing to be done here */
}

/** Stub init method */
void PageSizeGetterTest::init()
{
	/* Nothing to do here */
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult PageSizeGetterTest::iterate()
{
	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
	glw::GLboolean		  page_size_bool   = false;
	glw::GLdouble		  page_size_double = 0.0;
	glw::GLfloat		  page_size_float  = 0.0f;
	glw::GLint			  page_size_int	= 0;
	glw::GLint64		  page_size_int64  = 0;
	bool				  result		   = true;

	/* Only execute if the implementation supports the GL_ARB_sparse_buffer extension */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer"))
	{
		throw tcu::NotSupportedError("GL_ARB_sparse_buffer is not supported");
	}

	/* glGetIntegerv() */
	gl.getIntegerv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &page_size_int);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed");

	if (page_size_int < 1 || page_size_int > 65536)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Page size reported by the implementation (" << page_size_int
						   << ")"
							  " by glGetIntegerv() is out of the allowed range."
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/* glGetBooleanv() */
	gl.getBooleanv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &page_size_bool);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv() call failed");

	if (!page_size_bool)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid page size reported by glGetBooleanv()"
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/* glGetDoublev() */
	gl.getDoublev(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &page_size_double);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetDoublev() call failed");

	if (de::abs(page_size_double - page_size_int) > 1e-5)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid page size reported by glGetDoublev()"
													   " (reported value: "
						   << page_size_double << ", expected value: " << page_size_int << ")"
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/* glGetFloatv() */
	gl.getFloatv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &page_size_float);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() call failed");

	if (de::abs(page_size_float - static_cast<float>(page_size_int)) > 1e-5f)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid page size reported by glGetFloatv()"
													   " (reported value: "
						   << page_size_float << ", expected value: " << page_size_int << ")"
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	/* glGetInteger64v() */
	gl.getInteger64v(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &page_size_int64);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() call failed");

	if (page_size_int64 != page_size_int)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid page size reported by glGetInteger64v()"
													   " (reported value: "
						   << page_size_int64 << ", expected value: " << page_size_int << ")"
						   << tcu::TestLog::EndMessage;

		result = false;
	}

	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");

	return STOP;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 *  @param all_pages_committed        true to run the test with all data memory pages committed,
 *                                    false to leave some of them without an actual memory backing.
 */
AtomicCounterBufferStorageTestCase::AtomicCounterBufferStorageTestCase(const glw::Functions& gl,
																	   tcu::TestContext&	 testContext,
																	   glw::GLint page_size, bool all_pages_committed)
	: m_all_pages_committed(all_pages_committed)
	, m_gl(gl)
	, m_gl_atomic_counter_uniform_array_stride(0)
	, m_gl_max_vertex_atomic_counters_value(0)
	, m_helper_bo(0)
	, m_helper_bo_size(0)
	, m_helper_bo_size_rounded(0)
	, m_n_draw_calls(3) /* as per test spec */
	, m_page_size(page_size)
	, m_po(0)
	, m_sparse_bo(0)
	, m_sparse_bo_data_size(0)
	, m_sparse_bo_data_size_rounded(0)
	, m_sparse_bo_data_start_offset(0)
	, m_sparse_bo_data_start_offset_rounded(0)
	, m_testCtx(testContext)
	, m_vao(0)
{
	/* Left blank intentionally */
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void AtomicCounterBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_po != 0)
	{
		m_gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_vao != 0)
	{
		m_gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void AtomicCounterBufferStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, m_sparse_bo_data_start_offset_rounded,		/* offset */
									 m_sparse_bo_data_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool AtomicCounterBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	static const unsigned char data_zero = 0;
	bool					   result	= true;

	/* Only execute if GL_MAX_VERTEX_ATOMIC_COUNTERS is > 0 */
	if (m_gl_max_vertex_atomic_counters_value == 0)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "G_MAX_VERTEX_ATOMIC_COUNTERS is 0. Skipping the test."
						   << tcu::TestLog::EndMessage;

		goto end;
	}

	/* Bind the test program object */
	m_gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

	m_gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	/* Try using both ranged and non-ranged AC bindings.
	 *
	 * NOTE: It only makes sense to perform glBindBufferBase() test if all AC pages are
	 *       committed
	 */
	for (unsigned int n_binding_type = (m_all_pages_committed) ? 0 : 1;
		 n_binding_type < 2; /* glBindBufferBase(), glBindBufferRange() */
		 ++n_binding_type)
	{
		bool result_local = true;

		if (n_binding_type == 0)
		{
			m_gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, /* index */
								m_sparse_bo);

			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferBase() call failed.");
		}
		else
		{
			m_gl.bindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, /* index */
								 m_sparse_bo, m_sparse_bo_data_start_offset, m_helper_bo_size);

			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferRange() call failed.");
		}

		/* Zero out the sparse buffer's contents */
		m_gl.clearBufferData(GL_ATOMIC_COUNTER_BUFFER, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &data_zero);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glClearBufferData() call failed.");

		/* Run the test */
		m_gl.drawArraysInstanced(GL_POINTS, 0,							/* first */
								 m_gl_max_vertex_atomic_counters_value, /* count */
								 m_n_draw_calls);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArraysInstanced() call failed");

		/* Retrieve the atomic counter values */
		const glw::GLuint* ac_data = NULL;
		const unsigned int n_expected_written_values =
			(m_all_pages_committed) ? m_gl_max_vertex_atomic_counters_value : m_gl_max_vertex_atomic_counters_value / 2;

		m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_sparse_bo);
		m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_helper_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffeR() call failed");

		m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
							   (n_binding_type == 0) ? 0 : m_sparse_bo_data_start_offset, 0, /* writeOffset */
							   m_sparse_bo_data_size);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

		ac_data = (const glw::GLuint*)m_gl.mapBufferRange(GL_COPY_WRITE_BUFFER, 0, /* offset */
														  m_sparse_bo_data_size, GL_MAP_READ_BIT);

		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBufferRange() call failed.");

		for (unsigned int n_counter = 0; n_counter < n_expected_written_values && result_local; ++n_counter)
		{
			const unsigned int expected_value = m_n_draw_calls;
			const unsigned int retrieved_value =
				*((unsigned int*)((unsigned char*)ac_data + m_gl_atomic_counter_uniform_array_stride * n_counter));

			if (expected_value != retrieved_value)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid atomic counter value "
															   "["
								   << retrieved_value << "]"
														 " instead of the expected value "
														 "["
								   << expected_value << "]"
														" at index "
								   << n_counter << " when using "
								   << ((n_binding_type == 0) ? "glBindBufferBase()" : "glBindBufferRange()")
								   << " for AC binding configuration" << tcu::TestLog::EndMessage;

				result_local = false;
			} /* if (expected_value != retrieved_value) */
		}	 /* for (all draw calls that need to be executed) */

		m_gl.unmapBuffer(GL_COPY_WRITE_BUFFER);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");

		result &= result_local;
	} /* for (both binding types) */

end:
	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool AtomicCounterBufferStorageTestCase::initTestCaseGlobal()
{
	const glw::GLuint ac_uniform_index = 0; /* only one uniform is defined in the VS below */
	std::stringstream n_counters_sstream;
	std::string		  n_counters_string;
	bool			  result = true;

	static const char* vs_body_preamble = "#version 430 core\n"
										  "\n";

	static const char* vs_body_core = "layout(binding = 0) uniform atomic_uint counters[N_COUNTERS];\n"
									  "\n"
									  "void main()\n"
									  "{\n"
									  "    for (uint n = 0; n < N_COUNTERS; ++n)\n"
									  "    {\n"
									  "        if (n == gl_VertexID)\n"
									  "        {\n"
									  "            atomicCounterIncrement(counters[n]);\n"
									  "        }\n"
									  "    }\n"
									  "\n"
									  "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
									  "}\n";
	const char* vs_body_parts[] = { vs_body_preamble, DE_NULL, /* will be set to n_counters_string.c_str() */
									vs_body_core };
	const unsigned int n_vs_body_parts = sizeof(vs_body_parts) / sizeof(vs_body_parts[0]);

	/* Retrieve GL_MAX_VERTEX_ATOMIC_COUNTERS value. The test will only be executed if it's >= 1 */
	m_gl.getIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &m_gl_max_vertex_atomic_counters_value);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetIntegerv() call failed.");

	if (m_gl_max_vertex_atomic_counters_value == 0)
	{
		goto end;
	}

	/* Form the N_COUNTERS declaration string */
	n_counters_sstream << "#define N_COUNTERS " << m_gl_max_vertex_atomic_counters_value << "\n";
	n_counters_string = n_counters_sstream.str();

	vs_body_parts[1] = n_counters_string.c_str();

	/* Set up the program object */
	DE_ASSERT(m_po == 0);

	m_po =
		SparseBufferTestUtilities::createProgram(m_gl, DE_NULL,							  /* fs_body_parts   */
												 0,										  /* n_fs_body_parts */
												 vs_body_parts, n_vs_body_parts, DE_NULL, /* attribute_names        */
												 DE_NULL,								  /* attribute_locations    */
												 0);									  /* n_attribute_properties */

	if (m_po == 0)
	{
		result = false;

		goto end;
	}

	/* Helper BO will be used to hold the atomic counter buffer data.
	 * Determine how much space will be needed.
	 *
	 * Min max for the GL constant value is 0. Bail out if that's the
	 * value we are returned - it is pointless to execute the test in
	 * such environment.
	 */
	m_gl.getActiveUniformsiv(m_po, 1, /* uniformCount */
							 &ac_uniform_index, GL_UNIFORM_ARRAY_STRIDE, &m_gl_atomic_counter_uniform_array_stride);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetActiveUniformsiv() call failed.");

	DE_ASSERT(m_gl_atomic_counter_uniform_array_stride >= (int)sizeof(unsigned int));

	m_helper_bo_size		 = m_gl_atomic_counter_uniform_array_stride * m_gl_max_vertex_atomic_counters_value;
	m_helper_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_helper_bo_size, m_page_size);

	/* Set up the helper BO */
	DE_ASSERT(m_helper_bo == 0);

	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_COPY_READ_BUFFER, m_helper_bo_size_rounded, DE_NULL, GL_MAP_READ_BIT); /* flags */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	/* Set up the vertex array object */
	DE_ASSERT(m_vao == 0);

	m_gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenVertexArrays() call failed.");

	m_gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindVertexArray() call failed.");

end:
	return result;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool AtomicCounterBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	/* Set up the sparse bufffer. */
	int sparse_bo_data_size = 0;

	DE_ASSERT(m_helper_bo_size_rounded != 0);

	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	if (m_all_pages_committed)
	{
		/* Commit all required pages */
		sparse_bo_data_size = m_helper_bo_size_rounded;
	}
	else
	{
		/* Only commit the first half of the required pages */
		DE_ASSERT((m_helper_bo_size_rounded % m_page_size) == 0);

		sparse_bo_data_size = (m_helper_bo_size_rounded / m_page_size) * m_page_size / 2;
	}

	/* NOTE: We need to ensure that the memory region assigned to the atomic counter buffer spans
	 *       at least through two separate pages.
	 *
	 * Since we align up, we need to move one page backward and then apply the alignment function
	 * to determine the start page index.
	 */
	const int sparse_bo_data_start_offset			 = m_page_size - m_helper_bo_size_rounded / 2;
	int		  sparse_bo_data_start_offset_minus_page = sparse_bo_data_start_offset - m_page_size;

	if (sparse_bo_data_start_offset_minus_page < 0)
	{
		sparse_bo_data_start_offset_minus_page = 0;
	}

	m_sparse_bo_data_start_offset = sparse_bo_data_start_offset;
	m_sparse_bo_data_start_offset_rounded =
		SparseBufferTestUtilities::alignOffset(sparse_bo_data_start_offset_minus_page, m_page_size);
	m_sparse_bo_data_size = sparse_bo_data_size;
	m_sparse_bo_data_size_rounded =
		SparseBufferTestUtilities::alignOffset(m_sparse_bo_data_start_offset + sparse_bo_data_size, m_page_size);

	DE_ASSERT((m_sparse_bo_data_size_rounded % m_page_size) == 0);
	DE_ASSERT((m_sparse_bo_data_start_offset_rounded % m_page_size) == 0);

	m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, m_sparse_bo_data_start_offset_rounded, m_sparse_bo_data_size_rounded,
								 GL_TRUE); /* commit */

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param context                    CTS rendering context
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
BufferTextureStorageTestCase::BufferTextureStorageTestCase(const glw::Functions& gl, deqp::Context& context,
														   tcu::TestContext& testContext, glw::GLint page_size)
	: m_gl(gl)
	, m_helper_bo(0)
	, m_helper_bo_data(DE_NULL)
	, m_helper_bo_data_size(0)
	, m_is_texture_buffer_range_supported(false)
	, m_page_size(page_size)
	, m_po(0)
	, m_po_local_wg_size(1024)
	, m_sparse_bo(0)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
	, m_ssbo(0)
	, m_ssbo_zero_data(DE_NULL)
	, m_ssbo_zero_data_size(0)
	, m_testCtx(testContext)
	, m_to(0)
	, m_to_width(65536) /* min max for GL_MAX_TEXTURE_BUFFER_SIZE_ARB */
{
	const glu::ContextInfo& context_info   = context.getContextInfo();
	glu::RenderContext&		render_context = context.getRenderContext();

	if (glu::contextSupports(render_context.getType(), glu::ApiType::core(4, 3)) ||
		context_info.isExtensionSupported("GL_ARB_texture_buffer_range"))
	{
		m_is_texture_buffer_range_supported = true;
	}
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void BufferTextureStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_helper_bo_data != DE_NULL)
	{
		delete[] m_helper_bo_data;

		m_helper_bo_data = DE_NULL;
	}

	if (m_po != 0)
	{
		m_gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_ssbo != 0)
	{
		m_gl.deleteBuffers(1, &m_ssbo);

		m_ssbo = 0;
	}

	if (m_ssbo_zero_data != DE_NULL)
	{
		delete[] m_ssbo_zero_data;

		m_ssbo_zero_data = DE_NULL;
	}

	if (m_to != 0)
	{
		m_gl.deleteTextures(1, &m_to);

		m_to = 0;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void BufferTextureStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool BufferTextureStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool result = true;

	/* Bind the program object */
	m_gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

	m_gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, /* index */
						m_ssbo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferBase() call failed.");

	/* Set up bindings for the copy ops */
	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

	/* Run the test in two iterations:
	 *
	 * a) All required pages are committed.
	 * b) Only half of the pages are committed. */
	for (unsigned int n_iteration = 0; n_iteration < 2; ++n_iteration)
	{

		/* Test glTexBuffer() and glTexBufferRange() separately. */
		for (int n_entry_point = 0; n_entry_point < (m_is_texture_buffer_range_supported ? 2 : 1); ++n_entry_point)
		{
			bool result_local = true;

			/* Set up the sparse buffer's memory backing. */
			const unsigned int tbo_commit_start_offset = (n_iteration == 0) ? 0 : m_sparse_bo_size_rounded / 2;
			const unsigned int tbo_commit_size =
				(n_iteration == 0) ? m_sparse_bo_size_rounded : m_sparse_bo_size_rounded / 2;

			m_gl.bindBuffer(GL_TEXTURE_BUFFER, m_sparse_bo);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

			m_gl.bufferPageCommitmentARB(GL_TEXTURE_BUFFER, tbo_commit_start_offset, tbo_commit_size,
										 GL_TRUE); /* commit */
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

			/* Set up the buffer texture's backing */
			if (n_entry_point == 0)
			{
				m_gl.texBuffer(GL_TEXTURE_BUFFER, GL_RGBA8, m_sparse_bo);

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexBuffer() call failed.");
			}
			else
			{
				m_gl.texBufferRange(GL_TEXTURE_BUFFER, GL_RGBA8, m_sparse_bo, 0, /* offset */
									m_sparse_bo_size);

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexBufferRange() call failed.");
			}

			/* Set up the sparse buffer's data storage */
			m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
								   0,											 /* writeOffset */
								   m_helper_bo_data_size);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

			/* Run the compute program */
			DE_ASSERT((m_to_width % m_po_local_wg_size) == 0);

			m_gl.dispatchCompute(m_to_width / m_po_local_wg_size, 1, /* num_groups_y */
								 1);								 /* num_groups_z */
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDispatchCompute() call failed.");

			/* Flush the caches */
			m_gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMemoryBarrier() call failed.");

			/* Map the SSBO into process space, so we can check if the texture buffer's
			 * contents was found valid by the compute shader */
			unsigned int		current_tb_offset = 0;
			const unsigned int* ssbo_data_ptr =
				(const unsigned int*)m_gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);

			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBuffer() call failed.");

			for (unsigned int n_texel = 0; n_texel < m_to_width && result_local;
				 ++n_texel, current_tb_offset += 4 /* rgba */)
			{
				/* NOTE: Since the CS uses std140 layout, we need to move by 4 ints for
				 *       each result value */
				if (current_tb_offset >= tbo_commit_start_offset &&
					current_tb_offset < (tbo_commit_start_offset + tbo_commit_size) && ssbo_data_ptr[n_texel * 4] != 1)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "A texel read from the texture buffer at index "
																   "["
									   << n_texel << "]"
													 " was marked as invalid by the CS invocation."
									   << tcu::TestLog::EndMessage;

					result_local = false;
				} /* if (ssbo_data_ptr[n_texel] != 1) */
			}	 /* for (all result values) */

			result &= result_local;

			m_gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");

			/* Remove the physical backing from the sparse buffer  */
			m_gl.bufferPageCommitmentARB(GL_TEXTURE_BUFFER, 0,				  /* offset */
										 m_sparse_bo_size_rounded, GL_FALSE); /* commit */

			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

			/* Reset SSBO's contents */
			m_gl.bufferSubData(GL_SHADER_STORAGE_BUFFER, 0, /* offset */
							   m_ssbo_zero_data_size, m_ssbo_zero_data);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferSubData() call failed.");
		} /* for (both entry-points) */
	}	 /* for (both iterations) */

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool BufferTextureStorageTestCase::initTestCaseGlobal()
{
	/* Set up the test program */
	static const char* cs_body =
		"#version 430 core\n"
		"\n"
		"layout(local_size_x = 1024) in;\n"
		"\n"
		"layout(std140, binding = 0) buffer data\n"
		"{\n"
		"    restrict writeonly int result[];\n"
		"};\n"
		"\n"
		"uniform samplerBuffer input_texture;\n"
		"\n"
		"void main()\n"
		"{\n"
		"    uint texel_index = gl_GlobalInvocationID.x;\n"
		"\n"
		"    if (texel_index < 65536)\n"
		"    {\n"
		"        vec4 expected_texel_data = vec4       (float((texel_index)       % 255) / 255.0,\n"
		"                                               float((texel_index + 35)  % 255) / 255.0,\n"
		"                                               float((texel_index + 78)  % 255) / 255.0,\n"
		"                                               float((texel_index + 131) % 255) / 255.0);\n"
		"        vec4 texel_data          = texelFetch(input_texture, int(texel_index) );\n"
		"\n"
		"        if (abs(texel_data.r - expected_texel_data.r) > 1.0 / 255.0 ||\n"
		"            abs(texel_data.g - expected_texel_data.g) > 1.0 / 255.0 ||\n"
		"            abs(texel_data.b - expected_texel_data.b) > 1.0 / 255.0 ||\n"
		"            abs(texel_data.a - expected_texel_data.a) > 1.0 / 255.0)\n"
		"        {\n"
		"            result[texel_index] = 0;\n"
		"        }\n"
		"        else\n"
		"        {\n"
		"            result[texel_index] = 1;\n"
		"        }\n"
		"    }\n"
		"}\n";

	m_po = SparseBufferTestUtilities::createComputeProgram(m_gl, &cs_body, 1); /* n_cs_body_parts */

	/* Set up a data buffer we will use to initialize the SSBO with default data.
	 *
	 * CS uses a std140 layout for the SSBO, so we need to add the additional padding.
	 */
	m_ssbo_zero_data_size = static_cast<unsigned int>(4 * sizeof(int) * m_to_width);
	m_ssbo_zero_data	  = new unsigned char[m_ssbo_zero_data_size];

	memset(m_ssbo_zero_data, 0, m_ssbo_zero_data_size);

	/* Set up the SSBO */
	m_gl.genBuffers(1, &m_ssbo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferData(GL_SHADER_STORAGE_BUFFER, m_ssbo_zero_data_size, m_ssbo_zero_data, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferData() call failed.");

	/* During execution, we will need to use a helper buffer object. The BO will hold
	 * data we will be copying into the sparse buffer object for each iteration.
	 *
	 * Create an array to hold the helper buffer's data and fill it with info that
	 * the compute shader is going to be expecting */
	unsigned char* helper_bo_data_traveller_ptr = NULL;

	m_helper_bo_data_size = m_to_width * 4; /* rgba */
	m_helper_bo_data	  = new unsigned char[m_helper_bo_data_size];

	helper_bo_data_traveller_ptr = m_helper_bo_data;

	for (unsigned int n_texel = 0; n_texel < m_to_width; ++n_texel)
	{
		/* Red */
		*helper_bo_data_traveller_ptr = static_cast<unsigned char>(n_texel % 255);
		++helper_bo_data_traveller_ptr;

		/* Green */
		*helper_bo_data_traveller_ptr = static_cast<unsigned char>((n_texel + 35) % 255);
		++helper_bo_data_traveller_ptr;

		/* Blue */
		*helper_bo_data_traveller_ptr = static_cast<unsigned char>((n_texel + 78) % 255);
		++helper_bo_data_traveller_ptr;

		/* Alpha */
		*helper_bo_data_traveller_ptr = static_cast<unsigned char>((n_texel + 131) % 255);
		++helper_bo_data_traveller_ptr;
	} /* for (all texels to be accessible via the buffer texture) */

	/* Set up the helper buffer object which we are going to use to copy data into
	 * the sparse buffer object. */
	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferData(GL_COPY_READ_BUFFER, m_helper_bo_data_size, m_helper_bo_data, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferData() call failed.");

	/* Set up the texture buffer object. We will attach the actual buffer storage
	 * in execute() */
	m_gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenTextures() call failed.");

	m_gl.bindTexture(GL_TEXTURE_BUFFER, m_to);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindTexture() call failed.");

	/* Determine the number of bytes both the helper and the sparse buffer
	 * object need to be able to hold, at maximum */
	m_sparse_bo_size		 = static_cast<unsigned int>(m_to_width * sizeof(int));
	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_sparse_bo_size, m_page_size);

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool BufferTextureStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
ClearOpsBufferStorageTestCase::ClearOpsBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext,
															 glw::GLint page_size)
	: m_gl(gl)
	, m_helper_bo(0)
	, m_initial_data(DE_NULL)
	, m_n_pages_to_use(16)
	, m_page_size(page_size)
	, m_sparse_bo(0)
	, m_sparse_bo_size_rounded(0)
	, m_testCtx(testContext)
{
	/* Left blank intentionally */
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void ClearOpsBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_initial_data != DE_NULL)
	{
		delete[] m_initial_data;

		m_initial_data = DE_NULL;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void ClearOpsBufferStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool ClearOpsBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool			   result	 = true;
	const unsigned int data_rgba8 = 0x12345678;

	for (unsigned int n_clear_op_type = 0; n_clear_op_type < 2; /* glClearBufferData(), glClearBufferSubData() */
		 ++n_clear_op_type)
	{
		const bool use_clear_buffer_data_call = (n_clear_op_type == 0);

		/* We will run the test case in two iterations:
		 *
		 * 1) All pages will have a physical backing.
		 * 2) Half of the pages will have a physical backing.
		 */
		for (unsigned int n_iteration = 0; n_iteration < 2; ++n_iteration)
		{
			/* By default, for each iteration all sparse buffer pages are commited.
			 *
			 * For the last iteration, we need to de-commit the latter half before
			 * proceeding with the test.
			 */
			const bool all_pages_committed = (n_iteration == 0);

			if (!all_pages_committed)
			{
				m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

				m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, m_sparse_bo_size_rounded / 2, /* offset */
											 m_sparse_bo_size_rounded / 2,					/* size   */
											 GL_TRUE);										/* commit */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
			}

			/* Set up the sparse buffer contents */
			m_gl.bindBuffer(GL_ARRAY_BUFFER, m_helper_bo);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

			m_gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
							   m_sparse_bo_size_rounded, m_initial_data);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferSubData() call failed.");

			m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
			m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_sparse_bo);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

			m_gl.copyBufferSubData(GL_COPY_READ_BUFFER,  /* readTarget  */
								   GL_COPY_WRITE_BUFFER, /* writeTarget */
								   0,					 /* readOffset */
								   0,					 /* writeOffset */
								   m_sparse_bo_size_rounded);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

			/* Issue the clear call */
			unsigned int clear_region_size		   = 0;
			unsigned int clear_region_start_offset = 0;

			if (use_clear_buffer_data_call)
			{
				DE_ASSERT((m_sparse_bo_size_rounded % sizeof(unsigned int)) == 0);

				clear_region_size		  = m_sparse_bo_size_rounded;
				clear_region_start_offset = 0;

				m_gl.clearBufferData(GL_COPY_WRITE_BUFFER, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data_rgba8);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glClearBufferData() call failed.");
			}
			else
			{
				DE_ASSERT(((m_sparse_bo_size_rounded / 2) % sizeof(unsigned int)) == 0);
				DE_ASSERT(((m_sparse_bo_size_rounded) % sizeof(unsigned int)) == 0);

				clear_region_size		  = m_sparse_bo_size_rounded / 2;
				clear_region_start_offset = m_sparse_bo_size_rounded / 2;

				m_gl.clearBufferSubData(GL_COPY_WRITE_BUFFER, GL_RGBA8, clear_region_start_offset, clear_region_size,
										GL_RGBA, GL_UNSIGNED_BYTE, &data_rgba8);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glClearBufferSubData() call failed.");
			}

			/* Retrieve the modified buffer's contents */
			const unsigned char* result_data = NULL;

			m_gl.copyBufferSubData(GL_COPY_WRITE_BUFFER, /* readTarget  */
								   GL_COPY_READ_BUFFER,  /* writeTarget */
								   0,					 /* readOffset  */
								   0,					 /* writeOffset */
								   m_sparse_bo_size_rounded);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

			result_data = (unsigned char*)m_gl.mapBufferRange(GL_COPY_READ_BUFFER, 0, /* offset */
															  m_sparse_bo_size_rounded, GL_MAP_READ_BIT);

			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBufferRange() call failed.");

			/* Verify the result data: unmodified region */
			bool			   result_local			  = true;
			const unsigned int unmodified_region_size = (use_clear_buffer_data_call) ? 0 : clear_region_start_offset;
			const unsigned int unmodified_region_start_offset = 0;

			for (unsigned int n_current_byte = unmodified_region_start_offset;
				 (n_current_byte < unmodified_region_start_offset + unmodified_region_size) && result_local;
				 ++n_current_byte)
			{
				const unsigned int  current_initial_data_offset = n_current_byte - unmodified_region_start_offset;
				const unsigned char expected_value				= m_initial_data[current_initial_data_offset];
				const unsigned char found_value					= result_data[n_current_byte];

				if (expected_value != found_value)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Unmodified buffer object region has invalid contents. Expected byte "
									   << "[" << (int)expected_value << "]"
																		", found byte:"
																		"["
									   << (int)found_value << "]"
															  " at index "
															  "["
									   << n_current_byte << "]; "
															"call type:"
															"["
									   << ((use_clear_buffer_data_call) ? "glClearBufferData()" :
																		  "glClearBufferSubData()")
									   << "]"
										  ", all required pages committed?:"
										  "["
									   << ((all_pages_committed) ? "yes" : "no") << "]" << tcu::TestLog::EndMessage;

					result_local = false;
					break;
				}
			}

			result &= result_local;
			result_local = true;

			/* Verify the result data: modified region (clamped to the memory region
			 * with actual physical backing) */
			const unsigned int modified_region_size			= (all_pages_committed) ? clear_region_size : 0;
			const unsigned int modified_region_start_offset = clear_region_start_offset;

			for (unsigned int n_current_byte = modified_region_start_offset;
				 (n_current_byte < modified_region_start_offset + modified_region_size) && result_local;
				 ++n_current_byte)
			{
				const unsigned char component_offset = n_current_byte % 4;
				const unsigned char expected_value =
					static_cast<unsigned char>((data_rgba8 & (0xFFu << (component_offset * 8))) >> (component_offset * 8));
				const unsigned char found_value = result_data[n_current_byte];

				if (expected_value != found_value)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Modified buffer object region has invalid contents. Expected byte "
									   << "[" << (int)expected_value << "]"
																		", found byte:"
																		"["
									   << (int)found_value << "]"
															  " at index "
															  "["
									   << n_current_byte << "]; "
															"call type:"
															"["
									   << ((use_clear_buffer_data_call) ? "glClearBufferData()" :
																		  "glClearBufferSubData()")
									   << "]"
										  ", all required pages committed?:"
										  "["
									   << ((all_pages_committed) ? "yes" : "no") << "]" << tcu::TestLog::EndMessage;

					result_local = false;
					break;
				}
			}

			result &= result_local;

			/* Unmap the storage before proceeding */
			m_gl.unmapBuffer(GL_COPY_READ_BUFFER);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");
		} /* for (both iterations) */
	}	 /* for (both clear types) */

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool ClearOpsBufferStorageTestCase::initTestCaseGlobal()
{
	unsigned int	   n_bytes_filled = 0;
	const unsigned int n_bytes_needed = m_n_pages_to_use * m_page_size;

	/* Determine the number of bytes both the helper and the sparse buffer
	 * object need to be able to hold, at maximum */
	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(n_bytes_needed, m_page_size);

	/* Set up the helper BO */
	DE_ASSERT(m_helper_bo == 0);

	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_COPY_READ_BUFFER, m_sparse_bo_size_rounded, DE_NULL,
					   GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT); /* flags */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	/* Set up a client-side data buffer we will use to fill the sparse BO with data,
	 * to be later cleared with the clear ops */
	DE_ASSERT(m_initial_data == DE_NULL);

	m_initial_data = new unsigned char[m_sparse_bo_size_rounded];

	while (n_bytes_filled < m_sparse_bo_size_rounded)
	{
		m_initial_data[n_bytes_filled] = static_cast<unsigned char>(n_bytes_filled % 256);

		++n_bytes_filled;
	}

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool ClearOpsBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	/* Set up the sparse bufffer. */
	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				 /* offset */
								 m_sparse_bo_size_rounded, GL_TRUE); /* commit */

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
CopyOpsBufferStorageTestCase::CopyOpsBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext,
														   glw::GLint page_size)
	: m_gl(gl)
	, m_helper_bo(0)
	, m_immutable_bo(0)
	, m_page_size(page_size)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
	, m_testCtx(testContext)
{
	m_ref_data[0]   = DE_NULL;
	m_ref_data[1]   = DE_NULL;
	m_ref_data[2]   = DE_NULL;
	m_sparse_bos[0] = 0;
	m_sparse_bos[1] = 0;
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */

void CopyOpsBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_immutable_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_immutable_bo);

		m_immutable_bo = 0;
	}

	for (unsigned int n_ref_data_buffer = 0; n_ref_data_buffer < sizeof(m_ref_data) / sizeof(m_ref_data[0]);
		 ++n_ref_data_buffer)
	{
		if (m_ref_data[n_ref_data_buffer] != DE_NULL)
		{
			delete[] m_ref_data[n_ref_data_buffer];

			m_ref_data[n_ref_data_buffer] = DE_NULL;
		}
	}

	/* Only release the test case-owned BO */
	if (m_sparse_bos[1] != 0)
	{
		m_gl.deleteBuffers(1, m_sparse_bos + 1);

		m_sparse_bos[1] = 0;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void CopyOpsBufferStorageTestCase::deinitTestCaseIteration()
{
	for (unsigned int n_sparse_bo = 0; n_sparse_bo < sizeof(m_sparse_bos) / sizeof(m_sparse_bos[0]); ++n_sparse_bo)
	{
		const glw::GLuint sparse_bo_id = m_sparse_bos[n_sparse_bo];

		if (sparse_bo_id != 0)
		{
			m_gl.bindBuffer(GL_ARRAY_BUFFER, sparse_bo_id);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

			m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
										 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
		} /* if (sparse_bo_id != 0) */
	}	 /* for (both BOs) */
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool CopyOpsBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool result = true;

	/* Iterate over all test cases */
	DE_ASSERT(m_immutable_bo != 0);
	DE_ASSERT(m_sparse_bos[0] != 0);
	DE_ASSERT(m_sparse_bos[1] != 0);

	for (_test_cases_const_iterator test_iterator = m_test_cases.begin(); test_iterator != m_test_cases.end();
		 ++test_iterator)
	{
		bool			  result_local = true;
		const _test_case& test_case	= *test_iterator;
		const glw::GLuint dst_bo_id =
			test_case.dst_bo_is_sparse ? m_sparse_bos[test_case.dst_bo_sparse_id] : m_immutable_bo;
		const glw::GLuint src_bo_id =
			test_case.src_bo_is_sparse ? m_sparse_bos[test_case.src_bo_sparse_id] : m_immutable_bo;

		/* Initialize immutable BO data (if used) */
		if (dst_bo_id == m_immutable_bo || src_bo_id == m_immutable_bo)
		{
			m_gl.bindBuffer(GL_ARRAY_BUFFER, m_immutable_bo);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

			m_gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
							   m_sparse_bo_size_rounded, m_ref_data[0]);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferSubData() call failed.");
		}

		/* Initialize sparse BO data storage */
		for (unsigned int n_sparse_bo = 0; n_sparse_bo < sizeof(m_sparse_bos) / sizeof(m_sparse_bos[0]); ++n_sparse_bo)
		{
			const bool is_dst_bo = (dst_bo_id == m_sparse_bos[n_sparse_bo]);
			const bool is_src_bo = (src_bo_id == m_sparse_bos[n_sparse_bo]);

			if (!is_dst_bo && !is_src_bo)
				continue;

			m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
			m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_sparse_bos[n_sparse_bo]);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

			if (is_dst_bo)
			{
				m_gl.bufferPageCommitmentARB(GL_COPY_WRITE_BUFFER, test_case.dst_bo_commit_start_offset,
											 test_case.dst_bo_commit_size, GL_TRUE); /* commit */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
			}

			if (is_src_bo)
			{
				m_gl.bufferPageCommitmentARB(GL_COPY_WRITE_BUFFER, test_case.src_bo_commit_start_offset,
											 test_case.src_bo_commit_size, GL_TRUE); /* commit */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
			}

			m_gl.bufferSubData(GL_COPY_READ_BUFFER, 0, /* offset */
							   m_sparse_bo_size_rounded, m_ref_data[1 + n_sparse_bo]);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferSubData() call failed.");

			m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
								   0,											 /* writeOffset */
								   m_sparse_bo_size_rounded);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");
		} /* for (both sparse BOs) */

		/* Set up the bindings */
		m_gl.bindBuffer(GL_COPY_READ_BUFFER, src_bo_id);
		m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, dst_bo_id);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		/* Issue the copy op */
		m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, test_case.src_bo_start_offset,
							   test_case.dst_bo_start_offset, test_case.n_bytes_to_copy);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

		/* Retrieve the destination buffer's contents. The BO used for the previous copy op might have
		 * been a sparse BO, so copy its storage to a helper immutable BO */
		const unsigned short* dst_bo_data_ptr = NULL;

		m_gl.bindBuffer(GL_COPY_READ_BUFFER, dst_bo_id);
		m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_helper_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
							   0,											 /* writeOffset */
							   m_sparse_bo_size_rounded);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

		dst_bo_data_ptr = (const unsigned short*)m_gl.mapBufferRange(GL_COPY_WRITE_BUFFER, 0, /* offset */
																	 m_sparse_bo_size_rounded, GL_MAP_READ_BIT);

		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBufferRange() call failed.");

		/* Verify the retrieved data:
		 *
		 * 1. Check the bytes which precede the copy op dst offset. These should be equal to
		 *    the destination buffer's reference data within the committed memory region.
		 **/
		if (test_case.dst_bo_start_offset != 0 && test_case.dst_bo_commit_start_offset < test_case.dst_bo_start_offset)
		{
			DE_ASSERT(((test_case.dst_bo_start_offset - test_case.dst_bo_commit_start_offset) % sizeof(short)) == 0);

			const unsigned int n_valid_values = static_cast<unsigned int>(
				(test_case.dst_bo_start_offset - test_case.dst_bo_commit_start_offset) / sizeof(short));

			for (unsigned int n_value = 0; n_value < n_valid_values && result_local; ++n_value)
			{
				const int dst_data_offset = static_cast<int>(sizeof(short) * n_value);

				if (dst_data_offset >= test_case.dst_bo_commit_start_offset &&
					dst_data_offset < test_case.dst_bo_commit_start_offset + test_case.dst_bo_commit_size)
				{
					const unsigned short expected_short_value =
						*(unsigned short*)((unsigned char*)test_case.dst_bo_ref_data + dst_data_offset);
					const unsigned short found_short_value =
						*(unsigned short*)((unsigned char*)dst_bo_data_ptr + dst_data_offset);

					if (expected_short_value != found_short_value)
					{
						m_testCtx.getLog()
							<< tcu::TestLog::Message << "Malformed data found in the copy op's destination BO, "
														"preceding the region modified by the copy op. "
							<< "Destination BO id:" << dst_bo_id << " ("
							<< ((test_case.dst_bo_is_sparse) ? "sparse buffer)" : "immutable buffer)")
							<< ", commited region: " << test_case.dst_bo_commit_start_offset << ":"
							<< (test_case.dst_bo_commit_start_offset + test_case.dst_bo_commit_size)
							<< ", copy region: " << test_case.dst_bo_start_offset << ":"
							<< (test_case.dst_bo_start_offset + test_case.n_bytes_to_copy)
							<< ". Source BO id:" << src_bo_id << " ("
							<< ((test_case.src_bo_is_sparse) ? "sparse buffer)" : "immutable buffer)")
							<< ", commited region: " << test_case.src_bo_commit_start_offset << ":"
							<< (test_case.src_bo_commit_start_offset + test_case.src_bo_commit_size)
							<< ", copy region: " << test_case.src_bo_start_offset << ":"
							<< (test_case.src_bo_start_offset + test_case.n_bytes_to_copy) << ". Expected value of "
							<< expected_short_value << ", found value of " << found_short_value
							<< " at dst data offset of " << dst_data_offset << "." << tcu::TestLog::EndMessage;

						result_local = false;
					}
				}
			} /* for (all preceding values which should not have been affected by the copy op) */
		}	 /* if (copy op did not modify the beginning of the destination buffer storage) */

		/* 2. Check if the data written to the destination buffer object is correct. */
		for (unsigned int n_copied_short_value = 0;
			 n_copied_short_value < test_case.n_bytes_to_copy / sizeof(short) && result_local; ++n_copied_short_value)
		{
			const int src_data_offset =
				static_cast<unsigned int>(test_case.src_bo_start_offset + sizeof(short) * n_copied_short_value);
			const int dst_data_offset =
				static_cast<unsigned int>(test_case.dst_bo_start_offset + sizeof(short) * n_copied_short_value);

			if (dst_data_offset >= test_case.dst_bo_commit_start_offset &&
				dst_data_offset < test_case.dst_bo_commit_start_offset + test_case.dst_bo_commit_size &&
				src_data_offset >= test_case.src_bo_commit_start_offset &&
				src_data_offset < test_case.src_bo_commit_start_offset + test_case.src_bo_commit_size)
			{
				const unsigned short expected_short_value =
					*(unsigned short*)((unsigned char*)test_case.src_bo_ref_data + src_data_offset);
				const unsigned short found_short_value =
					*(unsigned short*)((unsigned char*)dst_bo_data_ptr + dst_data_offset);

				if (expected_short_value != found_short_value)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Malformed data found in the copy op's destination BO. "
									   << "Destination BO id:" << dst_bo_id << " ("
									   << ((test_case.dst_bo_is_sparse) ? "sparse buffer)" : "immutable buffer)")
									   << ", commited region: " << test_case.dst_bo_commit_start_offset << ":"
									   << (test_case.dst_bo_commit_start_offset + test_case.dst_bo_commit_size)
									   << ", copy region: " << test_case.dst_bo_start_offset << ":"
									   << (test_case.dst_bo_start_offset + test_case.n_bytes_to_copy)
									   << ". Source BO id:" << src_bo_id << " ("
									   << ((test_case.src_bo_is_sparse) ? "sparse buffer)" : "immutable buffer)")
									   << ", commited region: " << test_case.src_bo_commit_start_offset << ":"
									   << (test_case.src_bo_commit_start_offset + test_case.src_bo_commit_size)
									   << ", copy region: " << test_case.src_bo_start_offset << ":"
									   << (test_case.src_bo_start_offset + test_case.n_bytes_to_copy)
									   << ". Expected value of " << expected_short_value << ", found value of "
									   << found_short_value << " at dst data offset of " << dst_data_offset << "."
									   << tcu::TestLog::EndMessage;

					result_local = false;
				}
			}
		}

		/* 3. Verify the remaining data in the committed part of the destination buffer object is left intact. */
		const unsigned int commit_region_end_offset =
			test_case.dst_bo_commit_start_offset + test_case.dst_bo_commit_size;
		const unsigned int copy_region_end_offset = test_case.dst_bo_start_offset + test_case.n_bytes_to_copy;

		if (commit_region_end_offset > copy_region_end_offset)
		{
			DE_ASSERT(((commit_region_end_offset - copy_region_end_offset) % sizeof(short)) == 0);

			const unsigned int n_valid_values =
				static_cast<unsigned int>((commit_region_end_offset - copy_region_end_offset) / sizeof(short));

			for (unsigned int n_value = 0; n_value < n_valid_values && result_local; ++n_value)
			{
				const int dst_data_offset = static_cast<int>(copy_region_end_offset + sizeof(short) * n_value);

				if (dst_data_offset >= test_case.dst_bo_commit_start_offset &&
					dst_data_offset < test_case.dst_bo_commit_start_offset + test_case.dst_bo_commit_size)
				{
					const unsigned short expected_short_value =
						*(unsigned short*)((unsigned char*)test_case.dst_bo_ref_data + dst_data_offset);
					const unsigned short found_short_value =
						*(unsigned short*)((unsigned char*)dst_bo_data_ptr + dst_data_offset);

					if (expected_short_value != found_short_value)
					{
						m_testCtx.getLog()
							<< tcu::TestLog::Message << "Malformed data found in the copy op's destination BO, "
														"following the region modified by the copy op. "
							<< "Destination BO id:" << dst_bo_id << " ("
							<< ((test_case.dst_bo_is_sparse) ? "sparse buffer)" : "immutable buffer)")
							<< ", commited region: " << test_case.dst_bo_commit_start_offset << ":"
							<< (test_case.dst_bo_commit_start_offset + test_case.dst_bo_commit_size)
							<< ", copy region: " << test_case.dst_bo_start_offset << ":"
							<< (test_case.dst_bo_start_offset + test_case.n_bytes_to_copy)
							<< ". Source BO id:" << src_bo_id << " ("
							<< ((test_case.src_bo_is_sparse) ? "sparse buffer)" : "immutable buffer)")
							<< ", commited region: " << test_case.src_bo_commit_start_offset << ":"
							<< (test_case.src_bo_commit_start_offset + test_case.src_bo_commit_size)
							<< ", copy region: " << test_case.src_bo_start_offset << ":"
							<< (test_case.src_bo_start_offset + test_case.n_bytes_to_copy) << ". Expected value of "
							<< expected_short_value << ", found value of " << found_short_value
							<< " at dst data offset of " << dst_data_offset << "." << tcu::TestLog::EndMessage;

						result_local = false;
					}
				}
			} /* for (all preceding values which should not have been affected by the copy op) */
		}	 /* if (copy op did not modify the beginning of the destination buffer storage) */

		/* Unmap the buffer storage */
		m_gl.unmapBuffer(GL_COPY_WRITE_BUFFER);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");

		/* Clean up */
		for (unsigned int n_sparse_bo = 0; n_sparse_bo < sizeof(m_sparse_bos) / sizeof(m_sparse_bos[0]); ++n_sparse_bo)
		{
			const bool is_dst_bo = (dst_bo_id == m_sparse_bos[n_sparse_bo]);
			const bool is_src_bo = (src_bo_id == m_sparse_bos[n_sparse_bo]);

			if (is_dst_bo || is_src_bo)
			{
				m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bos[n_sparse_bo]);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

				m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, m_sparse_bo_size_rounded, GL_FALSE); /* commit */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
			}
		}

		result &= result_local;
	} /* for (all test cases) */

	return result;
}

/** Allocates reference buffers, fills them with data and updates the m_ref_data array. */
void CopyOpsBufferStorageTestCase::initReferenceData()
{
	DE_ASSERT(m_sparse_bo_size_rounded != 0);
	DE_ASSERT((m_sparse_bo_size_rounded % 2) == 0);
	DE_ASSERT(sizeof(short) == 2);

	for (unsigned int n_ref_data_buffer = 0; n_ref_data_buffer < sizeof(m_ref_data) / sizeof(m_ref_data[0]);
		 ++n_ref_data_buffer)
	{
		DE_ASSERT(m_ref_data[n_ref_data_buffer] == DE_NULL);

		m_ref_data[n_ref_data_buffer] = new unsigned short[m_sparse_bo_size_rounded / 2];

		/* Write reference values. */
		for (unsigned int n_short_value = 0; n_short_value < m_sparse_bo_size_rounded / 2; ++n_short_value)
		{
			m_ref_data[n_ref_data_buffer][n_short_value] =
				(unsigned short)((n_ref_data_buffer + 1) * (n_short_value + 1));
		}
	} /* for (all reference data buffers) */
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool CopyOpsBufferStorageTestCase::initTestCaseGlobal()
{
	m_sparse_bo_size		 = 2 * 3 * 4 * m_page_size;
	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_sparse_bo_size, m_page_size);

	initReferenceData();

	/* Initialize the sparse buffer object */
	m_gl.genBuffers(1, m_sparse_bos + 1);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bos[1]);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_ARRAY_BUFFER, m_sparse_bo_size_rounded, DE_NULL, /* data */
					   GL_SPARSE_STORAGE_BIT_ARB);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	/* Initialize the immutable buffer objects used by the test */
	for (unsigned int n_bo = 0; n_bo < 2; /* helper + immutable BO used for the copy ops */
		 ++n_bo)
	{
		glw::GLuint* bo_id_ptr = (n_bo == 0) ? &m_helper_bo : &m_immutable_bo;
		glw::GLenum  flags	 = GL_DYNAMIC_STORAGE_BIT;

		if (n_bo == 0)
		{
			flags |= GL_MAP_READ_BIT;
		}

		/* Initialize the immutable buffer object */
		m_gl.genBuffers(1, bo_id_ptr);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

		m_gl.bindBuffer(GL_ARRAY_BUFFER, *bo_id_ptr);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferStorage(GL_ARRAY_BUFFER, m_sparse_bo_size_rounded, m_ref_data[0], flags);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");
	}

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool CopyOpsBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Remember the BO id */
	m_sparse_bos[0] = sparse_bo;

	/* Initialize test cases, if this is the first call to initTestCaseIteration() */
	if (m_test_cases.size() == 0)
	{
		initTestCases();
	}

	/* Make sure all pages of the provided sparse BO are de-committed before
	 * ::execute() is called. */
	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bos[0]);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
								 m_sparse_bo_size_rounded, GL_FALSE); /* commit */

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

	return result;
}

/** Fills m_test_cases with test case descriptors. Each such descriptor defines
 *  a single copy op use case.
 *
 * The descriptors are then iterated over in ::execute(), defining the testing
 * behavior of the test copy ops buffer storage test case.
 */
void CopyOpsBufferStorageTestCase::initTestCases()
{
	/* We need to use the following destination & source BO configurations:
	 *
	 * Dst: sparse    BO 1;  Src: sparse    BO 2
	 * Dst: sparse    BO 1;  Src: immutable BO
	 * Dst: immutable BO;    Src: sparse    BO 1
	 * Dst: sparse    BO 1;  Src: sparse    BO 1
	 */
	unsigned int n_test_case = 0;

	for (unsigned int n_bo_configuration = 0; n_bo_configuration < 4; /* as per the comment */
		 ++n_bo_configuration, ++n_test_case)
	{
		glw::GLuint		dst_bo_sparse_id = 0;
		bool			dst_bo_is_sparse = false;
		unsigned short* dst_bo_ref_data  = DE_NULL;
		glw::GLuint		src_bo_sparse_id = 0;
		bool			src_bo_is_sparse = false;
		unsigned short* src_bo_ref_data  = DE_NULL;

		switch (n_bo_configuration)
		{
		case 0:
		{
			dst_bo_sparse_id = 0;
			dst_bo_is_sparse = true;
			dst_bo_ref_data  = m_ref_data[1];
			src_bo_sparse_id = 1;
			src_bo_is_sparse = true;
			src_bo_ref_data  = m_ref_data[2];

			break;
		}

		case 1:
		{
			dst_bo_sparse_id = 0;
			dst_bo_is_sparse = true;
			dst_bo_ref_data  = m_ref_data[1];
			src_bo_is_sparse = false;
			src_bo_ref_data  = m_ref_data[0];

			break;
		}

		case 2:
		{
			dst_bo_is_sparse = false;
			dst_bo_ref_data  = m_ref_data[0];
			src_bo_sparse_id = 0;
			src_bo_is_sparse = true;
			src_bo_ref_data  = m_ref_data[1];

			break;
		}

		case 3:
		{
			dst_bo_sparse_id = 0;
			dst_bo_is_sparse = true;
			dst_bo_ref_data  = m_ref_data[1];
			src_bo_sparse_id = 0;
			src_bo_is_sparse = true;
			src_bo_ref_data  = m_ref_data[1];

			break;
		}

		default:
		{
			TCU_FAIL("Invalid BO configuration index");
		}
		} /* switch (n_bo_configuration) */

		/* Need to test the copy operation in three different scenarios,
		 * in regard to the destination buffer:
		 *
		 * a) All pages of the destination region are committed.
		 * b) Half of the pages of the destination region are committed.
		 * c) None of the pages of the destination region are committed.
		 *
		 * Destination region spans from 0 to half of the memory we use
		 * for the testing purposes.
		 */
		DE_ASSERT((m_sparse_bo_size_rounded % m_page_size) == 0);
		DE_ASSERT((m_sparse_bo_size_rounded % 2) == 0);
		DE_ASSERT((m_sparse_bo_size_rounded % 4) == 0);

		for (unsigned int n_dst_region = 0; n_dst_region < 3; /* as per the comment */
			 ++n_dst_region)
		{
			glw::GLuint dst_bo_commit_size		   = 0;
			glw::GLuint dst_bo_commit_start_offset = 0;

			switch (n_dst_region)
			{
			case 0:
			{
				dst_bo_commit_start_offset = 0;
				dst_bo_commit_size		   = m_sparse_bo_size_rounded / 2;

				break;
			}

			case 1:
			{
				dst_bo_commit_start_offset = m_sparse_bo_size_rounded / 4;
				dst_bo_commit_size		   = m_sparse_bo_size_rounded / 4;

				break;
			}

			case 2:
			{
				dst_bo_commit_start_offset = 0;
				dst_bo_commit_size		   = 0;

				break;
			}

			default:
			{
				TCU_FAIL("Invalid destination region configuration index");
			}
			} /* switch (n_dst_region) */

			/* Same goes for the source region.
			 *
			 * Source region spans from m_sparse_bo_size_rounded / 2 to
			 * m_sparse_bo_size_rounded.
			 *
			 **/
			for (unsigned int n_src_region = 0; n_src_region < 3; /* as per the comment */
				 ++n_src_region)
			{
				glw::GLuint src_bo_commit_size		   = 0;
				glw::GLuint src_bo_commit_start_offset = 0;

				switch (n_src_region)
				{
				case 0:
				{
					src_bo_commit_start_offset = m_sparse_bo_size_rounded / 2;
					src_bo_commit_size		   = m_sparse_bo_size_rounded / 2;

					break;
				}

				case 1:
				{
					src_bo_commit_start_offset = 3 * m_sparse_bo_size_rounded / 4;
					src_bo_commit_size		   = m_sparse_bo_size_rounded / 4;

					break;
				}

				case 2:
				{
					src_bo_commit_start_offset = m_sparse_bo_size_rounded / 2;
					src_bo_commit_size		   = 0;

					break;
				}

				default:
				{
					TCU_FAIL("Invalid source region configuration index");
				}
				} /* switch (n_src_region) */

				/* Initialize the test case descriptor */
				_test_case test_case;

				test_case.dst_bo_commit_size		 = dst_bo_commit_size;
				test_case.dst_bo_commit_start_offset = dst_bo_commit_start_offset;
				test_case.dst_bo_sparse_id			 = dst_bo_sparse_id;
				test_case.dst_bo_is_sparse			 = dst_bo_is_sparse;
				test_case.dst_bo_ref_data			 = dst_bo_ref_data;
				test_case.dst_bo_start_offset		 = static_cast<glw::GLint>(sizeof(short) * n_test_case);
				test_case.n_bytes_to_copy			 = static_cast<glw::GLint>(
					m_sparse_bo_size_rounded / 2 - test_case.dst_bo_start_offset - sizeof(short) * n_test_case);
				test_case.src_bo_commit_size		 = src_bo_commit_size;
				test_case.src_bo_commit_start_offset = src_bo_commit_start_offset;
				test_case.src_bo_sparse_id			 = src_bo_sparse_id;
				test_case.src_bo_is_sparse			 = src_bo_is_sparse;
				test_case.src_bo_ref_data			 = src_bo_ref_data;
				test_case.src_bo_start_offset		 = m_sparse_bo_size_rounded / 2;

				DE_ASSERT(test_case.dst_bo_commit_size >= 0);
				DE_ASSERT(test_case.dst_bo_commit_start_offset >= 0);
				DE_ASSERT(test_case.dst_bo_ref_data != DE_NULL);
				DE_ASSERT(test_case.dst_bo_start_offset >= 0);
				DE_ASSERT(test_case.n_bytes_to_copy >= 0);
				DE_ASSERT(test_case.src_bo_commit_size >= 0);
				DE_ASSERT(test_case.src_bo_commit_start_offset >= 0);
				DE_ASSERT(test_case.src_bo_ref_data != DE_NULL);
				DE_ASSERT(test_case.src_bo_start_offset >= 0);

				m_test_cases.push_back(test_case);
			} /* for (all source region commit configurations) */
		}	 /* for (all destination region commit configurations) */
	}		  /* for (all BO configurations which need to be tested) */
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
IndirectDispatchBufferStorageTestCase::IndirectDispatchBufferStorageTestCase(const glw::Functions& gl,
																			 tcu::TestContext&	 testContext,
																			 glw::GLint			   page_size)
	: m_dispatch_draw_call_args_start_offset(-1)
	, m_expected_ac_value(0)
	, m_gl(gl)
	, m_global_wg_size_x(2048)
	, m_helper_bo(0)
	, m_local_wg_size_x(1023) /* must stay in sync with the local work-groups's size hardcoded in m_po's body! */
	, m_page_size(page_size)
	, m_po(0)
	, m_sparse_bo(0)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
	, m_testCtx(testContext)
{
	/* Left blank intentionally */
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void IndirectDispatchBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_po != 0)
	{
		m_gl.deleteProgram(m_po);

		m_po = 0;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void IndirectDispatchBufferStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool IndirectDispatchBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool result = true;

	/* Set up the buffer bindings */
	m_gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_helper_bo);
	m_gl.bindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed");

	m_gl.bindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, /* index */
						 m_helper_bo, 12,			  /* offset */
						 4);						  /* size */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferRange() call failed.");

	/* Bind the compute program */
	m_gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

	/* Zero out atomic counter value. */
	const unsigned int zero_ac_value = 0;

	m_gl.bufferSubData(GL_ATOMIC_COUNTER_BUFFER, 12, /* offset */
					   4,							 /* size */
					   &zero_ac_value);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferSubData() call failed.");

	m_expected_ac_value = zero_ac_value;

	/* Run the test only in a configuration where all arguments are local in
	 * committed memory page(s): reading arguments from uncommitted pages means
	 * reading undefined data, which can result in huge dispatches that
	 * effectively hang the test.
	 */
	m_gl.bufferPageCommitmentARB(GL_DISPATCH_INDIRECT_BUFFER, 0,	 /* offset */
								 m_sparse_bo_size_rounded, GL_TRUE); /* commit */

	m_expected_ac_value += m_global_wg_size_x * m_local_wg_size_x;

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call(s) failed.");

	/* Copy the indirect dispatch call args data from the helper BO to the sparse BO */
	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
						   m_dispatch_draw_call_args_start_offset, sizeof(unsigned int) * 3);

	/* Run the program */
	m_gl.dispatchComputeIndirect(m_dispatch_draw_call_args_start_offset);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDispatchComputeIndirect() call failed.");

	/* Extract the AC value and verify it */
	const unsigned int* ac_data_ptr =
		(const unsigned int*)m_gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 12, /* offset */
												 4,							   /* length */
												 GL_MAP_READ_BIT);

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBufferRange() call failed.");

	if (*ac_data_ptr != m_expected_ac_value && result)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid atomic counter value encountered. "
													   "Expected value: ["
						   << m_expected_ac_value << "]"
													 ", found:"
													 "["
						   << *ac_data_ptr << "]." << tcu::TestLog::EndMessage;

		result = false;
	}

	/* Unmap the buffer before we move on with the next iteration */
	m_gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool IndirectDispatchBufferStorageTestCase::initTestCaseGlobal()
{
	bool result = true;

	/* One of the cases the test case implementation needs to support is the scenario
	 * where the indirect call arguments are located on the boundary of two (or more) memory pages,
	 * and some of the pages are not committed.
	 *
	 * There are two scenarios which can happen:
	 *
	 * a) page size >= sizeof(uint) * 3: Allocate two pages, arg start offset: (page_size - 4) aligned to 4.
	 *                                   The alignment is a must, since we'll be feeding the offset to an indirect dispatch call.
	 * b) page size <  sizeof(uint) * 3: Allocate as many pages as needed, disable some of the pages.
	 *
	 * For code clarity, the two cases are handled by separate branches, although they could be easily
	 * merged.
	 */
	const int n_indirect_dispatch_call_arg_bytes = sizeof(unsigned int) * 3;

	if (m_page_size >= n_indirect_dispatch_call_arg_bytes)
	{
		/* Indirect dispatch call args must be aligned to 4 */
		DE_ASSERT(m_page_size >= 4);

		m_dispatch_draw_call_args_start_offset = SparseBufferTestUtilities::alignOffset(m_page_size - 4, 4);
		m_sparse_bo_size = m_dispatch_draw_call_args_start_offset + n_indirect_dispatch_call_arg_bytes;
	}
	else
	{
		m_dispatch_draw_call_args_start_offset = 0;
		m_sparse_bo_size					   = n_indirect_dispatch_call_arg_bytes;
	}

	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_sparse_bo_size, m_page_size);

	/* Set up the helper buffer object. Its structure is as follows:
	 *
	 * [ 0-11]: Indirect dispatch call args
	 * [12-15]: Atomic counter value storage
	 */
	unsigned int	   helper_bo_data[4] = { 0 };
	const unsigned int n_helper_bo_bytes = sizeof(helper_bo_data);

	helper_bo_data[0] = m_global_wg_size_x; /* num_groups_x */
	helper_bo_data[1] = 1;					/* num_groups_y */
	helper_bo_data[2] = 1;					/* num_groups_z */
	helper_bo_data[3] = 0;					/* default atomic counter value */

	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferData(GL_ARRAY_BUFFER, n_helper_bo_bytes, helper_bo_data, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferData() call failed.");

	/* Set up the test compute program object */
	static const char* cs_body = "#version 430 core\n"
								 "\n"
								 "layout(local_size_x = 1023)          in;\n"
								 "layout(binding      = 0, offset = 0) uniform atomic_uint ac;\n"
								 "\n"
								 "void main()\n"
								 "{\n"
								 "    atomicCounterIncrement(ac);\n"
								 "}\n";

	m_po = SparseBufferTestUtilities::createComputeProgram(m_gl, &cs_body, 1); /* n_cs_body_parts */

	result = (m_po != 0);

	return result;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool IndirectDispatchBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	/* Set up the sparse bufffer. */
	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				 /* offset */
								 m_sparse_bo_size_rounded, GL_TRUE); /* commit */

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
InvalidateBufferStorageTestCase::InvalidateBufferStorageTestCase(const glw::Functions& gl,
																 tcu::TestContext& testContext, glw::GLint page_size)
	: m_gl(gl)
	, m_n_pages_to_use(4)
	, m_page_size(page_size)
	, m_sparse_bo(0)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
{
	(void)testContext;
	DE_ASSERT((m_n_pages_to_use % 2) == 0);
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void InvalidateBufferStorageTestCase::deinitTestCaseGlobal()
{
	/* Stub */
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void InvalidateBufferStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool InvalidateBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool result = true;

	/* Since we cannot really perform any validation related to whether buffer
	 * storage invalidation works corectly, all this test can really do is to verify
	 * if the implementation does not crash when both entry-points are used against
	 * a sparse buffer object.
	 */
	for (unsigned int n_entry_point = 0; n_entry_point < 2; /* glInvalidateBuffer(), glInvalidateBufferSubData() */
		 ++n_entry_point)
	{
		const bool should_test_invalidate_buffer = (n_entry_point == 0);

		/* For glInvalidateBufferSubData(), we need to test two different ranges. */
		for (int n_iteration = 0; n_iteration < ((should_test_invalidate_buffer) ? 1 : 2); ++n_iteration)
		{
			if (should_test_invalidate_buffer)
			{
				m_gl.invalidateBufferData(m_sparse_bo);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glInvalidateBufferData() call failed.");
			}
			else
			{
				m_gl.invalidateBufferSubData(m_sparse_bo, 0, /* offset */
											 m_sparse_bo_size_rounded * ((n_iteration == 0) ? 1 : 2));
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glInvalidateBufferSubData() call failed.");
			}
		} /* for (all iterations) */
	}	 /* for (both entry-points) */

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool InvalidateBufferStorageTestCase::initTestCaseGlobal()
{
	const unsigned int n_bytes_needed = m_n_pages_to_use * m_page_size;

	/* Determine the number of bytes both the helper and the sparse buffer
	 * object need to be able to hold, at maximum */
	m_sparse_bo_size		 = n_bytes_needed;
	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(n_bytes_needed, m_page_size);

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool InvalidateBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	/* Set up the sparse bufffer. */
	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				 /* offset */
								 m_sparse_bo_size_rounded, GL_TRUE); /* commit */

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
PixelPackBufferStorageTestCase::PixelPackBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext,
															   glw::GLint page_size)
	: m_color_rb(0)
	, m_color_rb_height(1024)
	, m_color_rb_width(1024)
	, m_fbo(0)
	, m_gl(gl)
	, m_helper_bo(0)
	, m_page_size(page_size)
	, m_po(0)
	, m_ref_data_ptr(DE_NULL)
	, m_ref_data_size(0)
	, m_sparse_bo(0)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
	, m_testCtx(testContext)
	, m_vao(0)
{
	m_ref_data_size = m_color_rb_width * m_color_rb_height * 4; /* rgba */
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void PixelPackBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_color_rb != 0)
	{
		m_gl.deleteRenderbuffers(1, &m_color_rb);

		m_color_rb = 0;
	}

	if (m_fbo != 0)
	{
		m_gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_ref_data_ptr != DE_NULL)
	{
		delete[] m_ref_data_ptr;

		m_ref_data_ptr = DE_NULL;
	}

	if (m_po != 0)
	{
		m_gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_vao != 0)
	{
		m_gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void PixelPackBufferStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool PixelPackBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool result = true;

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	m_gl.bindBuffer(GL_PIXEL_PACK_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

	/* Run three separate iterations:
	 *
	 * a) All pages that are going to hold the texture data are committed.
	 * b) Use a zig-zag memory page commitment layout patern.
	 * b) No pages are committed.
	 */
	for (unsigned int n_iteration = 0; n_iteration < 3; ++n_iteration)
	{
		bool result_local = true;

		/* Set up the memory page commitment & the storage contents*/
		switch (n_iteration)
		{
		case 0:
		{
			m_gl.bufferPageCommitmentARB(GL_PIXEL_PACK_BUFFER, 0,			 /* offset */
										 m_sparse_bo_size_rounded, GL_TRUE); /* commit */
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

			break;
		}

		case 1:
		{
			const unsigned int n_pages = 1 + m_ref_data_size / m_page_size;

			DE_ASSERT((m_ref_data_size % m_page_size) == 0);

			for (unsigned int n_page = 0; n_page < n_pages; ++n_page)
			{
				const bool should_commit = ((n_page % 2) == 0);

				m_gl.bufferPageCommitmentARB(GL_PIXEL_PACK_BUFFER, m_page_size * n_page, m_page_size,
											 should_commit ? GL_TRUE : GL_FALSE);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
			} /* for (all relevant memory pages) */

			break;
		}

		case 2:
		{
			/* Do nothing - all pages already de-committed  */
			break;
		}

		default:
		{
			TCU_FAIL("Invalid iteration index");
		}
		} /* switch (n_iteration) */

		/* Draw full screen quad to generate the black-to-white gradient */
		const unsigned char* read_data_ptr = NULL;

		m_gl.useProgram(m_po);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

		m_gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays() call failed.");

		/* Read a framebuffer pixel data */
		m_gl.readPixels(0,																	/* x */
						0,																	/* y */
						m_color_rb_width, m_color_rb_height, GL_RGBA, GL_UNSIGNED_BYTE, 0); /* pixels */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels() call failed.");

		m_gl.copyBufferSubData(GL_PIXEL_PACK_BUFFER, GL_COPY_READ_BUFFER, 0, /* readOffset */
							   0,											 /* writeOffset */
							   m_ref_data_size);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

		read_data_ptr = (unsigned char*)m_gl.mapBufferRange(GL_COPY_READ_BUFFER, 0, /* offset */
															m_ref_data_size, GL_MAP_READ_BIT);

		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBufferRange() call failed.");

		/* Verify the data */
		unsigned int		 n_current_tex_data_byte	  = 0;
		const unsigned char* read_data_traveller_ptr	  = (const unsigned char*)read_data_ptr;
		const unsigned char* reference_data_traveller_ptr = (const unsigned char*)m_ref_data_ptr;

		for (unsigned int y = 0; y < m_color_rb_height && result_local; ++y)
		{
			for (unsigned int x = 0; x < m_color_rb_width && result_local; ++x)
			{
				for (unsigned int n_component = 0; n_component < 4 /* rgba */ && result_local; ++n_component)
				{
					unsigned char expected_value		 = 0;
					bool		  is_from_committed_page = true;

					if (n_iteration == 1) /* zig-zag */
					{
						is_from_committed_page = ((n_current_tex_data_byte / m_page_size) % 2) == 0;
					}
					else if (n_iteration == 2) /* no pages committed */
					{
						is_from_committed_page = false;
					}

					if (is_from_committed_page)
					{
						expected_value = *reference_data_traveller_ptr;
					}

					if (is_from_committed_page && de::abs(expected_value - *read_data_traveller_ptr) > 1)
					{
						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid texel data (channel:" << n_component
										   << ")"
											  " found at X:"
										   << x << ", "
												   "Y:"
										   << y << ")."
												   " Expected value:"
										   << expected_value << ","
																" found value:"
										   << *reference_data_traveller_ptr << tcu::TestLog::EndMessage;

						result_local = false;
					}

					n_current_tex_data_byte++;
					read_data_traveller_ptr++;
					reference_data_traveller_ptr++;
				} /* for (all components) */
			}	 /* for (all columns) */
		}		  /* for (all rows) */

		m_gl.unmapBuffer(GL_COPY_READ_BUFFER);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");

		read_data_ptr = DE_NULL;
		result &= result_local;

		/* Clean up */
		m_gl.bufferPageCommitmentARB(GL_PIXEL_PACK_BUFFER, 0,			  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
	} /* for (three iterations) */

	m_gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool PixelPackBufferStorageTestCase::initTestCaseGlobal()
{
	/* Determine vertex shader and fragment shader that will generate black-to-white gradient. */
	const char* gradient_fs_code = "#version 330 core\n"
								   "\n"
								   "out vec4 result;\n"
								   "\n"
								   "void main()\n"
								   "{\n"
								   "    float c = 1.0 - (gl_FragCoord.y - 0.5) / 1023.0;\n"
								   "    result  = vec4(c);\n"
								   "}\n";

	const char* gradient_vs_code = "#version 330\n"
								   "\n"
								   "void main()\n"
								   "{\n"
								   "    switch (gl_VertexID)\n"
								   "    {\n"
								   "        case 0: gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); break;\n"
								   "        case 1: gl_Position = vec4( 1.0, -1.0, 0.0, 1.0); break;\n"
								   "        case 2: gl_Position = vec4(-1.0,  1.0, 0.0, 1.0); break;\n"
								   "        case 3: gl_Position = vec4( 1.0,  1.0, 0.0, 1.0); break;\n"
								   "    }\n"
								   "}\n";

	m_po = SparseBufferTestUtilities::createProgram(m_gl, &gradient_fs_code, 1, /* n_fs_body_parts */
													&gradient_vs_code, 1,		/* n_vs_body_parts*/
													NULL,						/* attribute_names */
													NULL,						/* attribute_locations */
													GL_NONE,					/* attribute_properties */
													0,							/* tf_varyings */
													0,							/* n_tf_varyings */
													0);							/* tf_varying_mode */
	if (m_po == 0)
	{
		TCU_FAIL("Failed to link the test program");
	}

	/* Generate and bind VAO */
	m_gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenVertexArrays() call failed.");

	m_gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindVertexArray() call failed.");

	/* Generate and bind FBO */
	m_gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenFramebuffers() call failed.");

	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindFramebuffer() call failed.");

	m_gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadBuffer() call failed.");

	/* Generate and bind RBO and attach it to FBO as a color attachment */
	m_gl.genRenderbuffers(1, &m_color_rb);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenRenderbuffers() call failed.");

	m_gl.bindRenderbuffer(GL_RENDERBUFFER, m_color_rb);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindRenderbuffer() call failed.");

	m_gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, m_color_rb_width, m_color_rb_height);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glRenderbufferStorage() call failed.");

	m_gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rb);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFramebufferRenderbuffer() call failed.");

	if (m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		throw tcu::NotSupportedError("Cannot execute the test - driver does not support rendering"
									 "to a GL_RGBA8 renderbuffer-based color attachment");
	}

	m_gl.viewport(0, /* x */
				  0, /* y */
				  m_color_rb_width, m_color_rb_height);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glViewport() call failed.");

	/* Determine what sparse buffer storage size we are going to need*/
	m_sparse_bo_size		 = m_ref_data_size;
	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_sparse_bo_size, m_page_size);

	/* Prepare the texture data */
	unsigned char* ref_data_traveller_ptr = DE_NULL;

	m_ref_data_ptr		   = new unsigned char[m_ref_data_size];
	ref_data_traveller_ptr = m_ref_data_ptr;

	for (unsigned int y = 0; y < m_color_rb_height; ++y)
	{
		const unsigned char color = (unsigned char)((1.0f - float(y) / float(m_color_rb_height - 1)) * 255.0f);

		for (unsigned int x = 0; x < m_color_rb_width; ++x)
		{
			memset(ref_data_traveller_ptr, color, 4); /* rgba */

			ref_data_traveller_ptr += 4; /* rgba */
		}								 /* for (all columns) */
	}									 /* for (all rows) */

	/* Set up the helper buffer object. */
	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_COPY_READ_BUFFER, m_ref_data_size, m_ref_data_ptr, GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool PixelPackBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
PixelUnpackBufferStorageTestCase::PixelUnpackBufferStorageTestCase(const glw::Functions& gl,
																   tcu::TestContext& testContext, glw::GLint page_size)
	: m_gl(gl)
	, m_helper_bo(0)
	, m_page_size(page_size)
	, m_read_data_ptr(DE_NULL)
	, m_sparse_bo(0)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
	, m_testCtx(testContext)
	, m_texture_data_ptr(DE_NULL)
	, m_texture_data_size(0)
	, m_to(0)
	, m_to_data_zero(DE_NULL)
	, m_to_height(1024)
	, m_to_width(1024)
{
	m_texture_data_size = m_to_width * m_to_height * 4; /* rgba */
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void PixelUnpackBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_read_data_ptr != DE_NULL)
	{
		delete[] m_read_data_ptr;

		m_read_data_ptr = DE_NULL;
	}

	if (m_texture_data_ptr != DE_NULL)
	{
		delete[] m_texture_data_ptr;

		m_texture_data_ptr = DE_NULL;
	}

	if (m_to != 0)
	{
		m_gl.deleteTextures(1, &m_to);

		m_to = 0;
	}

	if (m_to_data_zero != DE_NULL)
	{
		delete[] m_to_data_zero;

		m_to_data_zero = DE_NULL;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void PixelUnpackBufferStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool PixelUnpackBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool result = true;

	m_gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bindTexture(GL_TEXTURE_2D, m_to);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindTexture() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindTexture() call failed.");

	/* Run three separate iterations:
	 *
	 * a) All pages holding the source texture data are committed.
	 * b) Use a zig-zag memory page commitment layout patern.
	 * b) No pages are committed.
	 */
	for (unsigned int n_iteration = 0; n_iteration < 3; ++n_iteration)
	{
		bool result_local = true;

		/* Set up the memory page commitment & the storage contents*/
		switch (n_iteration)
		{
		case 0:
		{
			m_gl.bufferPageCommitmentARB(GL_PIXEL_UNPACK_BUFFER, 0,			 /* offset */
										 m_sparse_bo_size_rounded, GL_TRUE); /* commit */
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

			m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_PIXEL_UNPACK_BUFFER, 0, /* readOffset */
								   0,											   /* writeOffset */
								   m_texture_data_size);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

			break;
		}

		case 1:
		{
			const unsigned int n_pages = m_texture_data_size / m_page_size;

			for (unsigned int n_page = 0; n_page < n_pages; ++n_page)
			{
				const bool should_commit = ((n_page % 2) == 0);

				m_gl.bufferPageCommitmentARB(GL_PIXEL_UNPACK_BUFFER, m_page_size * n_page, m_page_size,
											 should_commit ? GL_TRUE : GL_FALSE);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

				if (should_commit)
				{
					m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_PIXEL_UNPACK_BUFFER,
										   m_page_size * n_page, /* readOffset */
										   m_page_size * n_page, /* writeOffset */
										   m_page_size);
					GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");
				}
			} /* for (all relevant memory pages) */

			break;
		}

		case 2:
		{
			/* Do nothing */
			break;
		}

		default:
		{
			TCU_FAIL("Invalid iteration index");
		}
		} /* switch (n_iteration) */

		/* Clean up the base mip-map's contents before we proceeding with updating it
		 * with data downloaded from the BO, in order to avoid situation where silently
		 * failing glTexSubImage2D() calls slip past unnoticed */
		m_gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
						   0,				 /* xoffset */
						   0,				 /* yoffset */
						   m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, m_to_data_zero);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexSubImage2D() call failed.");

		m_gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		/* Update the base mip-map's contents */
		m_gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
						   0,				 /* xoffset */
						   0,				 /* yoffset */
						   m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, (const glw::GLvoid*)0);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexSubImage2D() call failed.");

		/* Read back the stored mip-map data */
		memset(m_read_data_ptr, 0xFF, m_texture_data_size);

		m_gl.getTexImage(GL_TEXTURE_2D, 0, /* level */
						 GL_RGBA, GL_UNSIGNED_BYTE, m_read_data_ptr);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetTexImage() call failed.");

		/* Verify the data */
		unsigned int n_current_tex_data_byte	= 0;
		const char*  read_data_traveller_ptr	= (const char*)m_read_data_ptr;
		const char*  texture_data_traveller_ptr = (const char*)m_texture_data_ptr;

		for (unsigned int y = 0; y < m_to_height && result_local; ++y)
		{
			for (unsigned int x = 0; x < m_to_width && result_local; ++x)
			{
				for (unsigned int n_component = 0; n_component < 4 /* rgba */ && result_local; ++n_component)
				{
					char expected_value			= 0;
					bool is_from_committed_page = true;

					if (n_iteration == 1) /* zig-zag */
					{
						is_from_committed_page = ((n_current_tex_data_byte / m_page_size) % 2) == 0;
					}
					else if (n_iteration == 2) /* no pages committed */
					{
						is_from_committed_page = false;
					}

					if (is_from_committed_page)
					{
						expected_value = *texture_data_traveller_ptr;
					}

					if (is_from_committed_page && de::abs(expected_value - *read_data_traveller_ptr) >= 1)
					{
						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid texel data (channel:" << n_component
										   << ")"
											  " found at X:"
										   << x << ", "
												   "Y:"
										   << y << ")."
												   " Expected value:"
										   << expected_value << ","
																" found value:"
										   << *read_data_traveller_ptr << tcu::TestLog::EndMessage;

						result_local = false;
					}

					n_current_tex_data_byte++;
					read_data_traveller_ptr++;
					texture_data_traveller_ptr++;
				} /* for (all components) */
			}	 /* for (all columns) */
		}		  /* for (all rows) */

		result &= result_local;

		/* Clean up */
		m_gl.bufferPageCommitmentARB(GL_PIXEL_UNPACK_BUFFER, 0,			  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
	} /* for (three iterations) */

	m_gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool PixelUnpackBufferStorageTestCase::initTestCaseGlobal()
{
	/* Determine sparse buffer storage size */
	m_sparse_bo_size		 = m_texture_data_size;
	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_sparse_bo_size, m_page_size);

	/* Prepare the texture data */
	unsigned char* texture_data_traveller_ptr = DE_NULL;

	m_read_data_ptr			   = new unsigned char[m_texture_data_size];
	m_texture_data_ptr		   = new unsigned char[m_texture_data_size];
	texture_data_traveller_ptr = m_texture_data_ptr;

	for (unsigned int y = 0; y < m_to_height; ++y)
	{
		for (unsigned int x = 0; x < m_to_width; ++x)
		{
			const unsigned char color = (unsigned char)(float(x) / float(m_to_width - 1) * 255.0f);

			memset(texture_data_traveller_ptr, color, 4); /* rgba */

			texture_data_traveller_ptr += 4; /* rgba */
		}									 /* for (all columns) */
	}										 /* for (all rows) */

	m_to_data_zero = new unsigned char[m_texture_data_size];

	memset(m_to_data_zero, 0, m_texture_data_size);

	/* Set up the helper buffer object */
	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_COPY_READ_BUFFER, m_texture_data_size, m_texture_data_ptr, GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	/* Set up texture object storage */
	m_gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenTextures() call failed.");

	m_gl.bindTexture(GL_TEXTURE_2D, m_to);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindTexture() call failed.");

	m_gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
					  GL_RGBA8, m_to_width, m_to_height);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexStorage2D() call failed.");

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool PixelUnpackBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param ibo_usage                  Specifies if an indexed draw call should be used by the test. For more details,
 *                                    please see documentation for _ibo_usage.
 *  @param use_color_data             true to use the color data for the tested draw call;
 *                                    false to omit usage of attribute data.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
QuadsBufferStorageTestCase::QuadsBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext,
													   glw::GLint page_size, _ibo_usage ibo_usage, bool use_color_data)
	: m_attribute_color_location(0)	/* predefined attribute locations */
	, m_attribute_position_location(1) /* predefined attribute locations */
	, m_color_data_offset(0)
	, m_data(DE_NULL)
	, m_data_size(0)
	, m_data_size_rounded(0)
	, m_fbo(0)
	, m_gl(gl)
	, m_helper_bo(0)
	, m_ibo_data_offset(-1)
	, m_ibo_usage(ibo_usage)
	, m_n_quad_delta_x(5)
	, m_n_quad_delta_y(5)
	, m_n_quad_height(5)
	, m_n_quad_width(5)
	, m_n_quads_x(100) /* as per spec */
	, m_n_quads_y(100) /* as per spec */
	, m_n_vertices_to_draw(0)
	, m_pages_committed(false)
	, m_po(0)
	, m_sparse_bo(0)
	, m_testCtx(testContext)
	, m_to(0)
	, m_to_height(1024) /* as per spec */
	, m_to_width(1024)  /* as per spec */
	, m_use_color_data(use_color_data)
	, m_vao(0)
	, m_vbo_data_offset(-1)
{
	/*
	 * Each quad = 2 triangles, 1 triangle = 3 vertices, 1 vertex = 4 components.
	 * The inefficient representation has been used on purpose - we want the data to take
	 * more than 64KB so that it is guaranteed that it will span over more than 1 page.
	 */
	m_data_size = 0;

	m_n_vertices_to_draw = m_n_quads_x * /* quads in X */
						   m_n_quads_y * /* quads in Y */
						   2 *			 /* triangles */
						   3;			 /* vertices per triangle */

	m_data_size = static_cast<glw::GLuint>(m_n_vertices_to_draw * 4 /* components */ * sizeof(float));

	if (m_ibo_usage != IBO_USAGE_NONE)
	{
		DE_ASSERT(m_n_vertices_to_draw < 65536);

		m_data_size = static_cast<glw::GLuint>(m_data_size + (m_n_vertices_to_draw * sizeof(unsigned short)));
	}

	if (m_use_color_data)
	{
		m_data_size = static_cast<glw::GLuint>(m_data_size +
											   (m_n_vertices_to_draw * sizeof(unsigned char) * 4 * /* rgba components */
												2 *												   /* triangles */
												3)); /* vertices per triangle */
	}

	m_data_size_rounded = SparseBufferTestUtilities::alignOffset(m_data_size, page_size);
}

/** Allocates a data buffer and fills it with vertex/index/color data. Vertex data is always stored,
 *  index data only if m_ibo_usage is different from IBO_USAGE_NONE. Color data is only saved if
 *  m_use_color_data is true.
 *
 *  @param out_data              Deref will be used to store a pointer to the allocated data buffer.
 *                               Ownership is transferred to the caller. Must not be NULL.
 *  @param out_vbo_data_offset   Deref will be used to store an offset, from which VBO data starts,
 *                               relative to the beginning of *out_data. Must not be NULL.
 *  @param out_ibo_data_offset   Deref will be used to store an offset, from which IBO data starts,
 *                               relative to the beginning of *out_data. May be NULL if m_ibo_usage
 *                               is IBO_USAGE_NONE.
 *  @param out_color_data_offset Deref will be used to store na offset, from which color data starts,
 *                               relative to the beginning of *out_data. May be NULL if m_use_color_data
 *                               is false.
 *
 */
void QuadsBufferStorageTestCase::createTestData(unsigned char** out_data, unsigned int* out_vbo_data_offset,
												unsigned int* out_ibo_data_offset,
												unsigned int* out_color_data_offset) const
{
	unsigned char* data_traveller_ptr = NULL;

	*out_data			 = new unsigned char[m_data_size];
	*out_vbo_data_offset = 0;

	data_traveller_ptr = *out_data;

	for (unsigned int n_quad_y = 0; n_quad_y < m_n_quads_y; ++n_quad_y)
	{
		for (unsigned int n_quad_x = 0; n_quad_x < m_n_quads_x; ++n_quad_x)
		{
			const unsigned int quad_start_x_px = n_quad_x * (m_n_quad_delta_x + m_n_quad_width);
			const unsigned int quad_start_y_px = n_quad_y * (m_n_quad_delta_y + m_n_quad_height);
			const unsigned int quad_end_x_px   = quad_start_x_px + m_n_quad_width;
			const unsigned int quad_end_y_px   = quad_start_y_px + m_n_quad_height;

			const float quad_end_x_ss   = float(quad_end_x_px) / float(m_to_width) * 2.0f - 1.0f;
			const float quad_end_y_ss   = float(quad_end_y_px) / float(m_to_height) * 2.0f - 1.0f;
			const float quad_start_x_ss = float(quad_start_x_px) / float(m_to_width) * 2.0f - 1.0f;
			const float quad_start_y_ss = float(quad_start_y_px) / float(m_to_height) * 2.0f - 1.0f;

			/*  1,4--5
			 *  |\   |
			 *  | \  |
			 *  2----3,6
			 */
			const float v1_4[] = {
				quad_start_x_ss, quad_start_y_ss, 0.0f, /* z */
				1.0f,									/* w */
			};
			const float v2[] = {
				quad_start_x_ss, quad_end_y_ss, 0.0f, /* z */
				1.0f								  /* w */
			};
			const float v3_6[] = {
				quad_end_x_ss, quad_end_y_ss, 0.0f, /* z */
				1.0f								/* w */
			};
			const float v5[] = {
				quad_end_x_ss, quad_start_y_ss, 0.0f, /* z */
				1.0f								  /* w */
			};

			memcpy(data_traveller_ptr, v1_4, sizeof(v1_4));
			data_traveller_ptr += sizeof(v1_4);

			memcpy(data_traveller_ptr, v2, sizeof(v2));
			data_traveller_ptr += sizeof(v2);

			memcpy(data_traveller_ptr, v3_6, sizeof(v3_6));
			data_traveller_ptr += sizeof(v3_6);

			memcpy(data_traveller_ptr, v1_4, sizeof(v1_4));
			data_traveller_ptr += sizeof(v1_4);

			memcpy(data_traveller_ptr, v5, sizeof(v5));
			data_traveller_ptr += sizeof(v5);

			memcpy(data_traveller_ptr, v3_6, sizeof(v3_6));
			data_traveller_ptr += sizeof(v3_6);
		} /* for (all quads in X) */
	}	 /* for (all quads in Y) */

	/* Set up index data if needed */
	if (m_ibo_usage != IBO_USAGE_NONE)
	{
		*out_ibo_data_offset = static_cast<unsigned int>(data_traveller_ptr - *out_data);

		for (int index = m_n_vertices_to_draw - 1; index >= 0; --index)
		{
			*(unsigned short*)data_traveller_ptr = (unsigned short)index;
			data_traveller_ptr += sizeof(unsigned short);
		} /* for (all index values) */
	}	 /* if (m_use_ibo) */
	else
	{
		*out_ibo_data_offset = 0;
	}

	/* Set up color data if needed */
	if (m_use_color_data)
	{
		*out_color_data_offset = static_cast<unsigned int>(data_traveller_ptr - *out_data);

		for (unsigned int n_quad = 0; n_quad < m_n_quads_x * m_n_quads_y; ++n_quad)
		{
			/* Use magic formulas to generate a color data set for the quads. The data
			 * needs to be duplicated for 6 vertices forming a single quad. */
			for (unsigned int n_vertex = 0; n_vertex < 6; ++n_vertex)
			{
				/* Red */
				*data_traveller_ptr = static_cast<unsigned char>(n_quad % 256); //((n_quad + 15) * 14) % 256;
				data_traveller_ptr++;

				/* Green */
				*data_traveller_ptr = static_cast<unsigned char>(((n_quad + 32) * 7) % 255);
				data_traveller_ptr++;

				/* Blue */
				*data_traveller_ptr = static_cast<unsigned char>(((n_quad + 7) * 53) % 255);
				data_traveller_ptr++;

				/* Alpha */
				*data_traveller_ptr = static_cast<unsigned char>(((n_quad + 13) * 3) % 255);
				data_traveller_ptr++;
			}
		} /* for (all quads) */
	}
	else
	{
		*out_color_data_offset = 0;
	}
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void QuadsBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_data != DE_NULL)
	{
		delete[] m_data;

		m_data = DE_NULL;
	}

	if (m_fbo != 0)
	{
		m_gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_po != 0)
	{
		m_gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_to != 0)
	{
		m_gl.deleteTextures(1, &m_to);

		m_to = 0;
	}

	if (m_vao != 0)
	{
		m_gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void QuadsBufferStorageTestCase::deinitTestCaseIteration()
{
	/* If the test executed successfully, all pages should've been released by now.
	 * However, if it failed, it's a good idea to de-commit them at this point.
	 * Redundant calls are fine spec-wise, too. */
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,			 /* offset */
									 m_data_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool QuadsBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	bool result = true;

	m_gl.viewport(0, /* x */
				  0, /* y */
				  m_to_width, m_to_height);

	m_gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

	m_gl.clearColor(0.0f,  /* red */
					0.0f,  /* green */
					0.0f,  /* blue */
					0.0f); /* alpha */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glClearColor() call failed.");

	/* Render the quads.
	 *
	 * Run in two iterations:
	 *
	 * a) Iteration 1 performs the draw call with the VBO & IBO pages committed
	 * b) Iteration 2 performs the draw call with the VBO & IBO pages without any
	 *    physical backing.
	 **/
	for (unsigned int n_iteration = 0; n_iteration < 2; ++n_iteration)
	{
		initSparseBO((n_iteration == 0), /* decommit pages after upload */
					 (sparse_bo_storage_flags & GL_DYNAMIC_STORAGE_BIT) != 0);

		m_gl.clear(GL_COLOR_BUFFER_BIT);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glClear() call failed.");

		switch (m_ibo_usage)
		{
		case IBO_USAGE_NONE:
		{
			m_gl.drawArrays(GL_TRIANGLES, 0, /* first */
							m_n_vertices_to_draw);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays() call failed.");

			break;
		}

		case IBO_USAGE_INDEXED_DRAW_CALL:
		{
			m_gl.drawElements(GL_TRIANGLES, m_n_vertices_to_draw, GL_UNSIGNED_SHORT,
							  (glw::GLvoid*)(intptr_t)m_ibo_data_offset);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawElements() call failed.");

			break;
		}

		case IBO_USAGE_INDEXED_RANGED_DRAW_CALL:
		{
			m_gl.drawRangeElements(GL_TRIANGLES, 0,		 /* start */
								   m_n_vertices_to_draw, /* end */
								   m_n_vertices_to_draw, /* count */
								   GL_UNSIGNED_SHORT, (glw::GLvoid*)(intptr_t)m_ibo_data_offset);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawRangeElements() call failed.");

			break;
		}

		default:
		{
			TCU_FAIL("Unrecognized IBO usage value");
		}
		} /* switch (m_ibo_usage) */

		/* Retrieve the rendered output */
		unsigned char* read_data = new unsigned char[m_to_width * m_to_height * sizeof(char) * 4 /* rgba */];

		m_gl.readPixels(0, /* x */
						0, /* y */
						m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, read_data);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels() call failed.");

		/* IF the data pages have been committed by the time the draw call was made, validate the data.
		 *
		 * For each quad region (be it filled or not), check the center and make sure the retrieved
		 * color corresponds to the expected value.
		 */
		if (m_pages_committed)
		{
			for (unsigned int n_quad_region_y = 0; n_quad_region_y < m_n_quads_y * 2; /* quad + empty "delta" region */
				 ++n_quad_region_y)
			{
				for (unsigned int n_quad_region_x = 0; n_quad_region_x < m_n_quads_x * 2; ++n_quad_region_x)
				{
					/* Determine the expected texel color */
					unsigned char expected_color[4];
					unsigned char found_color[4];
					bool		  is_delta_region = (n_quad_region_x % 2) != 0 || (n_quad_region_y % 2) != 0;

					if (is_delta_region)
					{
						memset(expected_color, 0, sizeof(expected_color));
					} /* if (is_delta_region) */
					else
					{
						if (m_use_color_data)
						{
							const unsigned int   n_quad_x = n_quad_region_x / 2;
							const unsigned int   n_quad_y = n_quad_region_y / 2;
							const unsigned char* data_ptr =
								m_data + m_color_data_offset +
								(n_quad_y * m_n_quads_x + n_quad_x) * 4 /* rgba */ * 6; /* vertices */

							memcpy(expected_color, data_ptr, sizeof(expected_color));
						} /* if (m_use_color_data) */
						else
						{
							memset(expected_color, 255, sizeof(expected_color));
						}
					}

					/* Do we have a match? */
					DE_ASSERT(m_n_quad_height == m_n_quad_delta_y);
					DE_ASSERT(m_n_quad_width == m_n_quad_delta_x);

					const unsigned int sample_texel_x = m_n_quad_delta_x * n_quad_region_x;
					const unsigned int sample_texel_y = m_n_quad_delta_y * n_quad_region_y;

					memcpy(found_color, read_data + (sample_texel_y * m_to_width + sample_texel_x) * 4, /* rgba */
						   sizeof(found_color));

					if (memcmp(expected_color, found_color, sizeof(expected_color)) != 0)
					{
						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid color found at "
																	   "("
										   << sample_texel_x << ", " << sample_texel_y << "): "
																						  "Expected color:"
																						  "("
										   << (int)expected_color[0] << ", " << (int)expected_color[1] << ", "
										   << (int)expected_color[2] << ", " << (int)expected_color[3] << "), "
																										  "Found:"
																										  "("
										   << (int)found_color[0] << ", " << (int)found_color[1] << ", "
										   << (int)found_color[2] << ", " << (int)found_color[3] << "), "
										   << tcu::TestLog::EndMessage;

						result = false;
						goto end;
					}
				} /* for (all quads in X) */
			}	 /* for (all quads in Y) */
		}		  /* if (m_pages_committed) */

		delete[] read_data;
		read_data = DE_NULL;
	} /* for (both iterations) */

end:
	return result;
}

/** Creates test data and fills the result buffer object (whose ID is stored under m_helper_bo)
 *  with the data.
 */
void QuadsBufferStorageTestCase::initHelperBO()
{
	DE_ASSERT(m_data == DE_NULL);
	DE_ASSERT(m_helper_bo == 0);

	createTestData(&m_data, &m_vbo_data_offset, &m_ibo_data_offset, &m_color_data_offset);

	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_COPY_READ_BUFFER, m_data_size, m_data, 0); /* flags */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");
}

/** Creates test data (if necessary), configures sparse buffer's memory page commitment
 *  and uploads the test data to the buffer object. Finally, the method configures the
 *  vertex array object, used by ::execute() at the draw call time.
 *
 *  @param decommit_data_pages_after_upload true to de-commit memory pages requested before
 *                                          uploading the vertex/index/color data.
 *  @param is_dynamic_storage               true to upload the data via glBufferSubData() call.
 *                                          false to use a copy op for the operation.
 **/
void QuadsBufferStorageTestCase::initSparseBO(bool decommit_data_pages_after_upload, bool is_dynamic_storage)
{
	/* Set up the vertex buffer object. */
	if (m_data == DE_NULL)
	{
		createTestData(&m_data, &m_vbo_data_offset, &m_ibo_data_offset, &m_color_data_offset);
	}
	else
	{
		/* Sanity checks */
		if (m_ibo_usage != IBO_USAGE_NONE)
		{
			DE_ASSERT(m_vbo_data_offset != m_ibo_data_offset);
		}

		if (m_use_color_data)
		{
			DE_ASSERT(m_vbo_data_offset != m_ibo_data_offset);
			DE_ASSERT(m_ibo_data_offset != m_color_data_offset);
		}
	}

	/* Commit as many pages as we need to upload the data */
	m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,			/* offset */
								 m_data_size_rounded, GL_TRUE); /* commit */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_pages_committed = true;

	/* Upload the data */
	if (is_dynamic_storage)
	{
		m_gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
						   m_data_size, m_data);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferSubData() call failed.");
	}
	else
	{
		/* Sparse BO cannot be directly uploaded data to. Copy the data from a helper BO */
		m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_ARRAY_BUFFER, 0, /* readOffset */
							   0,										/* writeOffset */
							   m_data_size);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");
	}

	/* Set the VAO up */
	m_gl.vertexAttribPointer(m_attribute_position_location, 4, /* size */
							 GL_FLOAT, GL_FALSE,			   /* normalized */
							 0,								   /* stride */
							 (glw::GLvoid*)(intptr_t)m_vbo_data_offset);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glVertexAttribPointer() call failed.");

	m_gl.enableVertexAttribArray(m_attribute_position_location); /* index */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEnableVertexAttribPointer() call failed.");

	if (m_use_color_data)
	{
		m_gl.vertexAttribPointer(m_attribute_color_location, 4, /* size */
								 GL_UNSIGNED_BYTE, GL_TRUE,		/* normalized */
								 0,								/* stride */
								 (glw::GLvoid*)(intptr_t)m_color_data_offset);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glVertexAttribPointer() call failed.");

		m_gl.enableVertexAttribArray(m_attribute_color_location); /* index */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEnableVertexAttribPointer() call failed.");
	}
	else
	{
		m_gl.vertexAttrib4f(m_attribute_color_location, 1.0f, 1.0f, 1.0f, 1.0f);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glVertexAttrib4f() call failed.");

		m_gl.disableVertexAttribArray(m_attribute_color_location);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDisableVertexAttribArray() call failed.");
	}

	if (m_ibo_usage != IBO_USAGE_NONE)
	{
		m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");
	} /* if (m_use_ibo) */

	/* If we were requested to do so, decommit the pages we have just uploaded
	 * the data to.
	 */
	if (decommit_data_pages_after_upload)
	{
		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,			 /* offset */
									 m_data_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_pages_committed = false;
	} /* if (decommit_data_pages_after_upload) */
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool QuadsBufferStorageTestCase::initTestCaseGlobal()
{
	bool result = true;

	/* Set up the texture object */
	DE_ASSERT(m_to == 0);

	m_gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenTextures() call failed.");

	m_gl.bindTexture(GL_TEXTURE_2D, m_to);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindTexture() call failed.");

	m_gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
					  GL_RGBA8, m_to_width, m_to_height);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexStorage2D() call failed.");

	/* Set up the framebuffer object */
	DE_ASSERT(m_fbo == 0);

	m_gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenFramebuffers() call failed.");

	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindFramebuffer() call failed.");

	m_gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to, 0); /* level */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFramebufferTexture2D() call failed.");

	/* Set up the vertex array object */
	DE_ASSERT(m_vao == 0);

	m_gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenVertexArrays() call failed.");

	m_gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindVertexArray() call failed.");

	/* Init a helper BO */
	initHelperBO();

	/* Set up the program object */
	const char* fs_body = "#version 430 core\n"
						  "\n"
						  "flat in  vec4 fs_color;\n"
						  "     out vec4 color;\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    color = fs_color;\n"
						  "}\n";

	const char* vs_body = "#version 430 core\n"
						  "\n"
						  "in vec4 color;\n"
						  "in vec4 position;\n"
						  "\n"
						  "flat out vec4 fs_color;\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    fs_color    = color;\n"
						  "    gl_Position = position;\n"
						  "}\n";

	const unsigned int attribute_locations[] = { m_attribute_color_location, m_attribute_position_location };
	const char*		   attribute_names[]	 = { "color", "position" };
	const unsigned int n_attributes			 = sizeof(attribute_locations) / sizeof(attribute_locations[0]);

	DE_ASSERT(m_po == 0);

	m_po = SparseBufferTestUtilities::createProgram(m_gl, &fs_body, 1, /* n_fs_body_parts */
													&vs_body, 1, attribute_names, attribute_locations,
													n_attributes); /* n_vs_body_parts */

	if (m_po == 0)
	{
		result = false;

		goto end;
	}

end:
	return result;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool QuadsBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
QueryBufferStorageTestCase::QueryBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext,
													   glw::GLint page_size)
	: m_gl(gl)
	, m_helper_bo(0)
	, m_n_triangles(15)
	, m_page_size(page_size)
	, m_po(0)
	, m_qo(0)
	, m_sparse_bo(0)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
	, m_testCtx(testContext)
	, m_vao(0)
{
	/* Left blank on purpose */
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void QueryBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_po != 0)
	{
		m_gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_qo != 0)
	{
		m_gl.deleteQueries(1, &m_qo);

		m_qo = 0;
	}

	if (m_vao != 0)
	{
		m_gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void QueryBufferStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool QueryBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	static const unsigned char data_r8_zero = 0;
	bool					   result		= true;

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

	/* Run two separate iterations:
	 *
	 * a) The page holding the query result value is committed.
	 * b) The page is not committed.
	 */
	for (unsigned int n_iteration = 0; n_iteration < 2; ++n_iteration)
	{
		const bool should_commit_page = (n_iteration == 0);

		/* Set up the memory page commitment */
		m_gl.bufferPageCommitmentARB(GL_QUERY_BUFFER, 0, /* offset */
									 m_sparse_bo_size_rounded, should_commit_page ? GL_TRUE : GL_FALSE);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		/* Run the draw call */
		m_gl.beginQuery(GL_PRIMITIVES_GENERATED, m_qo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBeginQuery() call failed.");

		m_gl.drawArrays(GL_TRIANGLES, 0, /* first */
						m_n_triangles * 3);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays() call failed.");

		m_gl.endQuery(GL_PRIMITIVES_GENERATED);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEndQuery() call failed.");

		/* Copy the query result to the sparse buffer */
		for (unsigned int n_getter_call = 0; n_getter_call < 4; ++n_getter_call)
		{
			glw::GLsizei result_n_bytes;

			switch (n_getter_call)
			{
			case 0:
			{
				result_n_bytes = sizeof(glw::GLint);
				m_gl.getQueryObjectiv(m_qo, GL_QUERY_RESULT, (glw::GLint*)0); /* params */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetQueryObjectiv() call failed.");

				break;
			}

			case 1:
			{
				result_n_bytes = sizeof(glw::GLint);
				m_gl.getQueryObjectuiv(m_qo, GL_QUERY_RESULT, (glw::GLuint*)0); /* params */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetQueryObjectuiv() call failed.");

				break;
			}

			case 2:
			{
				result_n_bytes = sizeof(glw::GLint64);
				m_gl.getQueryObjecti64v(m_qo, GL_QUERY_RESULT, (glw::GLint64*)0);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetQueryObjecti64v() call failed.");

				break;
			}

			case 3:
			{
				result_n_bytes = sizeof(glw::GLint64);
				m_gl.getQueryObjectui64v(m_qo, GL_QUERY_RESULT, (glw::GLuint64*)0);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetQueryObjectui64v() call failed.");

				break;
			}

			default:
			{
				TCU_FAIL("Invalid getter call type");
			}
			} /* switch (n_getter_call) */

			/* Verify the query result */
			if (should_commit_page)
			{
				const glw::GLint64* result_ptr = NULL;

				m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_helper_bo);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

				m_gl.clearBufferData(GL_COPY_WRITE_BUFFER, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &data_r8_zero);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glClearBufferData() call failed.");

				m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
									   0,											 /* writeOffset */
									   result_n_bytes);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

				result_ptr = (const glw::GLint64*)m_gl.mapBuffer(GL_COPY_WRITE_BUFFER, GL_READ_ONLY);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBuffer() call failed.");

				if (*result_ptr != m_n_triangles)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Invalid query result stored in a sparse buffer. Found: "
										  "["
									   << *result_ptr << "]"
														 ", expected: "
														 "["
									   << m_n_triangles << "]" << tcu::TestLog::EndMessage;

					result = false;
				}

				m_gl.unmapBuffer(GL_COPY_WRITE_BUFFER);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");
			} /* for (all query getter call types) */
		}	 /* if (should_commit_page) */
	}		  /* for (both iterations) */

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool QueryBufferStorageTestCase::initTestCaseGlobal()
{
	/* Determine sparse buffer storage size */
	m_sparse_bo_size		 = sizeof(glw::GLuint64);
	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_sparse_bo_size, m_page_size);

	/* Set up the test program object */
	static const char* vs_body = "#version 140\n"
								 "\n"
								 "void main()\n"
								 "{\n"
								 "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
								 "}\n";

	m_po = SparseBufferTestUtilities::createProgram(m_gl, DE_NULL, /* fs_body_parts */
													0,			   /* n_fs_body_parts */
													&vs_body, 1,   /* n_vs_body_parts */
													DE_NULL,	   /* attribute_names */
													DE_NULL,	   /* attribute_locations */
													0);			   /* n_attribute_locations */

	if (m_po == 0)
	{
		TCU_FAIL("Test program linking failure");
	}

	/* Set up the helper buffer object */
	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_COPY_WRITE_BUFFER, sizeof(glw::GLint64), DE_NULL, /* data */
					   GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	/* Set up the test query object */
	m_gl.genQueries(1, &m_qo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenQueries() call failed.");

	/* Set up the VAO */
	m_gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenVertexArrays() call failed.");

	m_gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindVertexArray() call failed.");

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool QueryBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	/* Set up the sparse buffer. */
	m_gl.bindBuffer(GL_QUERY_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
SSBOStorageTestCase::SSBOStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size)
	: m_gl(gl)
	, m_helper_bo(0)
	, m_page_size(page_size)
	, m_po(0)
	, m_po_local_wg_size(1024)
	, m_result_bo(0)
	, m_sparse_bo(0)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
	, m_ssbo_data(DE_NULL)
	, m_testCtx(testContext)
{
	/* min max for SSBO size from GL_ARB_shader_storage_buffer_object is 16mb;
	 *
	 * The specified amount of space lets the test write as many
	 * ints as it's possible, with an assertion that our CS
	 * uses a std140 layout and the SSBO only contains an unsized array.
	 *
	 * NOTE: 16777216 % 1024 = 0, which is awesome because we can hardcode the
	 *       local workgroup size directly in the CS.
	 */
	m_sparse_bo_size		 = (16777216 / (sizeof(int) * 4) /* std140 */) * (sizeof(int) * 4);
	m_sparse_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_sparse_bo_size, m_page_size);
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void SSBOStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_po != 0)
	{
		m_gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_result_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_result_bo);

		m_result_bo = 0;
	}

	if (m_ssbo_data != DE_NULL)
	{
		delete[] m_ssbo_data;

		m_ssbo_data = DE_NULL;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void SSBOStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool SSBOStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool result = true;

	/* Bind the program object */
	m_gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

	/* Set up shader storage buffer bindings */
	m_gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, /* index */
						m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferBase() call failed.");

	/* Run the test in three iterations:
	 *
	 * a) All required pages are committed.
	 * b) Only half of the pages are committed (in a zig-zag layout)
	 * c) None of the pages are committed.
	 */
	for (unsigned int n_iteration = 0; n_iteration < 3; ++n_iteration)
	{
		bool result_local = true;

		/* Set up the shader storage buffer object's memory backing */
		const bool   is_zigzag_ssbo			  = (n_iteration == 1);
		unsigned int ssbo_commit_size		  = 0;
		unsigned int ssbo_commit_start_offset = 0;

		switch (n_iteration)
		{
		case 0:
		case 1:
		{
			ssbo_commit_size		 = m_sparse_bo_size_rounded;
			ssbo_commit_start_offset = 0;

			if (is_zigzag_ssbo)
			{
				const unsigned int n_pages = ssbo_commit_size / m_page_size;

				for (unsigned int n_page = 0; n_page < n_pages; n_page += 2)
				{
					m_gl.bufferPageCommitmentARB(GL_SHADER_STORAGE_BUFFER, m_page_size * n_page, /* offset */
												 m_page_size,									 /* size */
												 GL_TRUE);										 /* commit */
				} /* for (all memory pages) */
			}
			else
			{
				m_gl.bufferPageCommitmentARB(GL_SHADER_STORAGE_BUFFER, 0, /* offset */
											 ssbo_commit_size, GL_TRUE);  /* commit */
			}

			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call(s) failed.");

			break;
		}

		case 2:
		{
			/* Use no physical memory backing */
			break;
		}

		default:
		{
			TCU_FAIL("Unrecognized iteration index");
		}
		} /* switch (n_iteration) */

		/* Set up bindings for the copy op */
		m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
		m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

		/* Set up the sparse buffer's data storage */
		m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
							   0,											 /* writeOffset */
							   m_sparse_bo_size);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

		/* Run the compute program */
		DE_ASSERT((m_sparse_bo_size % m_po_local_wg_size) == 0);

		m_gl.dispatchCompute(m_sparse_bo_size / m_po_local_wg_size, 1, /* num_groups_y */
							 1);									   /* num_groups_z */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDispatchCompute() call failed.");

		/* Flush the caches */
		m_gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMemoryBarrier() call failed.");

		/* Copy SSBO's storage to a mappable result BO */
		m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_sparse_bo);
		m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_result_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

		m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
							   0,											 /* writeOffset */
							   m_sparse_bo_size);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

		/* Map the result BO to the process space */
		unsigned int		current_ssbo_offset = 0;
		const unsigned int* ssbo_data_ptr = (const unsigned int*)m_gl.mapBuffer(GL_COPY_WRITE_BUFFER, GL_READ_ONLY);

		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBuffer() call failed.");

		for (unsigned int n_invocation = 0; current_ssbo_offset < m_sparse_bo_size && result_local; ++n_invocation,
						  current_ssbo_offset = static_cast<unsigned int>(current_ssbo_offset +
																		  (sizeof(int) * 4 /* std140 */)))
		{
			const unsigned int n_page = current_ssbo_offset / m_page_size;

			if ((is_zigzag_ssbo && (n_page % 2) == 0) ||
				(!is_zigzag_ssbo && (current_ssbo_offset >= ssbo_commit_start_offset &&
									 current_ssbo_offset < (ssbo_commit_start_offset + ssbo_commit_size))))
			{
				if (ssbo_data_ptr[n_invocation * 4] != (n_invocation + 1))
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Value written to the SSBO at byte "
																   "["
									   << (sizeof(int) * n_invocation) << "]"
																		  " is invalid. Found:"
									   << "[" << ssbo_data_ptr[n_invocation * 4] << "]"
																					", expected:"
									   << "[" << (n_invocation + 1) << "]" << tcu::TestLog::EndMessage;

					result_local = false;
				}
			} /* if (ssbo_data_ptr[n_texel] != 1) */
		}	 /* for (all result values) */

		result &= result_local;

		m_gl.unmapBuffer(GL_COPY_WRITE_BUFFER);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");

		/* Remove the physical backing from the sparse buffer  */
		m_gl.bufferPageCommitmentARB(GL_SHADER_STORAGE_BUFFER, 0,		  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */

		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
	} /* for (three iterations) */

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool SSBOStorageTestCase::initTestCaseGlobal()
{
	/* Set up the test program */
	static const char* cs_body =
		"#version 430 core\n"
		"\n"
		"layout(local_size_x = 1024) in;\n"
		"\n"
		"layout(std140, binding = 0) buffer data\n"
		"{\n"
		"    restrict uint io_values[];\n"
		"};\n"
		"\n"
		"void main()\n"
		"{\n"
		"    uint value_index = gl_GlobalInvocationID.x;\n"
		"    uint new_value   = (io_values[value_index] == value_index) ? (value_index + 1u) : value_index;\n"
		"\n"
		"    io_values[value_index] = new_value;\n"
		"}\n";

	m_po = SparseBufferTestUtilities::createComputeProgram(m_gl, &cs_body, 1); /* n_cs_body_parts */

	/* Set up a data buffer we will use to initialize the SSBO with default data.
	 *
	 * CS uses a std140 layout for the SSBO, so we need to add the additional padding.
	 */
	DE_ASSERT((m_sparse_bo_size) != 0);
	DE_ASSERT((m_sparse_bo_size % (sizeof(int) * 4)) == 0);
	DE_ASSERT((m_sparse_bo_size % 1024) == 0);

	m_ssbo_data = new unsigned int[m_sparse_bo_size / sizeof(int)];

	memset(m_ssbo_data, 0, m_sparse_bo_size);

	for (unsigned int index = 0; index < m_sparse_bo_size / sizeof(int) / 4; ++index)
	{
		/* Mind the std140 rules for arrays of ints */
		m_ssbo_data[4 * index] = index;
	}

	/* During execution, we will need to use a helper buffer object. The BO will hold
	 * data we will be copying into the sparse buffer object for each iteration.
	 */
	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferData(GL_COPY_READ_BUFFER, m_sparse_bo_size, m_ssbo_data, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferData() call failed.");

	/* To retrieve the data written to a sparse SSBO, we need to use another
	 * non-sparse helper BO.
	 */
	m_gl.genBuffers(1, &m_result_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_result_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferData(GL_ARRAY_BUFFER, m_sparse_bo_size, DE_NULL, /* data */
					GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferData() call failed.");

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool SSBOStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	return result;
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 *  @param all_pages_committed        true to provide memory backing for all memory pages holding data used by the test.
 *                                    false to leave some of them uncommitted.
 */
TransformFeedbackBufferStorageTestCase::TransformFeedbackBufferStorageTestCase(const glw::Functions& gl,
																			   tcu::TestContext&	 testContext,
																			   glw::GLint			 page_size,
																			   bool all_pages_committed)
	: m_all_pages_committed(all_pages_committed)
	, m_data_bo(0)
	, m_data_bo_index_data_offset(0)
	, m_data_bo_indexed_indirect_arg_offset(0)
	, m_data_bo_indexed_mdi_arg_offset(0)
	, m_data_bo_regular_indirect_arg_offset(0)
	, m_data_bo_regular_mdi_arg_offset(0)
	, m_data_bo_size(0)
	, m_draw_call_baseInstance(1231)
	, m_draw_call_baseVertex(65537)
	, m_draw_call_first(913)
	, m_draw_call_firstIndex(4)
	, m_gl(gl)
	, m_helper_bo(0)
	, m_index_data(DE_NULL)
	, m_index_data_size(0)
	, m_indirect_arg_data(DE_NULL)
	, m_indirect_arg_data_size(0)
	, m_min_memory_page_span(4) /* as per test spec */
	, m_multidrawcall_drawcount(-1)
	, m_multidrawcall_primcount(-1)
	, m_n_instances_to_test(4)
	, m_n_vertices_per_instance(0)
	, m_page_size(page_size)
	, m_po_ia(0)
	, m_po_sa(0)
	, m_result_bo(0)
	, m_result_bo_size(0)
	, m_result_bo_size_rounded(0)
	, m_testCtx(testContext)
	, m_vao(0)
{
	/* Left blank on purpose */
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void TransformFeedbackBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_data_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_data_bo);

		m_data_bo = 0;
	}

	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_index_data != DE_NULL)
	{
		delete[] m_index_data;

		m_index_data = DE_NULL;
	}

	if (m_indirect_arg_data != DE_NULL)
	{
		delete[] m_indirect_arg_data;

		m_indirect_arg_data = DE_NULL;
	}

	if (m_po_ia != 0)
	{
		m_gl.deleteProgram(m_po_ia);

		m_po_ia = 0;
	}

	if (m_po_sa != 0)
	{
		m_gl.deleteProgram(m_po_sa);

		m_po_sa = 0;
	}

	if (m_result_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_result_bo);

		m_result_bo = 0;
	}

	if (m_vao != 0)
	{
		m_gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool TransformFeedbackBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	bool result = true;

	/* Iterate through two different transform feedback modes we need to test */
	for (unsigned int n_tf_type = 0; n_tf_type < 2; /* interleaved & separate attribs */
		 ++n_tf_type)
	{
		const bool is_ia_iteration = (n_tf_type == 0);

		/* Bind the test PO to the context */
		m_gl.useProgram(is_ia_iteration ? m_po_ia : m_po_sa);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

		/* Set up TF general binding, which is needed for a glClearBufferData() call
		 * we'll be firing shortly.
		 */
		m_gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, /* needed for the subsequent glClearBufferData() call */
						m_result_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		/* Iterate through all draw call types */
		for (unsigned int n_draw_call_type = 0; n_draw_call_type < DRAW_CALL_COUNT; ++n_draw_call_type)
		{
			int				   draw_call_count					= 0; /* != 1 for multi-draw calls only */
			int				   draw_call_first_instance_id[2]   = { -1 };
			int				   draw_call_first_vertex_id[2]		= { -1 };
			int				   draw_call_n_instances[2]			= { 0 };
			int				   draw_call_n_vertices[2]			= { 0 };
			bool			   draw_call_is_vertex_id_ascending = false;
			const _draw_call   draw_call_type					= (_draw_call)n_draw_call_type;
			unsigned int	   n_result_bytes_per_instance[2]   = { 0 };
			const unsigned int n_result_bytes_per_vertex		= sizeof(unsigned int) * 2;
			unsigned int	   n_result_bytes_total				= 0;
			glw::GLuint*	   result_ptr						= DE_NULL;

			m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_data_bo);
			m_gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_data_bo);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

			/* Commit pages needed to execute transform feed-back */
			if (m_all_pages_committed)
			{
				m_gl.bufferPageCommitmentARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0,	/* offset */
											 m_result_bo_size_rounded, GL_TRUE); /* commit */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
			}
			else
			{
				for (unsigned int n_page = 0; n_page < m_result_bo_size_rounded / m_page_size; ++n_page)
				{
					m_gl.bufferPageCommitmentARB(GL_TRANSFORM_FEEDBACK_BUFFER, n_page * m_page_size, /* offset */
												 m_page_size,										 /* size   */
												 (n_page % 2 == 0) ? GL_TRUE : GL_FALSE);			 /* commit */
				}

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
			}

			/* Zero out the target BO before we begin the TF */
			static const unsigned char data_zero = 0;

			m_gl.clearBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &data_zero);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glClearBufferData() call failed.");

			/* Set up transform feed-back buffer bindings */
			DE_ASSERT(m_result_bo_size != 0);

			if (is_ia_iteration)
			{
				DE_ASSERT(m_result_bo != 0);

				m_gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index */
									 m_result_bo, 0,				  /* offset */
									 m_result_bo_size);

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferRange() call failed.");
			}
			else
			{
				DE_ASSERT(m_result_bo_size % 2 == 0);

				m_gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index */
									 m_result_bo, 0,				  /* offset */
									 m_result_bo_size / 2);
				m_gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 1, /* index */
									 m_result_bo, m_result_bo_size / 2, m_result_bo_size / 2);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferRange() call(s) failed.");
			}

			m_gl.beginTransformFeedback(GL_POINTS);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBeginTransformFeedback() call failed.");

			/* NOTE: Some discussion about the expected "vertex id" value:
			 *
			 * In GL 4.5 core spec (Feb2/2015 version), we have:
			 *
			 * >>
			 * The index of any element transferred to the GL by DrawElementsOneInstance
			 * is referred to as its vertex ID, and may be read by a vertex shader as
			 * gl_VertexID. The vertex ID of the ith element transferred is the sum of
			 * basevertex and the value stored in the currently bound element array buffer at
			 * offset indices +i.
			 * <<
			 *
			 * So for glDrawElements*() derivatives, we will be expecting gl_VertexID to be set to
			 * (basevertex + index[i] + i)
			 *
			 * DrawArrays does not support the "base vertex" concept at all:
			 *
			 * >>
			 * The index of any element transferred to the GL by DrawArraysOneInstance
			 * is referred to as its vertex ID, and may be read by a vertex shader as gl_VertexID.
			 * The vertex ID of the ith element transferred is first + i.
			 * <<
			 *
			 * For regular draw calls, gl_VertexID should be of form:
			 *
			 * (first + i)
			 *
			 * In both cases, gl_InstanceID does NOT include the baseinstance value, as per:
			 *
			 * >>
			 * If an enabled vertex attribute array is instanced (it has a non-zero divisor as
			 * specified by VertexAttribDivisor), the element index that is transferred to the GL,
			 * for all vertices, is given by
			 *
			 * floor(instance / divisor) + baseinstance
			 *
			 * The value of instance may be read by a vertex shader as gl_InstanceID, as
			 * described in section 11.1.3.9
			 * <<
			 */
			switch (draw_call_type)
			{
			case DRAW_CALL_INDEXED:
			{
				m_gl.drawElements(GL_POINTS, m_n_vertices_per_instance, GL_UNSIGNED_INT,
								  (const glw::GLvoid*)(intptr_t)m_data_bo_index_data_offset);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawElements() call failed.");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_n_vertices_per_instance;
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = 1;
				draw_call_n_vertices[0]			 = m_n_vertices_per_instance;
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_n_vertices_per_instance;
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_INDEXED_BASE_VERTEX:
			{
				m_gl.drawElementsBaseVertex(GL_POINTS, m_n_vertices_per_instance, GL_UNSIGNED_INT,
											(const glw::GLvoid*)(intptr_t)m_data_bo_index_data_offset,
											m_draw_call_baseVertex);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawElementsBaseVertex() call failed.");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_draw_call_baseVertex + m_n_vertices_per_instance;
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = 1;
				draw_call_n_vertices[0]			 = m_n_vertices_per_instance;
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_n_vertices_per_instance;
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_INDEXED_INDIRECT:
			{
				m_gl.drawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT,
										  (const glw::GLvoid*)(intptr_t)m_data_bo_indexed_indirect_arg_offset);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawElementsIndirect() call failed.");

				draw_call_count				   = 1;
				draw_call_first_instance_id[0] = 0;
				draw_call_first_vertex_id[0] =
					m_draw_call_baseVertex +
					m_index_data[((unsigned int)(intptr_t)m_multidrawcall_index[1] - m_data_bo_index_data_offset) /
								 sizeof(unsigned int)];
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_multidrawcall_count[1];
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * draw_call_n_vertices[0];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_INDEXED_INDIRECT_MULTI:
			{
				m_gl.multiDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT,
											   (const glw::GLvoid*)(intptr_t)m_data_bo_indexed_mdi_arg_offset,
											   m_multidrawcall_drawcount, 0); /* stride */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMultiDrawElementsIndirect() call failed.");

				draw_call_count				   = m_multidrawcall_drawcount;
				draw_call_first_instance_id[0] = 0;
				draw_call_first_instance_id[1] = 0;
				draw_call_first_vertex_id[0] =
					m_draw_call_baseVertex +
					m_index_data[((unsigned int)(intptr_t)m_multidrawcall_index[0] - m_data_bo_index_data_offset) /
								 sizeof(unsigned int)];
				draw_call_first_vertex_id[1] =
					m_draw_call_baseVertex +
					m_index_data[((unsigned int)(intptr_t)m_multidrawcall_index[1] - m_data_bo_index_data_offset) /
								 sizeof(unsigned int)];
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = 1;
				draw_call_n_instances[1]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_multidrawcall_count[0];
				draw_call_n_vertices[1]			 = m_multidrawcall_count[1];
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * draw_call_n_vertices[0];
				n_result_bytes_per_instance[1]   = n_result_bytes_per_vertex * draw_call_n_vertices[1];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0] +
									   n_result_bytes_per_instance[1] * draw_call_n_instances[1];

				break;
			}

			case DRAW_CALL_INDEXED_MULTI:
			{
				m_gl.multiDrawElements(GL_POINTS, m_multidrawcall_count, GL_UNSIGNED_INT, m_multidrawcall_index,
									   m_multidrawcall_drawcount);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMultiDrawElements() call failed");

				draw_call_count				   = m_multidrawcall_drawcount;
				draw_call_first_instance_id[0] = 0;
				draw_call_first_instance_id[1] = 0;
				draw_call_first_vertex_id[0] =
					m_index_data[((unsigned int)(intptr_t)m_multidrawcall_index[0] - m_data_bo_index_data_offset) /
								 sizeof(unsigned int)];
				draw_call_first_vertex_id[1] =
					m_index_data[((unsigned int)(intptr_t)m_multidrawcall_index[1] - m_data_bo_index_data_offset) /
								 sizeof(unsigned int)];
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = 1;
				draw_call_n_instances[1]		 = 1;
				draw_call_n_vertices[0]			 = m_multidrawcall_count[0];
				draw_call_n_vertices[1]			 = m_multidrawcall_count[1];
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_multidrawcall_count[0];
				n_result_bytes_per_instance[1]   = n_result_bytes_per_vertex * m_multidrawcall_count[1];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0] +
									   n_result_bytes_per_instance[1] * draw_call_n_instances[1];

				break;
			}

			case DRAW_CALL_INDEXED_MULTI_BASE_VERTEX:
			{
				m_gl.multiDrawElementsBaseVertex(GL_POINTS, m_multidrawcall_count, GL_UNSIGNED_INT,
												 m_multidrawcall_index, m_multidrawcall_drawcount,
												 m_multidrawcall_basevertex);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMultiDrawElementsBaseVertex() call failed.");

				draw_call_count				   = m_multidrawcall_drawcount;
				draw_call_first_instance_id[0] = 0;
				draw_call_first_instance_id[1] = 0;
				draw_call_first_vertex_id[0] =
					m_multidrawcall_basevertex[0] +
					m_index_data[((unsigned int)(intptr_t)m_multidrawcall_index[0] - m_data_bo_index_data_offset) /
								 sizeof(unsigned int)];
				draw_call_first_vertex_id[1] =
					m_multidrawcall_basevertex[1] +
					m_index_data[((unsigned int)(intptr_t)m_multidrawcall_index[1] - m_data_bo_index_data_offset) /
								 sizeof(unsigned int)];
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = 1;
				draw_call_n_instances[1]		 = 1;
				draw_call_n_vertices[0]			 = m_multidrawcall_count[0];
				draw_call_n_vertices[1]			 = m_multidrawcall_count[1];
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_multidrawcall_count[0];
				n_result_bytes_per_instance[1]   = n_result_bytes_per_vertex * m_multidrawcall_count[1];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0] +
									   n_result_bytes_per_instance[1] * draw_call_n_instances[1];

				break;
			}

			case DRAW_CALL_INSTANCED_INDEXED:
			{
				m_gl.drawElementsInstanced(GL_POINTS, m_n_vertices_per_instance, GL_UNSIGNED_INT,
										   (const glw::GLvoid*)(intptr_t)m_data_bo_index_data_offset,
										   m_n_instances_to_test);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawElementsInstanced() call failed.");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_index_data[0];
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_n_vertices_per_instance;
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_n_vertices_per_instance;
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_INSTANCED_INDEXED_BASE_VERTEX:
			{
				m_gl.drawElementsInstancedBaseVertex(GL_POINTS, m_n_vertices_per_instance, GL_UNSIGNED_INT,
													 (const glw::GLvoid*)(intptr_t)m_data_bo_index_data_offset,
													 m_n_instances_to_test, m_draw_call_baseVertex);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawElementsInstancedBaseVertex() call failed.");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_draw_call_baseVertex + m_index_data[0];
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_n_vertices_per_instance;
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_n_vertices_per_instance;
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_INSTANCED_INDEXED_BASE_VERTEX_BASE_INSTANCE:
			{
				m_gl.drawElementsInstancedBaseVertexBaseInstance(
					GL_POINTS, m_n_vertices_per_instance, GL_UNSIGNED_INT,
					(const glw::GLvoid*)(intptr_t)m_data_bo_index_data_offset, m_n_instances_to_test,
					m_draw_call_baseVertex, m_draw_call_baseInstance);

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawElementsInstancedBaseVertexBaseInstance() call failed.");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_draw_call_baseVertex + m_index_data[0];
				draw_call_is_vertex_id_ascending = false;
				draw_call_n_instances[0]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_n_vertices_per_instance;
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_n_vertices_per_instance;
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_REGULAR:
			{
				m_gl.drawArrays(GL_POINTS, m_draw_call_first, m_n_vertices_per_instance);

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays() call failed");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_draw_call_first;
				draw_call_is_vertex_id_ascending = true;
				draw_call_n_instances[0]		 = 1;
				draw_call_n_vertices[0]			 = m_n_vertices_per_instance;
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_n_vertices_per_instance;
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_REGULAR_INDIRECT:
			{
				m_gl.drawArraysIndirect(GL_POINTS, (glw::GLvoid*)(intptr_t)m_data_bo_regular_indirect_arg_offset);

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArraysIndirect() call failed.");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_draw_call_first;
				draw_call_is_vertex_id_ascending = true;
				draw_call_n_instances[0]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_multidrawcall_count[1];
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * draw_call_n_vertices[0];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_REGULAR_INDIRECT_MULTI:
			{
				m_gl.multiDrawArraysIndirect(GL_POINTS, (glw::GLvoid*)(intptr_t)m_data_bo_regular_mdi_arg_offset,
											 m_multidrawcall_drawcount, 0); /* stride */

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMultiDrawArraysIndirect() call failed.");

				draw_call_count					 = 2;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_instance_id[1]   = 0;
				draw_call_first_vertex_id[0]	 = m_draw_call_first;
				draw_call_first_vertex_id[1]	 = m_draw_call_first;
				draw_call_is_vertex_id_ascending = true;
				draw_call_n_instances[0]		 = 1;
				draw_call_n_instances[1]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_multidrawcall_count[0];
				draw_call_n_vertices[1]			 = m_multidrawcall_count[1];
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * draw_call_n_vertices[0];
				n_result_bytes_per_instance[1]   = n_result_bytes_per_vertex * draw_call_n_vertices[1];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0] +
									   n_result_bytes_per_instance[1] * draw_call_n_instances[1];

				break;
			}

			case DRAW_CALL_REGULAR_INSTANCED:
			{
				m_gl.drawArraysInstanced(GL_POINTS, m_draw_call_first, m_n_vertices_per_instance,
										 m_n_instances_to_test);

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArraysInstanced() call failed.");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_draw_call_first;
				draw_call_is_vertex_id_ascending = true;
				draw_call_n_instances[0]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_n_vertices_per_instance;
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * draw_call_n_vertices[0];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_REGULAR_INSTANCED_BASE_INSTANCE:
			{
				m_gl.drawArraysInstancedBaseInstance(GL_POINTS, m_draw_call_first, m_n_vertices_per_instance,
													 m_n_instances_to_test, m_draw_call_baseInstance);

				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArraysInstancedBaseInstance() call failed.");

				draw_call_count					 = 1;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_vertex_id[0]	 = m_draw_call_first;
				draw_call_is_vertex_id_ascending = true;
				draw_call_n_instances[0]		 = m_n_instances_to_test;
				draw_call_n_vertices[0]			 = m_n_vertices_per_instance;
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * draw_call_n_vertices[0];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] * draw_call_n_instances[0];

				break;
			}

			case DRAW_CALL_REGULAR_MULTI:
			{
				m_gl.multiDrawArrays(GL_POINTS, m_multidrawcall_first, m_multidrawcall_count,
									 m_multidrawcall_drawcount);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMultiDrawArrays() call failed.");

				draw_call_count					 = m_multidrawcall_drawcount;
				draw_call_first_instance_id[0]   = 0;
				draw_call_first_instance_id[1]   = 0;
				draw_call_first_vertex_id[0]	 = m_multidrawcall_first[0];
				draw_call_first_vertex_id[1]	 = m_multidrawcall_first[1];
				draw_call_is_vertex_id_ascending = true;
				draw_call_n_instances[0]		 = 1;
				draw_call_n_instances[1]		 = 1;
				draw_call_n_vertices[0]			 = m_multidrawcall_count[0];
				draw_call_n_vertices[1]			 = m_multidrawcall_count[1];
				n_result_bytes_per_instance[0]   = n_result_bytes_per_vertex * m_multidrawcall_count[0];
				n_result_bytes_per_instance[1]   = n_result_bytes_per_vertex * m_multidrawcall_count[1];
				n_result_bytes_total			 = n_result_bytes_per_instance[0] + n_result_bytes_per_instance[1];

				break;
			}

			default:
			{
				TCU_FAIL("Unrecognized draw call type");
			}
			} /* switch (draw_call_type) */

			DE_ASSERT(n_result_bytes_total <= m_result_bo_size);

			m_gl.endTransformFeedback();
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEndTransformFeedback() call failed.");

			/* Retrieve the captured data */
			glw::GLuint  mappable_bo_id			  = m_helper_bo;
			unsigned int mappable_bo_start_offset = 0;

			/* We cannot map the result BO storage directly into process space, since
			 * it's a sparse buffer. Copy the generated data to a helper BO and map
			 * that BO instead. */
			m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_result_bo);
			m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_helper_bo);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

			if (is_ia_iteration)
			{
				m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
									   0,											 /* writeOffset */
									   n_result_bytes_total);
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");
			}
			else
			{
				DE_ASSERT((n_result_bytes_total % 2) == 0);

				m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
									   0,											 /* writeOffset */
									   n_result_bytes_total / 2);
				m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
									   m_result_bo_size / 2,	  /* readOffset  */
									   m_result_bo_size / 2,	  /* writeOffset */
									   n_result_bytes_total / 2); /* size        */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");
			}

			m_gl.bindBuffer(GL_ARRAY_BUFFER, mappable_bo_id);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

			result_ptr = (unsigned int*)m_gl.mapBufferRange(GL_ARRAY_BUFFER, mappable_bo_start_offset, m_result_bo_size,
															GL_MAP_READ_BIT);

			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBufferRange() call failed.");

			/* Verify the generated output */
			bool		continue_checking		  = true;
			glw::GLuint result_instance_id_stride = 0;
			glw::GLuint result_vertex_id_stride   = 0;

			if (is_ia_iteration)
			{
				result_instance_id_stride = 2;
				result_vertex_id_stride   = 2;
			}
			else
			{
				result_instance_id_stride = 1;
				result_vertex_id_stride   = 1;
			}

			/* For all draw calls.. */
			for (int n_draw_call = 0; n_draw_call < draw_call_count && continue_checking; ++n_draw_call)
			{
				/* ..and resulting draw call instances.. */
				for (int n_instance = 0; n_instance < draw_call_n_instances[n_draw_call] && continue_checking;
					 ++n_instance)
				{
					DE_ASSERT((n_result_bytes_per_instance[n_draw_call] % sizeof(unsigned int)) == 0);

					/* Determine where the result TF data start from */
					const glw::GLuint expected_instance_id = draw_call_first_instance_id[n_draw_call] + n_instance;
					glw::GLuint*	  result_instance_id_traveller_ptr = DE_NULL;
					glw::GLuint*	  result_vertex_id_traveller_ptr   = DE_NULL;

					if (is_ia_iteration)
					{
						result_instance_id_traveller_ptr = result_ptr;

						for (int n_prev_draw_call = 0; n_prev_draw_call < n_draw_call; ++n_prev_draw_call)
						{
							result_instance_id_traveller_ptr += draw_call_n_instances[n_prev_draw_call] *
																n_result_bytes_per_instance[n_prev_draw_call] /
																sizeof(unsigned int);
						}

						result_instance_id_traveller_ptr +=
							n_instance * n_result_bytes_per_instance[n_draw_call] / sizeof(unsigned int);
						result_vertex_id_traveller_ptr = result_instance_id_traveller_ptr + 1;
					} /* if (is_ia_iteration) */
					else
					{
						DE_ASSERT((m_result_bo_size % 2) == 0);

						result_instance_id_traveller_ptr = result_ptr;

						for (int n_prev_draw_call = 0; n_prev_draw_call < n_draw_call; ++n_prev_draw_call)
						{
							result_instance_id_traveller_ptr +=
								draw_call_n_instances[n_prev_draw_call] *
								n_result_bytes_per_instance[n_prev_draw_call] /
								2 / /* instance id..instance id data | vertex id..vertex id data */
								sizeof(unsigned int);
						}

						result_instance_id_traveller_ptr +=
							n_instance * n_result_bytes_per_instance[n_draw_call] / 2 / sizeof(unsigned int);
						result_vertex_id_traveller_ptr =
							result_instance_id_traveller_ptr + (m_result_bo_size / 2) / sizeof(unsigned int);
					}

					/* Start checking the generated output */
					for (int n_point = 0; n_point < draw_call_n_vertices[n_draw_call] && continue_checking; ++n_point)
					{
						glw::GLuint expected_vertex_id	= 1;
						glw::GLuint retrieved_instance_id = 2;
						glw::GLuint retrieved_vertex_id   = 3;

						if (draw_call_is_vertex_id_ascending)
						{
							expected_vertex_id = draw_call_first_vertex_id[n_draw_call] + n_point;
						} /* if (draw_call_is_vertex_id_ascending) */
						else
						{
							if (draw_call_first_vertex_id[n_draw_call] >= n_point)
							{
								expected_vertex_id = draw_call_first_vertex_id[n_draw_call] - n_point;
							}
							else
							{
								expected_vertex_id = 0;
							}
						}

						/* Only perform the check if the offsets refer to pages with physical backing.
						 *
						 * Note that, on platforms, whose page size % 4 != 0, the values can land partially out of bounds,
						 * and partially in the safe zone. In such cases, skip the verification. */
						const bool result_instance_id_page_has_physical_backing =
							(((((char*)result_instance_id_traveller_ptr - (char*)result_ptr) / m_page_size) % 2) ==
							 0) &&
							((((((char*)result_instance_id_traveller_ptr - (char*)result_ptr) + sizeof(unsigned int) -
								1) /
							   m_page_size) %
							  2) == 0);
						const bool result_vertex_id_page_has_physical_backing =
							(((((char*)result_vertex_id_traveller_ptr - (char*)result_ptr) / m_page_size) % 2) == 0) &&
							((((((char*)result_vertex_id_traveller_ptr - (char*)result_ptr) + sizeof(unsigned int) -
								1) /
							   m_page_size) %
							  2) == 0);

						retrieved_instance_id = *result_instance_id_traveller_ptr;
						result_instance_id_traveller_ptr += result_instance_id_stride;

						retrieved_vertex_id = *result_vertex_id_traveller_ptr;
						result_vertex_id_traveller_ptr += result_vertex_id_stride;

						if ((result_instance_id_page_has_physical_backing &&
							 retrieved_instance_id != expected_instance_id) ||
							(result_vertex_id_page_has_physical_backing && retrieved_vertex_id != expected_vertex_id))
						{
							m_testCtx.getLog()
								<< tcu::TestLog::Message << "For "
															"["
								<< getName() << "]"
												", sparse BO flags "
												"["
								<< SparseBufferTestUtilities::getSparseBOFlagsString(sparse_bo_storage_flags)
								<< "]"
								   ", draw call type "
								<< getDrawCallTypeString(draw_call_type) << " at index "
																			"["
								<< n_draw_call << " / " << (draw_call_count - 1) << "]"
																					", TF mode "
																					"["
								<< ((is_ia_iteration) ? "interleaved attribs" : "separate attribs") << "]"
								<< ", instance "
								   "["
								<< n_instance << " / " << (draw_call_n_instances[n_draw_call] - 1) << "]"
								<< ", point at index "
								   "["
								<< n_point << " / " << (draw_call_n_vertices[n_draw_call] - 1) << "]"
								<< ", VS-level gl_VertexID was equal to "
								   "["
								<< retrieved_vertex_id << "]"
														  " and gl_InstanceID was set to "
														  "["
								<< retrieved_instance_id << "]"
															", whereas gl_VertexID of value "
															"["
								<< expected_vertex_id << "]"
														 " and gl_InstanceID of value "
														 "["
								<< expected_instance_id << "]"
														   " were anticipated."
								<< tcu::TestLog::EndMessage;

							continue_checking = false;
							result			  = false;

							break;
						} /* if (reported gl_InstanceID / gl_VertexID values are wrong) */
					}	 /* for (all drawn points) */
				}		  /* for (all instances) */

				/* Release memory pages we have allocated for the transform feed-back.
				 *
				 * NOTE: For some iterations, this call will attempt to de-commit pages which
				 *       have not been assigned physical backing. This is a valid behavior,
				 *       as per spec.
				 */
				m_gl.bufferPageCommitmentARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0,	 /* offset */
											 m_result_bo_size_rounded, GL_FALSE); /* commit */
				GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
			} /* for (all draw call) */

			m_gl.unmapBuffer(GL_ARRAY_BUFFER);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");
		} /* for (all draw call types) */
	}	 /* for (both TF modes) */

	return result;
}

/** Converts the internal enum to a null-terminated text string.
 *
 *  @param draw_call Draw call type to return a string for.
 *
 *  @return The requested string or "[?!]", if the enum was not recognized.
 **/
const char* TransformFeedbackBufferStorageTestCase::getDrawCallTypeString(_draw_call draw_call)
{
	const char* result = "[?!]";

	switch (draw_call)
	{
	case DRAW_CALL_INDEXED:
		result = "glDrawElements()";
		break;
	case DRAW_CALL_INDEXED_BASE_VERTEX:
		result = "glDrawElementsBaseVertex()";
		break;
	case DRAW_CALL_INDEXED_INDIRECT:
		result = "glDrawElementsIndirect()";
		break;
	case DRAW_CALL_INDEXED_INDIRECT_MULTI:
		result = "glMultiDrawElementIndirect()";
		break;
	case DRAW_CALL_INDEXED_MULTI:
		result = "glMultiDrawElements()";
		break;
	case DRAW_CALL_INDEXED_MULTI_BASE_VERTEX:
		result = "glMultiDrawElementsBaseVertex()";
		break;
	case DRAW_CALL_INSTANCED_INDEXED:
		result = "glDrawElementsInstanced()";
		break;
	case DRAW_CALL_INSTANCED_INDEXED_BASE_VERTEX:
		result = "glDrawElementsInstancedBaseVertex()";
		break;
	case DRAW_CALL_INSTANCED_INDEXED_BASE_VERTEX_BASE_INSTANCE:
		result = "glDrawElementsInstancedBaseVertexBaseInstance()";
		break;
	case DRAW_CALL_REGULAR:
		result = "glDrawArrays()";
		break;
	case DRAW_CALL_REGULAR_INDIRECT:
		result = "glDrawArraysIndirect()";
		break;
	case DRAW_CALL_REGULAR_INDIRECT_MULTI:
		result = "glMultiDrawArraysIndirect()";
		break;
	case DRAW_CALL_REGULAR_INSTANCED:
		result = "glDrawArraysInstanced()";
		break;
	case DRAW_CALL_REGULAR_INSTANCED_BASE_INSTANCE:
		result = "glDrawArraysInstancedBaseInstance()";
		break;
	case DRAW_CALL_REGULAR_MULTI:
		result = "glMultiDrawArrays()";
		break;

	default:
		break;
	} /* switch (draw_call) */

	return result;
}

/** Initializes test data buffer, and then sets up:
 *
 *  - an immutable buffer object (id stored in m_data_bo), to which the test data
 *    is copied.
 *  - a mappable immutable buffer object (id stored in m_helper_bo)
 **/
void TransformFeedbackBufferStorageTestCase::initDataBO()
{
	initTestData();

	/* Initialize data BO (the BO which holds index + indirect draw call args */
	DE_ASSERT(m_data_bo == 0);

	m_gl.genBuffers(1, &m_data_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_data_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_ARRAY_BUFFER, m_data_bo_size, DE_NULL, GL_DYNAMIC_STORAGE_BIT);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	m_gl.bufferSubData(GL_ARRAY_BUFFER, m_data_bo_indexed_indirect_arg_offset, m_indirect_arg_data_size,
					   m_indirect_arg_data);
	m_gl.bufferSubData(GL_ARRAY_BUFFER, m_data_bo_index_data_offset, m_index_data_size, m_index_data);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferSubData() call(s) failed.");

	/* Generate & bind a helper BO we need to copy the data to from the sparse BO
	 * if direct mapping is not possible.
	 */
	DE_ASSERT(m_result_bo_size != 0);
	DE_ASSERT(m_result_bo == 0);
	DE_ASSERT(m_helper_bo == 0);

	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_ARRAY_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_ARRAY_BUFFER, m_result_bo_size, DE_NULL, /* data */
					   GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool TransformFeedbackBufferStorageTestCase::initTestCaseGlobal()
{
	bool result = true;

	/* Initialize test program object */
	static const char*		  tf_varyings[] = { "instance_id", "vertex_id" };
	static const unsigned int n_tf_varyings = sizeof(tf_varyings) / sizeof(tf_varyings[0]);
	static const char*		  vs_body		= "#version 420 core\n"
								 "\n"
								 "out uint instance_id;\n"
								 "out uint vertex_id;\n"
								 "\n"
								 "void main()\n"
								 "{\n"
								 "    instance_id = gl_InstanceID;\n"
								 "    vertex_id   = gl_VertexID;\n"
								 "}\n";

	m_po_ia = SparseBufferTestUtilities::createProgram(m_gl, DE_NULL, /* fs_body_parts */
													   0,			  /* n_fs_body_parts */
													   &vs_body, 1,   /* n_vs_body_parts */
													   DE_NULL,		  /* attribute_names */
													   DE_NULL,		  /* attribute_locations */
													   0,			  /* n_attribute_properties */
													   tf_varyings, n_tf_varyings, GL_INTERLEAVED_ATTRIBS);

	m_po_sa = SparseBufferTestUtilities::createProgram(m_gl, DE_NULL, /* fs_body_parts */
													   0,			  /* n_fs_body_parts */
													   &vs_body, 1,   /* n_vs_body_parts */
													   DE_NULL,		  /* attribute_names */
													   DE_NULL,		  /* attribute_locations */
													   0,			  /* n_attribute_properties */
													   tf_varyings, n_tf_varyings, GL_SEPARATE_ATTRIBS);

	if (m_po_ia == 0 || m_po_sa == 0)
	{
		result = false;

		goto end;
	}

	/* Generate & bind a VAO */
	m_gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenVertexArrays() call failed.");

	m_gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindVertexArray() call failed.");

	initDataBO();

end:
	return result;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool TransformFeedbackBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Initialize buffer objects used by the test case */
	m_result_bo = sparse_bo;

	/* Sanity check */
	DE_ASSERT(m_data_bo != 0);

	return result;
}

/** Sets up client-side data arrays, later uploaded to the test buffer object, used as a source for:
 *
 *  - index data
 *  - indirect draw call arguments
 *  - multi draw call arguments
 **/
void TransformFeedbackBufferStorageTestCase::initTestData()
{
	/* We need the result data to span across at least m_min_memory_page_span memory pages.
	 * Each vertex outputs 2 * sizeof(int) = 8 bytes of data.
	 *
	 * For simplicity, we assume the number of bytes we calculate here is per instance. */
	m_n_vertices_per_instance = static_cast<unsigned int>((m_page_size * m_min_memory_page_span / (sizeof(int) * 2)));

	/* Let:
	 *
	 *     index_data_size       = (n of vertices per a single instance) * sizeof(unsigned int)
	 *     indexed_indirect_size = sizeof(glDrawElementsIndirect()      indirect arguments)
	 *     indexed_mdi_size      = sizeof(glMultiDrawElementsIndirect() indirect arguments) * 2 (single instance & multiple instances case)
	 *     regular_indirect_size = sizeof(glDrawArraysIndirect()        indirect arguments)
	 *     regular_mdi_size      = sizeof(glMultiDrawArraysIndirect()   indirect arguments) * 2 (single instance & multiple instances case)
	 *
	 *
	 * The layout we will use for the data buffer is:
	 *
	 * [indexed indirect arg data // Size: indexed_indirect_size bytes]
	 * [indexed MDI arg data      // Size: indexed_mdi_size      bytes]
	 * [regular indirect arg data // Size: regular_indirect_size bytes]
	 * [regular MDI arg data      // Size: regular_mdi_size      bytes]
	 * [index data                // Size: index_data_size       bytes]
	 */
	const unsigned int indexed_indirect_size = sizeof(unsigned int) * 5 /* as per GL spec */;
	const unsigned int indexed_mdi_size		 = sizeof(unsigned int) * 5 /* as per GL spec */ * 2; /* draw calls */
	const unsigned int regular_indirect_size = sizeof(unsigned int) * 4;						  /* as per GL spec */
	const unsigned int regular_mdi_size		 = sizeof(unsigned int) * 4 /* as per GL spec */ * 2; /* draw calls */

	m_data_bo_indexed_indirect_arg_offset = 0;
	m_data_bo_indexed_mdi_arg_offset	  = m_data_bo_indexed_indirect_arg_offset + indexed_indirect_size;
	m_data_bo_regular_indirect_arg_offset = m_data_bo_indexed_mdi_arg_offset + indexed_mdi_size;
	m_data_bo_regular_mdi_arg_offset	  = m_data_bo_regular_indirect_arg_offset + regular_indirect_size;
	m_data_bo_index_data_offset			  = m_data_bo_regular_mdi_arg_offset + regular_mdi_size;

	/* Form the index data */
	DE_ASSERT(m_index_data == DE_NULL);
	DE_ASSERT(m_draw_call_firstIndex == sizeof(unsigned int));

	m_index_data_size = static_cast<glw::GLuint>(
		(1 /* extra index, as per m_draw_call_firstIndex */ + m_n_vertices_per_instance) * sizeof(unsigned int));
	m_index_data = (unsigned int*)new unsigned char[m_index_data_size];

	for (unsigned int n_index = 0; n_index < m_n_vertices_per_instance + 1; ++n_index)
	{
		m_index_data[n_index] = m_n_vertices_per_instance - n_index;
	} /* for (all available indices) */

	/* Set multi draw-call arguments */
	m_multidrawcall_basevertex[0] = m_draw_call_baseVertex;
	m_multidrawcall_basevertex[1] = 257;
	m_multidrawcall_count[0]	  = m_n_vertices_per_instance;
	m_multidrawcall_count[1]	  = m_n_vertices_per_instance - 16;
	m_multidrawcall_drawcount	 = 2;
	m_multidrawcall_first[0]	  = 0;
	m_multidrawcall_first[1]	  = m_draw_call_first;
	m_multidrawcall_index[0]	  = (glw::GLvoid*)(intptr_t)m_data_bo_index_data_offset;
	m_multidrawcall_index[1]	  = (glw::GLvoid*)(intptr_t)(m_data_bo_index_data_offset + m_draw_call_firstIndex);
	m_multidrawcall_primcount	 = m_n_instances_to_test;

	/* Form the indirect data */
	DE_ASSERT(m_indirect_arg_data == DE_NULL);

	m_indirect_arg_data_size = m_data_bo_index_data_offset - m_data_bo_indexed_indirect_arg_offset;
	m_indirect_arg_data		 = (unsigned int*)new unsigned char[m_indirect_arg_data_size];

	unsigned int* indirect_arg_data_traveller_ptr = m_indirect_arg_data;

	/* 1. Indexed indirect arg data */
	DE_ASSERT(((unsigned int)(intptr_t)(m_multidrawcall_index[1]) % sizeof(unsigned int)) == 0);

	*indirect_arg_data_traveller_ptr = m_multidrawcall_count[1]; /* count */
	indirect_arg_data_traveller_ptr++;

	*indirect_arg_data_traveller_ptr = m_n_instances_to_test; /* primCount */
	indirect_arg_data_traveller_ptr++;

	*indirect_arg_data_traveller_ptr = static_cast<unsigned int>((unsigned int)(intptr_t)(m_multidrawcall_index[1]) /
																 sizeof(unsigned int)); /* firstIndex */
	indirect_arg_data_traveller_ptr++;

	*indirect_arg_data_traveller_ptr = m_draw_call_baseVertex; /* baseVertex */
	indirect_arg_data_traveller_ptr++;

	*indirect_arg_data_traveller_ptr = m_draw_call_baseInstance; /* baseInstance */
	indirect_arg_data_traveller_ptr++;

	/* 2. Indexed MDI arg data */
	for (unsigned int n_draw_call = 0; n_draw_call < 2; ++n_draw_call)
	{
		DE_ASSERT(((unsigned int)(intptr_t)(m_multidrawcall_index[n_draw_call]) % sizeof(unsigned int)) == 0);

		*indirect_arg_data_traveller_ptr = m_multidrawcall_count[n_draw_call]; /* count */
		indirect_arg_data_traveller_ptr++;

		*indirect_arg_data_traveller_ptr = (n_draw_call == 0) ? 1 : m_n_instances_to_test; /* primCount */
		indirect_arg_data_traveller_ptr++;

		*indirect_arg_data_traveller_ptr = static_cast<unsigned int>(
			(unsigned int)(intptr_t)(m_multidrawcall_index[n_draw_call]) / sizeof(unsigned int)); /* firstIndex */
		indirect_arg_data_traveller_ptr++;

		*indirect_arg_data_traveller_ptr = m_draw_call_baseVertex;
		indirect_arg_data_traveller_ptr++;

		*indirect_arg_data_traveller_ptr = m_draw_call_baseInstance;
		indirect_arg_data_traveller_ptr++;
	} /* for (both single-instanced and multi-instanced cases) */

	/* 3. Regular indirect arg data */
	*indirect_arg_data_traveller_ptr = m_multidrawcall_count[1]; /* count */
	indirect_arg_data_traveller_ptr++;

	*indirect_arg_data_traveller_ptr = m_n_instances_to_test; /* primCount */
	indirect_arg_data_traveller_ptr++;

	*indirect_arg_data_traveller_ptr = m_draw_call_first; /* first */
	indirect_arg_data_traveller_ptr++;

	*indirect_arg_data_traveller_ptr = m_draw_call_baseInstance; /* baseInstance */
	indirect_arg_data_traveller_ptr++;

	/* 4. Regular MDI arg data */
	for (unsigned int n_draw_call = 0; n_draw_call < 2; ++n_draw_call)
	{
		*indirect_arg_data_traveller_ptr = m_multidrawcall_count[n_draw_call]; /* count */
		indirect_arg_data_traveller_ptr++;

		*indirect_arg_data_traveller_ptr = (n_draw_call == 0) ? 1 : m_n_instances_to_test; /* instanceCount */
		indirect_arg_data_traveller_ptr++;

		*indirect_arg_data_traveller_ptr = m_draw_call_first; /* first */
		indirect_arg_data_traveller_ptr++;

		*indirect_arg_data_traveller_ptr = m_draw_call_baseInstance; /* baseInstance */
		indirect_arg_data_traveller_ptr++;
	} /* for (both single-instanced and multi-instanced cases) */

	/* Store the number of bytes we will need to allocate for the data BO */
	m_data_bo_size = m_index_data_size + m_indirect_arg_data_size;

	/* Determine the number of bytes we will need to have at hand to hold all the captured TF varyings.
	 * The equation below takes into account the heaviest draw call the test will ever issue.
	 */
	m_result_bo_size =
		static_cast<glw::GLuint>(sizeof(unsigned int) * 2 /* TF varyings per vertex */ *
								 (m_multidrawcall_count[0] + m_multidrawcall_count[1]) * m_multidrawcall_primcount);
	m_result_bo_size_rounded = SparseBufferTestUtilities::alignOffset(m_result_bo_size, m_page_size);

	/* Sanity checks */
	DE_ASSERT(m_min_memory_page_span > 0);
	DE_ASSERT(m_page_size > 0);
	DE_ASSERT(m_result_bo_size >= (m_min_memory_page_span * m_page_size));
}

/** Constructor.
 *
 *  @param gl                         GL entry-points container
 *  @param testContext                CTS test context
 *  @param page_size                  Page size, as reported by implementation for the GL_SPARSE_BUFFER_PAGE_SIZE_ARB query.
 *  @param pGLBufferPageCommitmentARB Func ptr to glBufferPageCommitmentARB() entry-point.
 */
UniformBufferStorageTestCase::UniformBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext,
														   glw::GLint page_size)
	: m_gl(gl)
	, m_gl_uniform_buffer_offset_alignment_value(0)
	, m_helper_bo(0)
	, m_n_pages_to_use(4)
	, m_n_ubo_uints(0)
	, m_page_size(page_size)
	, m_po(0)
	, m_sparse_bo(0)
	, m_sparse_bo_data_size(0)
	, m_sparse_bo_data_start_offset(0)
	, m_sparse_bo_size(0)
	, m_sparse_bo_size_rounded(0)
	, m_testCtx(testContext)
	, m_tf_bo(0)
	, m_ubo_data(DE_NULL)
	, m_vao(0)
{
	if ((m_n_pages_to_use % 2) != 0)
	{
		DE_ASSERT(DE_FALSE);
	}
}

/** Releases all GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
void UniformBufferStorageTestCase::deinitTestCaseGlobal()
{
	if (m_helper_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_helper_bo);

		m_helper_bo = 0;
	}

	if (m_po != 0)
	{
		m_gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_tf_bo != 0)
	{
		m_gl.deleteBuffers(1, &m_tf_bo);

		m_tf_bo = 0;
	}

	if (m_ubo_data != DE_NULL)
	{
		delete[] m_ubo_data;

		m_ubo_data = DE_NULL;
	}

	if (m_vao != 0)
	{
		m_gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** Releases temporary GL objects, created specifically for one test case iteration. */
void UniformBufferStorageTestCase::deinitTestCaseIteration()
{
	if (m_sparse_bo != 0)
	{
		m_gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0,				  /* offset */
									 m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		m_sparse_bo = 0;
	}
}

/** Executes a single test iteration. The BufferStorage test will call this method
 *  numerously during its life-time, testing various valid flag combinations applied
 *  to the tested sparse buffer object at glBufferStorage() call time.
 *
 *  @param sparse_bo_storage_flags <flags> argument, used by the test in the glBufferStorage()
 *                                 call to set up the sparse buffer's storage.
 *
 *  @return true if the test case executed correctly, false otherwise.
 */
bool UniformBufferStorageTestCase::execute(glw::GLuint sparse_bo_storage_flags)
{
	(void)sparse_bo_storage_flags;
	bool result = true;

	m_gl.bindBufferRange(GL_UNIFORM_BUFFER, 0, /* index */
						 m_sparse_bo, m_sparse_bo_data_start_offset, m_n_ubo_uints * 4 * sizeof(unsigned int));
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferBase() call failed.");

	/* Run the test in three iterations:
	 *
	 * 1) Whole UBO storage is backed by physical backing.
	 * 2) Half the UBO storage is backed by physical backing.
	 * 3) None of the UBO storage is backed by physical backing.
	 */
	for (unsigned int n_iteration = 0; n_iteration < 3; ++n_iteration)
	{
		bool		 result_local			 = true;
		unsigned int ubo_commit_size		 = 0;
		unsigned int ubo_commit_start_offset = 0;

		switch (n_iteration)
		{
		case 0:
		{
			ubo_commit_size			= m_sparse_bo_data_size;
			ubo_commit_start_offset = m_sparse_bo_data_start_offset;

			break;
		}

		case 1:
		{
			DE_ASSERT((m_sparse_bo_data_size % 2) == 0);
			DE_ASSERT((m_sparse_bo_data_size % m_page_size) == 0);

			ubo_commit_size			= m_sparse_bo_data_size / 2;
			ubo_commit_start_offset = m_sparse_bo_data_start_offset;

			break;
		}

		case 2:
		{
			/* The default values do just fine */

			break;
		}

		default:
		{
			TCU_FAIL("Invalid iteration index");
		}
		} /* switch (n_iteration) */

		m_gl.bufferPageCommitmentARB(GL_UNIFORM_BUFFER, ubo_commit_start_offset, ubo_commit_size, GL_TRUE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");

		/* Copy the UBO data */
		m_gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, /* readOffset */
							   ubo_commit_start_offset, ubo_commit_size);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCopyBufferSubData() call failed.");

		/* Issue the draw call to execute the test */
		m_gl.useProgram(m_po);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed.");

		m_gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_tf_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

		m_gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index */
							m_tf_bo);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferBase() call failed.");

		m_gl.beginTransformFeedback(GL_POINTS);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBeginTransformFeedback() call failed.");

		m_gl.drawArrays(GL_POINTS, 0, /* first */
						m_n_ubo_uints);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays() call failed.");

		m_gl.endTransformFeedback();
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEndTransformFeedback() call failed.");

		/* Retrieve the data, verify the output */
		const unsigned int* result_data_ptr =
			(const unsigned int*)m_gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
		unsigned int ubo_data_offset = m_sparse_bo_data_start_offset;

		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBuffer() call failed.");

		for (unsigned int n_vertex = 0; n_vertex < m_n_ubo_uints && result_local;
			 ++n_vertex, ubo_data_offset = static_cast<unsigned int>(ubo_data_offset + 4 * sizeof(unsigned int)))
		{
			const bool is_ub_data_physically_backed = (ubo_data_offset >= ubo_commit_start_offset &&
													   ubo_data_offset < (ubo_commit_start_offset + ubo_commit_size)) ?
														  1 :
														  0;
			unsigned int	   expected_value  = -1;
			const unsigned int retrieved_value = result_data_ptr[n_vertex];

			if (is_ub_data_physically_backed)
			{
				expected_value = 1;
			}
			else
			{
				/* Read ops applied against non-committed sparse buffers return an undefined value.
				 */
				continue;
			}

			if (expected_value != retrieved_value)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value "
															   "("
								   << retrieved_value << ") "
														 "found at index "
														 "("
								   << n_vertex << ")"
												  ", instead of the expected value "
												  "("
								   << expected_value << ")"
														". Iteration index:"
														"("
								   << n_iteration << ")" << tcu::TestLog::EndMessage;

				result_local = false;
			}
		}

		result &= result_local;

		/* Clean up in anticipation for the next iteration */
		static const unsigned char data_zero_r8 = 0;

		m_gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() call failed.");

		m_gl.clearBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &data_zero_r8);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glClearBufferData() call failed.");

		m_gl.bufferPageCommitmentARB(GL_UNIFORM_BUFFER, 0, m_sparse_bo_size_rounded, GL_FALSE); /* commit */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferPageCommitmentARB() call failed.");
	} /* for (all three iterations) */

	return result;
}

/** Initializes GL objects used across all test case iterations.
 *
 *  Called once during BufferStorage test run-time.
 */
bool UniformBufferStorageTestCase::initTestCaseGlobal()
{
	/* Cache GL constant values */
	glw::GLint gl_max_uniform_block_size_value = 0;

	m_gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &gl_max_uniform_block_size_value);
	m_gl.getIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &m_gl_uniform_buffer_offset_alignment_value);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetIntegerv() call(s) failed.");

	/* Determine the number of uints we can access at once from a single VS invocation */
	DE_ASSERT(gl_max_uniform_block_size_value >= 1);

	/* Account for the fact that in std140 layout, array elements will be rounded up
	 * to the size of a vec4, i.e. 16 bytes. */
	m_n_ubo_uints = static_cast<unsigned int>(gl_max_uniform_block_size_value / (4 * sizeof(unsigned int)));

	/* Prepare the test program */
	std::stringstream vs_body_define_sstream;
	std::string		  vs_body_define_string;

	const char* tf_varying		 = "result";
	const char* vs_body_preamble = "#version 140\n"
								   "\n";

	const char* vs_body_main = "\n"
							   "layout(std140) uniform data\n"
							   "{\n"
							   "    uint data_input[N_UBO_UINTS];"
							   "};\n"
							   "\n"
							   "out uint result;\n"
							   "\n"
							   "void main()\n"
							   "{\n"
							   "    result = (data_input[gl_VertexID] == uint(gl_VertexID) ) ? 1u : 0u;\n"
							   "}";

	vs_body_define_sstream << "#define N_UBO_UINTS (" << m_n_ubo_uints << ")\n";
	vs_body_define_string = vs_body_define_sstream.str();

	const char*		   vs_body_parts[] = { vs_body_preamble, vs_body_define_string.c_str(), vs_body_main };
	const unsigned int n_vs_body_parts = sizeof(vs_body_parts) / sizeof(vs_body_parts[0]);

	m_po = SparseBufferTestUtilities::createProgram(m_gl, DE_NULL,							 /* fs_body_parts */
													0,										 /* n_fs_body_parts */
													vs_body_parts, n_vs_body_parts, DE_NULL, /* attribute_names */
													DE_NULL,								 /* attribute_locations */
													0,				/* n_attribute_properties */
													&tf_varying, 1, /* n_tf_varyings */
													GL_INTERLEAVED_ATTRIBS);

	if (m_po == 0)
	{
		TCU_FAIL("The test program failed to link");
	}

	/* Determine the number of bytes the sparse buffer needs to be able to have
	 * a physical backing or.
	 *
	 * We will provide physical backing for twice the required size and then use
	 * a region in the centered of the allocated memory block.
	 *
	 * NOTE: We need to be able to use an offset which is aligned to both the page size,
	 *       and the UB offset alignment.
	 * */
	m_sparse_bo_data_size = static_cast<unsigned int>(sizeof(unsigned int) * m_page_size);
	m_sparse_bo_size	  = (m_page_size * m_gl_uniform_buffer_offset_alignment_value) * 2;

	if (m_sparse_bo_size < m_sparse_bo_data_size * 2)
	{
		m_sparse_bo_size = m_sparse_bo_data_size * 2;
	}

	m_sparse_bo_size_rounded	  = m_sparse_bo_size; /* rounded to the page size by default */
	m_sparse_bo_data_start_offset = (m_sparse_bo_size - m_sparse_bo_data_size) / 2;

	/* Set up the TFBO storage */
	const unsigned tfbo_size = static_cast<unsigned int>(sizeof(unsigned int) * m_n_ubo_uints);

	m_gl.genBuffers(1, &m_tf_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_tf_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, tfbo_size, DE_NULL, /* data */
					   GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	/* Set up the UBO contents. We're actually setting up an immutable BO here,
	 * but we'll use its contents for a copy op, executed at the beginning of
	 * each iteration.
	 */
	unsigned int* ubo_data_traveller_ptr = DE_NULL;

	DE_ASSERT((m_sparse_bo_data_size % sizeof(unsigned int)) == 0);

	m_ubo_data			   = new (std::nothrow) unsigned char[m_sparse_bo_data_size];
	ubo_data_traveller_ptr = (unsigned int*)m_ubo_data;

	for (unsigned int n_vertex = 0; n_vertex < m_sparse_bo_data_size / (4 * sizeof(unsigned int)); ++n_vertex)
	{
		*ubo_data_traveller_ptr = n_vertex;
		ubo_data_traveller_ptr += 4;
	}

	m_gl.genBuffers(1, &m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() call failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	/* Set up helper BO storage */
	m_gl.bufferStorage(GL_COPY_READ_BUFFER, m_sparse_bo_data_size, m_ubo_data, 0); /* flags */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferStorage() call failed.");

	/* Set up the VAO */
	m_gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenVertexArrays() call failed.");

	m_gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindVertexArray() call failed.");

	return true;
}

/** Initializes GL objects which are needed for a single test case iteration.
 *
 *  deinitTestCaseIteration() will be called after the test case is executed in ::execute()
 *  to release these objects.
 **/
bool UniformBufferStorageTestCase::initTestCaseIteration(glw::GLuint sparse_bo)
{
	bool result = true;

	/* Cache the BO id, if not cached already */
	DE_ASSERT(m_sparse_bo == 0 || m_sparse_bo == sparse_bo);

	m_sparse_bo = sparse_bo;

	/* Set up the sparse buffer bindings. */
	m_gl.bindBuffer(GL_COPY_WRITE_BUFFER, m_sparse_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call(s) failed.");

	m_gl.bindBuffer(GL_COPY_READ_BUFFER, m_helper_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	m_gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_tf_bo);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() call failed.");

	return result;
}

/** Constructor.
 *
 *  @param context     Rendering context
 *  @param name        Test name
 *  @param description Test description
 */
BufferStorageTest::BufferStorageTest(deqp::Context& context)
	: TestCase(context, "BufferStorageTest", "Tests various interactions between sparse buffers and other API areas")
	, m_sparse_bo(0)
{
	/* Left blank intentionally */
}

/** Tears down any GL objects set up to run the test. */
void BufferStorageTest::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* De-initialize all test the test cases */
	for (TestCasesVectorIterator itTestCase = m_testCases.begin(); itTestCase != m_testCases.end(); ++itTestCase)
	{
		(*itTestCase)->deinitTestCaseGlobal();

		delete (*itTestCase);
	} /* for (all registered test case objects) */

	m_testCases.clear();

	if (m_sparse_bo != 0)
	{
		gl.deleteBuffers(1, &m_sparse_bo);

		m_sparse_bo = 0;
	}
}

/** Stub init method */
void BufferStorageTest::init()
{
	/* We cannot initialize the test case objects here as there are cases where there
	 * is no rendering context bound to the thread, when this method is called. */
}

/** Fills m_testCases with BufferStorageTestCase instances which implement the sub-cases
 *  for the second test described in the CTS_ARB_sparse_buffer test specification
 **/
void BufferStorageTest::initTestCases()
{
	const glw::Functions& gl		= m_context.getRenderContext().getFunctions();
	glw::GLint			  page_size = 0;

	/* Retrieve "sparse buffer" GL constant values and entry-point func ptrs */
	gl.getIntegerv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &page_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_SPARSE_BUFFER_PAGE_SIZE_ARB pname");

	/* Initialize all test case objects:
	 *
	 * Test cases a1-a6 */
	m_testCases.push_back(new QuadsBufferStorageTestCase(
		gl, m_testCtx, page_size, QuadsBufferStorageTestCase::IBO_USAGE_NONE, false)); /* use_color_data */
	m_testCases.push_back(new QuadsBufferStorageTestCase(
		gl, m_testCtx, page_size, QuadsBufferStorageTestCase::IBO_USAGE_INDEXED_DRAW_CALL, false)); /* use_color_data */
	m_testCases.push_back(new QuadsBufferStorageTestCase(gl, m_testCtx, page_size,
														 QuadsBufferStorageTestCase::IBO_USAGE_INDEXED_RANGED_DRAW_CALL,
														 false)); /* use_color_data */
	m_testCases.push_back(new QuadsBufferStorageTestCase(
		gl, m_testCtx, page_size, QuadsBufferStorageTestCase::IBO_USAGE_INDEXED_DRAW_CALL, true)); /* use_color_data */
	m_testCases.push_back(new QuadsBufferStorageTestCase(gl, m_testCtx, page_size,
														 QuadsBufferStorageTestCase::IBO_USAGE_INDEXED_RANGED_DRAW_CALL,
														 true)); /* use_color_data */

	/* Test case b1 */
	m_testCases.push_back(
		new TransformFeedbackBufferStorageTestCase(gl, m_testCtx, page_size, true)); /* all_tf_pages_committed */

	/* Test case b2 */
	m_testCases.push_back(
		new TransformFeedbackBufferStorageTestCase(gl, m_testCtx, page_size, false)); /* all_tf_pages_committed */

	/* Test case c */
	m_testCases.push_back(new ClearOpsBufferStorageTestCase(gl, m_testCtx, page_size));

	/* Test case d */
	m_testCases.push_back(new InvalidateBufferStorageTestCase(gl, m_testCtx, page_size));

	/* Test case e */
	m_testCases.push_back(
		new AtomicCounterBufferStorageTestCase(gl, m_testCtx, page_size, false)); /* all_pages_committed */
	m_testCases.push_back(
		new AtomicCounterBufferStorageTestCase(gl, m_testCtx, page_size, true)); /* all_pages_committed */

	/* Test case f */
	m_testCases.push_back(new BufferTextureStorageTestCase(gl, m_context, m_testCtx, page_size));

	/* Test case g */
	m_testCases.push_back(new CopyOpsBufferStorageTestCase(gl, m_testCtx, page_size));

	/* Test case h */
	m_testCases.push_back(new IndirectDispatchBufferStorageTestCase(gl, m_testCtx, page_size));

	/* Test case i */
	m_testCases.push_back(new SSBOStorageTestCase(gl, m_testCtx, page_size));

	/* Test case j */
	m_testCases.push_back(new UniformBufferStorageTestCase(gl, m_testCtx, page_size));

	/* Test case k */
	m_testCases.push_back(new PixelPackBufferStorageTestCase(gl, m_testCtx, page_size));

	/* Test case l */
	m_testCases.push_back(new PixelUnpackBufferStorageTestCase(gl, m_testCtx, page_size));

	/* Test case m */
	m_testCases.push_back(new QueryBufferStorageTestCase(gl, m_testCtx, page_size));

	/* Initialize all test cases */
	for (TestCasesVectorIterator itTestCase = m_testCases.begin(); itTestCase != m_testCases.end(); ++itTestCase)
	{
		(*itTestCase)->initTestCaseGlobal();
	}
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult BufferStorageTest::iterate()
{
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
	bool				  result = true;

	/* Only execute if the implementation supports the GL_ARB_sparse_buffer extension */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer"))
	{
		throw tcu::NotSupportedError("GL_ARB_sparse_buffer is not supported");
	}

	/* The buffer storage test cases require OpenGL 4.3 feature-set. */
	if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 3)))
	{
		throw tcu::NotSupportedError("GL_ARB_sparse_buffer conformance tests require OpenGL 4.3 core feature-set");
	}

	/* Register & initialize the test case objects */
	initTestCases();

	/* Iterate over all sparse BO flag combinations. We need to consider a total of 4 flags:
	 *
	 * - GL_CLIENT_STORAGE_BIT  (bit 0)
	 * - GL_DYNAMIC_STORAGE_BIT (bit 1)
	 * - GL_MAP_COHERENT_BIT    (bit 2)
	 * - GL_MAP_PERSISTENT_BIT  (bit 3)
	 *
	 *  GL_MAP_READ_BIT and GL_MAP_WRITE_BIT are excluded, since they are incompatible
	 *  with sparse buffers by definition.
	 *
	 *  GL_SPARSE_STORAGE_BIT_ARB is assumed to be always defined. Some of the combinations are invalid.
	 *  Such loop iterations will be skipped.
	 * */

	for (unsigned int n_flag_combination = 0; n_flag_combination < (1 << 4); ++n_flag_combination)
	{
		const glw::GLint flags = ((n_flag_combination & (1 << 0)) ? GL_CLIENT_STORAGE_BIT : 0) |
								 ((n_flag_combination & (1 << 1)) ? GL_DYNAMIC_STORAGE_BIT : 0) |
								 ((n_flag_combination & (1 << 2)) ? GL_MAP_COHERENT_BIT : 0) |
								 ((n_flag_combination & (1 << 3)) ? GL_MAP_PERSISTENT_BIT : 0) |
								 GL_SPARSE_STORAGE_BIT_ARB;

		if ((flags & GL_MAP_PERSISTENT_BIT) != 0)
		{
			if ((flags & GL_MAP_READ_BIT) == 0 && (flags & GL_MAP_WRITE_BIT) == 0)
			{
				continue;
			}
		}

		if (((flags & GL_MAP_COHERENT_BIT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT) == 0))
		{
			continue;
		}

		/* Set up the sparse BO */
		gl.genBuffers(1, &m_sparse_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");

		gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

		gl.bufferStorage(GL_ARRAY_BUFFER, 1024768 * 1024, /* as per test spec */
						 DE_NULL,						  /* data */
						 flags);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");

		for (TestCasesVectorIterator itTestCase = m_testCases.begin(); itTestCase != m_testCases.end(); ++itTestCase)
		{
			gl.bindBuffer(GL_ARRAY_BUFFER, m_sparse_bo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

			if (!(*itTestCase)->initTestCaseIteration(m_sparse_bo))
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Test case [" << (*itTestCase)->getName()
								   << "] "
									  "has failed to initialize."
								   << tcu::TestLog::EndMessage;

				result = false;
				goto end;
			}

			if (!(*itTestCase)->execute(flags))
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Test case [" << (*itTestCase)->getName()
								   << "] "
									  "has failed to execute correctly."
								   << tcu::TestLog::EndMessage;

				result = false;
			} /* if (!testCaseResult) */

			(*itTestCase)->deinitTestCaseIteration();
		} /* for (all added test cases) */

		/* Release the sparse BO */
		gl.deleteBuffers(1, &m_sparse_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() call failed.");

		m_sparse_bo = 0;
	}

end:
	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");

	return STOP;
}

/** Constructor.
 *
 *  @param context Rendering context.
 */
SparseBufferTests::SparseBufferTests(deqp::Context& context)
	: TestCaseGroup(context, "sparse_buffer_tests", "Verify conformance of CTS_ARB_sparse_buffer implementation")
{
}

/** Initializes the test group contents. */
void SparseBufferTests::init()
{
	addChild(new BufferStorageTest(m_context));
	addChild(new NegativeTests(m_context));
	addChild(new PageSizeGetterTest(m_context));
}

} /* gl4cts namespace */
