/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2017 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 glcRobustnessTests.cpp
 * \brief Conformance tests for the Robustness feature functionality.
 */ /*-------------------------------------------------------------------*/

#include "glcRobustnessTests.hpp"
#include "deSharedPtr.hpp"
#include "glcRobustBufferAccessBehaviorTests.hpp"
#include "gluContextInfo.hpp"
#include "gluPlatform.hpp"
#include "gluRenderContext.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTestLog.hpp"
#include <cstring>

using namespace glw;
using namespace glcts::RobustBufferAccessBehavior;

namespace glcts
{

namespace ResetNotificationStrategy
{

class RobustnessBase : public tcu::TestCase
{
public:
	RobustnessBase(tcu::TestContext& testCtx, const char* name, const char* description, glu::ApiType apiType);

	glu::RenderContext* createRobustContext(glu::ResetNotificationStrategy reset);

private:
	glu::ApiType m_ApiType;
};

RobustnessBase::RobustnessBase(tcu::TestContext& testCtx, const char* name, const char* description,
							   glu::ApiType apiType)
	: tcu::TestCase(testCtx, name, description), m_ApiType(apiType)
{
}

glu::RenderContext* RobustnessBase::createRobustContext(glu::ResetNotificationStrategy reset)
{
	/* Create test context to verify if GL_KHR_robustness extension is available */
	{
		deqp::Context context(m_testCtx, glu::ContextType(m_ApiType));
		if (!context.getContextInfo().isExtensionSupported("GL_KHR_robustness") &&
			!contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
									"GL_KHR_robustness extension not supported");
			return NULL;
		}
	}

	glu::RenderConfig		renderCfg(glu::ContextType(m_ApiType, glu::CONTEXT_ROBUST));
	const tcu::CommandLine& commandLine = m_testCtx.getCommandLine();
	glu::parseRenderConfig(&renderCfg, commandLine);

	if (commandLine.getSurfaceType() == tcu::SURFACETYPE_WINDOW)
		renderCfg.resetNotificationStrategy = reset;
	else
		throw tcu::NotSupportedError("Test not supported in non-windowed context");

	/* Try to create core/es robusness context */
	return createRenderContext(m_testCtx.getPlatform(), commandLine, renderCfg);
}

class NoResetNotificationCase : public RobustnessBase
{
	typedef glw::GLenum(GLW_APIENTRY* PFNGLGETGRAPHICSRESETSTATUS)();

public:
	NoResetNotificationCase(tcu::TestContext& testCtx, const char* name, const char* description, glu::ApiType apiType)
		: RobustnessBase(testCtx, name, description, apiType)
	{
	}

	virtual IterateResult iterate(void)
	{
		glu::ResetNotificationStrategy	strategy = glu::RESET_NOTIFICATION_STRATEGY_NO_RESET_NOTIFICATION;
		de::SharedPtr<glu::RenderContext> robustContext(createRobustContext(strategy));
		if (!robustContext.get())
			return STOP;

		glw::GLint reset = 0;

		const glw::Functions& gl = robustContext->getFunctions();
		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");

		if (reset != GL_NO_RESET_NOTIFICATION)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! glGet returned wrong value [" << reset
							   << ", expected " << GL_NO_RESET_NOTIFICATION << "]." << tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

		glw::GLint status = gl.getGraphicsResetStatus();
		if (status != GL_NO_ERROR)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
							   << "Test failed! glGetGraphicsResetStatus returned wrong value [" << status
							   << ", expected " << GL_NO_ERROR << "]." << tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

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

class LoseContextOnResetCase : public RobustnessBase
{
public:
	LoseContextOnResetCase(tcu::TestContext& testCtx, const char* name, const char* description, glu::ApiType apiType)
		: RobustnessBase(testCtx, name, description, apiType)
	{
	}

	virtual IterateResult iterate(void)
	{
		glu::ResetNotificationStrategy	strategy = glu::RESET_NOTIFICATION_STRATEGY_LOSE_CONTEXT_ON_RESET;
		de::SharedPtr<glu::RenderContext> robustContext(createRobustContext(strategy));
		if (!robustContext.get())
			return STOP;

		glw::GLint reset = 0;

		const glw::Functions& gl = robustContext->getFunctions();
		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");

		if (reset != GL_LOSE_CONTEXT_ON_RESET)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! glGet returned wrong value [" << reset
							   << ", expected " << GL_LOSE_CONTEXT_ON_RESET << "]." << tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

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

} // ResetNotificationStrategy namespace

namespace RobustBufferAccessBehavior
{

static deqp::Context* createContext(tcu::TestContext& testCtx, glu::ApiType apiType)
{
	deqp::Context* context = new deqp::Context(testCtx, glu::ContextType(apiType));
	if (!context)
	{
		testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Pointer to context is NULL.");
		return DE_NULL;
	}

	if (!(contextSupports(context->getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
		  (context->getContextInfo().isExtensionSupported("GL_KHR_robustness") &&
		   context->getContextInfo().isExtensionSupported("GL_KHR_robust_buffer_access_behavior"))))
	{
		testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
		delete context;
		return DE_NULL;
	}

	return context;
}

/** Implementation of test GetnUniformTest. Description follows:
 *
 * This test verifies if read uniform variables to the buffer with bufSize less than expected result with GL_INVALID_OPERATION error;
 **/
class GetnUniformTest : public tcu::TestCase
{
public:
	/* Public methods */
	GetnUniformTest(tcu::TestContext& testCtx, glu::ApiType apiType);
	virtual ~GetnUniformTest()
	{
	}

	/* Public methods inherited from TestCase */
	virtual tcu::TestNode::IterateResult iterate(void);

private:
	/* Private methods */
	std::string getComputeShader(bool glslES320);

	bool verifyResult(const void* inputData, const void* resultData, int size, const char* method);
	bool verifyError(glw::GLint error, glw::GLint expectedError, const char* method);

	glu::ApiType m_ApiType;
};

/** Constructor
 *
 * @param context Test context
 **/
GetnUniformTest::GetnUniformTest(tcu::TestContext& testCtx, glu::ApiType apiType)
	: tcu::TestCase(testCtx, "getnuniform", "Verifies if read uniform variables to the buffer with bufSize less than "
											"expected result with GL_INVALID_OPERATION")
	, m_ApiType(apiType)
{
	/* Nothing to be done here */
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult GetnUniformTest::iterate()
{
	de::SharedPtr<deqp::Context> context(createContext(m_testCtx, m_ApiType));
	if (!context.get())
		return STOP;

	glu::RenderContext& renderContext = context->getRenderContext();
	const Functions& gl = renderContext.getFunctions();

	const GLfloat input4f[]  = { 1.0f, 5.4f, 3.14159f, 1.28f };
	const GLint   input3i[]  = { 10, -20, -30 };
	const GLuint  input4ui[] = { 10, 20, 30, 40 };

	/* Test result indicator */
	bool test_result = true;

	/* Iterate over all cases */
	Program program(gl);

	/* Compute Shader */
	bool			   glslES320 = contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
	const std::string& cs		 = getComputeShader(glslES320);

	/* Shaders initialization */
	program.Init(cs /* cs */, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */);
	program.Use();

	/* Initialize shader storage buffer */
	GLuint buf;

	gl.genBuffers(1, &buf);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");

	gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buf);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");

	gl.bufferData(GL_SHADER_STORAGE_BUFFER, 16, DE_NULL, GL_STREAM_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");

	/* passing uniform values */
	gl.programUniform4fv(program.m_id, 11, 1, input4f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramUniform4fv");

	gl.programUniform3iv(program.m_id, 12, 1, input3i);
	GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramUniform3iv");

	gl.programUniform4uiv(program.m_id, 13, 1, input4ui);
	GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramUniform4uiv");

	gl.dispatchCompute(1, 1, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");

	/* veryfing gfetnUniform error messages */
	GLfloat result4f[4];
	GLint   result3i[3];
	GLuint  result4ui[4];

	gl.getnUniformfv(program.m_id, 11, sizeof(GLfloat) * 4, result4f);
	test_result = test_result &&
				  verifyResult((void*)input4f, (void*)result4f, sizeof(GLfloat) * 4, "getnUniformfv [false negative]");
	test_result = test_result && verifyError(gl.getError(), GL_NO_ERROR, "getnUniformfv [false negative]");

	gl.getnUniformfv(program.m_id, 11, sizeof(GLfloat) * 3, result4f);
	test_result = test_result && verifyError(gl.getError(), GL_INVALID_OPERATION, "getnUniformfv [false positive]");

	gl.getnUniformiv(program.m_id, 12, sizeof(GLint) * 3, result3i);
	test_result = test_result &&
				  verifyResult((void*)input3i, (void*)result3i, sizeof(GLint) * 3, "getnUniformiv [false negative]");
	test_result = test_result && verifyError(gl.getError(), GL_NO_ERROR, "getnUniformiv [false negative]");

	gl.getnUniformiv(program.m_id, 12, sizeof(GLint) * 2, result3i);
	test_result = test_result && verifyError(gl.getError(), GL_INVALID_OPERATION, "getnUniformiv [false positive]");

	gl.getnUniformuiv(program.m_id, 13, sizeof(GLuint) * 4, result4ui);
	test_result = test_result && verifyResult((void*)input4ui, (void*)result4ui, sizeof(GLuint) * 4,
											  "getnUniformuiv [false negative]");
	test_result = test_result && verifyError(gl.getError(), GL_NO_ERROR, "getnUniformuiv [false negative]");

	gl.getnUniformuiv(program.m_id, 13, sizeof(GLuint) * 3, result4ui);
	test_result = test_result && verifyError(gl.getError(), GL_INVALID_OPERATION, "getnUniformuiv [false positive]");

	/* Set result */
	if (true == test_result)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	gl.deleteBuffers(1, &buf);

	/* Done */
	return tcu::TestNode::STOP;
}

std::string GetnUniformTest::getComputeShader(bool glslES320)
{
	std::stringstream shader;
	shader << "#version " << (glslES320 ? "320 es\n" : "450\n");
	shader << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
		  "layout (location = 11) uniform vec4 inputf;\n"
		  "layout (location = 12) uniform ivec3 inputi;\n"
		  "layout (location = 13) uniform uvec4 inputu;\n"
		  "layout (std140, binding = 0) buffer ssbo {\n"
		  "   float valuef;\n"
		  "   int valuei;\n"
		  "   uint valueu;\n"
		  "};\n"
		  "void main()\n"
		  "{\n"
		  "   valuef = inputf.r + inputf.g + inputf.b + inputf.a;\n"
		  "   valuei = inputi.r + inputi.g + inputi.b;\n"
		  "   valueu = inputu.r + inputu.g + inputu.b + inputu.a;\n"
		  "}\n";
	return shader.str();
}

bool GetnUniformTest::verifyResult(const void* inputData, const void* resultData, int size, const char* method)
{
	int diff = memcmp(inputData, resultData, size);
	if (diff != 0)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! " << method << " result is not as expected."
						   << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

bool GetnUniformTest::verifyError(GLint error, GLint expectedError, const char* method)
{
	if (error != expectedError)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! " << method << " throws unexpected error ["
						   << error << "]." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** Implementation of test ReadnPixelsTest. Description follows:
 *
 * This test verifies if read pixels to the buffer with bufSize less than expected result with GL_INVALID_OPERATION error;
 **/
class ReadnPixelsTest : public tcu::TestCase
{
public:
	/* Public methods */
	ReadnPixelsTest(tcu::TestContext& testCtx, glu::ApiType apiType);
	virtual ~ReadnPixelsTest()
	{
	}

	/* Public methods inherited from TestCase */
	virtual tcu::TestNode::IterateResult iterate(void);

private:
	/* Private methods */
	void cleanTexture(deqp::Context& context, glw::GLuint texture_id);
	bool verifyResults(deqp::Context& context);
	bool verifyError(glw::GLint error, glw::GLint expectedError, const char* method);

	glu::ApiType m_ApiType;
};

/** Constructor
 *
 * @param context Test context
 **/
ReadnPixelsTest::ReadnPixelsTest(tcu::TestContext& testCtx, glu::ApiType apiType)
	: tcu::TestCase(testCtx, "readnpixels",
					"Verifies if read pixels to the buffer with bufSize less than expected result "
					"with GL_INVALID_OPERATION error")
	, m_ApiType(apiType)
{
	/* Nothing to be done here */
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult ReadnPixelsTest::iterate()
{
	de::SharedPtr<deqp::Context> context(createContext(m_testCtx, m_ApiType));
	if (!context.get())
		return STOP;

	static const GLuint elements[] = {
		0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7, 0, 7, 8, 0, 8, 1,
	};

	static const GLfloat vertices[] = {
		0.0f,  0.0f,  0.0f, 1.0f, /* 0 */
		-1.0f, 0.0f,  0.0f, 1.0f, /* 1 */
		-1.0f, 1.0f,  0.0f, 1.0f, /* 2 */
		0.0f,  1.0f,  0.0f, 1.0f, /* 3 */
		1.0f,  1.0f,  0.0f, 1.0f, /* 4 */
		1.0f,  0.0f,  0.0f, 1.0f, /* 5 */
		1.0f,  -1.0f, 0.0f, 1.0f, /* 6 */
		0.0f,  -1.0f, 0.0f, 1.0f, /* 7 */
		-1.0f, -1.0f, 0.0f, 1.0f, /* 8 */
	};

	bool glslES320 = contextSupports(context->getRenderContext().getType(), glu::ApiType::es(3, 2));
	std::string fs("#version ");
	fs += (glslES320 ? "320 es\n" : "450\n");
	fs += "layout (location = 0) out lowp uvec4 out_fs_color;\n"
		  "\n"
		  "void main()\n"
		  "{\n"
		  "	out_fs_color = uvec4(1, 0, 0, 1);\n"
		  "}\n"
		  "\n";

	std::string vs("#version ");
	vs += (glslES320 ? "320 es\n" : "450\n");
	vs += "layout (location = 0) in vec4 in_vs_position;\n"
		  "\n"
		  "void main()\n"
		  "{\n"
		  "	gl_Position = in_vs_position;\n"
		  "}\n"
		  "\n";

	static const GLuint height	 = 8;
	static const GLuint width	  = 8;
	static const GLuint n_vertices = 24;

	/* GL entry points */
	const Functions& gl = context->getRenderContext().getFunctions();

	/* Test case objects */
	Program		program(gl);
	Texture		texture(gl);
	Buffer		elements_buffer(gl);
	Buffer		vertices_buffer(gl);
	VertexArray vao(gl);

	/* Vertex array initialization */
	VertexArray::Generate(gl, vao.m_id);
	VertexArray::Bind(gl, vao.m_id);

	/* Texture initialization */
	Texture::Generate(gl, texture.m_id);
	Texture::Bind(gl, texture.m_id, GL_TEXTURE_2D);
	Texture::Storage(gl, GL_TEXTURE_2D, 1, GL_R8UI, width, height, 0);
	Texture::Bind(gl, 0, GL_TEXTURE_2D);

	/* Framebuffer initialization */
	GLuint fbo;
	gl.genFramebuffers(1, &fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.m_id, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");

	/* Buffers initialization */
	elements_buffer.InitData(GL_ELEMENT_ARRAY_BUFFER, GL_DYNAMIC_DRAW, sizeof(elements), elements);
	vertices_buffer.InitData(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, sizeof(vertices), vertices);

	/* Shaders initialization */
	program.Init("" /* cs */, fs, "" /* gs */, "" /* tcs */, "" /* tes */, vs);
	Program::Use(gl, program.m_id);

	/* Vertex buffer initialization */
	vertices_buffer.Bind();
	gl.bindVertexBuffer(0 /* bindindex = location */, vertices_buffer.m_id, 0 /* offset */, 16 /* stride */);
	gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 16, NULL);
	gl.enableVertexAttribArray(0 /* location */);

	/* Binding elements/indices buffer */
	elements_buffer.Bind();

	cleanTexture(*context, texture.m_id);

	gl.drawElements(GL_TRIANGLES, n_vertices, GL_UNSIGNED_INT, 0 /* indices */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");

	/* Set result */
	if (verifyResults(*context))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	/* Done */
	return tcu::TestNode::STOP;
}

/** Fill texture with value 128
 *
 * @param texture_id Id of texture
 **/
void ReadnPixelsTest::cleanTexture(deqp::Context& context, glw::GLuint texture_id)
{
	static const GLuint height = 8;
	static const GLuint width  = 8;

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

	GLubyte pixels[width * height];
	for (GLuint i = 0; i < width * height; ++i)
	{
		pixels[i] = 64;
	}

	Texture::Bind(gl, texture_id, GL_TEXTURE_2D);

	Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level  */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, 0 /* depth */,
					  GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels);

	/* Unbind */
	Texture::Bind(gl, 0, GL_TEXTURE_2D);
}

/** Verifies glReadnPixels results
 *
 * @return true when glReadnPixels , false otherwise
 **/
bool ReadnPixelsTest::verifyResults(deqp::Context& context)
{
	static const GLuint height	 = 8;
	static const GLuint width	  = 8;
	static const GLuint pixel_size = 4 * sizeof(GLuint);

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

	//Valid buffer size test
	const GLint bufSizeValid = width * height * pixel_size;
	GLubyte		pixelsValid[bufSizeValid];

	gl.readnPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, bufSizeValid, pixelsValid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "ReadnPixels");

	//Verify glReadnPixels result
	for (unsigned int i = 0; i < width * height; ++i)
	{
		const size_t offset = i * pixel_size;
		const GLuint value  = *(GLuint*)(pixelsValid + offset);

		if (value != 1)
		{
			context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid pixel value: " << value
											  << ". Offset: " << offset << tcu::TestLog::EndMessage;
			return false;
		}
	}

	//Invalid buffer size test
	const GLint bufSizeInvalid = width * height * pixel_size - 1;
	GLubyte		pixelsInvalid[bufSizeInvalid];

	gl.readnPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, bufSizeInvalid, pixelsInvalid);
	if (!verifyError(gl.getError(), GL_INVALID_OPERATION, "ReadnPixels [false positive]"))
		return false;

	return true;
}

/** Verify operation errors
 *
 * @param error OpenGL ES error code
 * @param expectedError Expected error code
 * @param method Method name marker
 *
 * @return true when error is as expected, false otherwise
 **/
bool ReadnPixelsTest::verifyError(GLint error, GLint expectedError, const char* method)
{
	if (error != expectedError)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! " << method << " throws unexpected error ["
						   << error << "]." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

} // RobustBufferAccessBehavior namespace

RobustnessTests::RobustnessTests(tcu::TestContext& testCtx, glu::ApiType apiType)
	: tcu::TestCaseGroup(testCtx, "robustness",
						 "Verifies API coverage and functionality of GL_KHR_robustness extension.")
	, m_ApiType(apiType)
{
}

void RobustnessTests::init(void)
{
	tcu::TestCaseGroup::init();

	try
	{
		addChild(new ResetNotificationStrategy::NoResetNotificationCase(
			m_testCtx, "no_reset_notification", "Verifies if NO_RESET_NOTIFICATION strategy works as expected.",
			m_ApiType));
		addChild(new ResetNotificationStrategy::LoseContextOnResetCase(
			m_testCtx, "lose_context_on_reset", "Verifies if LOSE_CONTEXT_ON_RESET strategy works as expected.",
			m_ApiType));

		addChild(new RobustBufferAccessBehavior::GetnUniformTest(m_testCtx, m_ApiType));
		addChild(new RobustBufferAccessBehavior::ReadnPixelsTest(m_testCtx, m_ApiType));
	}
	catch (...)
	{
		// Destroy context.
		tcu::TestCaseGroup::deinit();
		throw;
	}
}

} // glcts namespace
