/*-------------------------------------------------------------------------
 * 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  gl4cDirectStateAccessFramebuffersAndRenderbuffersTests.cpp
 * \brief Conformance tests for the Direct State Access feature functionality (Framebuffers and Renderbuffer access part).
 */ /*------------------------------------------------------------------------------------------------------------------------*/

/* Includes. */
#include "gl4cDirectStateAccessTests.hpp"

#include "deSharedPtr.hpp"

#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"

#include "tcuFuzzyImageCompare.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"

#include "glw.h"
#include "glwFunctions.hpp"

#include <algorithm>
#include <climits>
#include <cmath>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

namespace gl4cts
{
namespace DirectStateAccess
{
namespace Framebuffers
{
/******************************** Framebuffer Creation Test Implementation   ********************************/

/** @brief Creation Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationTest::CreationTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_creation", "Framebuffer Objects Creation Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Framebuffers' objects */
	static const glw::GLuint framebuffers_count = 2;

	glw::GLuint framebuffers_legacy[framebuffers_count] = {};
	glw::GLuint framebuffers_dsa[framebuffers_count]	= {};

	try
	{
		/* Check legacy state creation. */
		gl.genFramebuffers(framebuffers_count, framebuffers_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		for (glw::GLuint i = 0; i < framebuffers_count; ++i)
		{
			if (gl.isFramebuffer(framebuffers_legacy[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "GenFramebuffers has created default objects, but it should create only a names."
					<< tcu::TestLog::EndMessage;
			}
		}

		/* Check direct state creation. */
		gl.createFramebuffers(framebuffers_count, framebuffers_dsa);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");

		for (glw::GLuint i = 0; i < framebuffers_count; ++i)
		{
			if (!gl.isFramebuffer(framebuffers_dsa[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog() << tcu::TestLog::Message
													<< "CreateFramebuffers has not created default objects."
													<< tcu::TestLog::EndMessage;
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	for (glw::GLuint i = 0; i < framebuffers_count; ++i)
	{
		if (framebuffers_legacy[i])
		{
			gl.deleteFramebuffers(1, &framebuffers_legacy[i]);

			framebuffers_legacy[i] = 0;
		}

		if (framebuffers_dsa[i])
		{
			gl.deleteFramebuffers(1, &framebuffers_dsa[i]);

			framebuffers_dsa[i] = 0;
		}
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Framebuffer Renderbuffer Attachment Test Implementation   ********************************/

/** @brief Framebuffer Renderbuffer Attachment Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
RenderbufferAttachmentTest::RenderbufferAttachmentTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_renderbuffer_attachment", "Framebuffer Renderbuffer Attachment Test")
	, m_fbo(0)
	, m_rbo(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Framebuffer Renderbuffer Attachment Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult RenderbufferAttachmentTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;

		gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			is_ok &= Test(GL_COLOR_ATTACHMENT0 + i, GL_RGBA8);
			Clean();
		}

		is_ok &= Test(GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
		Clean();

		is_ok &= Test(GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
		Clean();

		is_ok &= Test(GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
		Clean();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Test functionality.
 *
 *  @param [in] attachment         Framebuffer attachment.
 *  @param [in] internalformat     Internal format.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool RenderbufferAttachmentTest::Test(glw::GLenum attachment, glw::GLenum internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* RBO creation. */
	gl.genRenderbuffers(1, &m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

	/* FBO creation. */
	gl.createFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");

	gl.namedFramebufferRenderbuffer(m_fbo, attachment, GL_RENDERBUFFER, m_rbo);

	if (glw::GLenum error = gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedFramebufferRenderbuffer for "
											<< glu::getFramebufferAttachmentStr(attachment)
											<< " attachment failed with error value " << glu::getErrorStr(error) << "."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);

	if (GL_FRAMEBUFFER_COMPLETE != status)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Named Framebuffer Renderbuffer Attachment test failed because of framebuffer "
			<< glu::getFramebufferStatusStr(status) << " with renderbuffer set up as "
			<< glu::getFramebufferAttachmentStr(attachment) << " attachment." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Clean up GL state.
 */
void RenderbufferAttachmentTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Cleanup. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_rbo)
	{
		gl.deleteRenderbuffers(1, &m_rbo);

		m_rbo = 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Framebuffer Texture Attachment Test Implementation   ********************************/

/** @brief Creation Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
TextureAttachmentTest::TextureAttachmentTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_texture_attachment", "Framebuffer Texture Attachment Test")
	, m_fbo(0)
	, m_to(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult TextureAttachmentTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;

		gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

		for (glw::GLuint i = 0; i < s_targets_count; ++i)
		{
			for (glw::GLuint j = 1; j <= MaxTextureLevels(s_targets[i]); ++j)
			{
				for (glw::GLint k = 0; k < max_color_attachments; ++k)
				{
					is_ok &= Test(GL_COLOR_ATTACHMENT0 + k, true, s_targets[i], GL_RGBA8, j);
					Clean();
				}

				is_ok &= Test(GL_DEPTH_ATTACHMENT, false, s_targets[i], GL_DEPTH_COMPONENT24, j);
				Clean();

				is_ok &= Test(GL_STENCIL_ATTACHMENT, false, s_targets[i], GL_STENCIL_INDEX8, j);
				Clean();

				is_ok &= Test(GL_DEPTH_STENCIL_ATTACHMENT, false, s_targets[i], GL_DEPTH24_STENCIL8, j);
				Clean();
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Test functionality.
 *
 *  @param [in]  attachment            Framebuffer attachment.
 *  @param [in] is_color_attachment    Is color attachment tested.
 *  @param [in] texture_target         Texture target.
 *  @param [in] internalformat         Internal format ot be tested.
 *  @param [in] levels                 Number of levels.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool TextureAttachmentTest::Test(glw::GLenum attachment, bool is_color_attachment, glw::GLenum texture_target,
								 glw::GLenum internalformat, glw::GLuint levels)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* RBO creation. */
	gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(texture_target, m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	if (GL_TEXTURE_2D_MULTISAMPLE == texture_target)
	{
		gl.texStorage2DMultisample(texture_target, 1, internalformat, (glw::GLuint)std::pow((double)2, (double)levels),
								   (glw::GLuint)std::pow((double)2, (double)levels), GL_FALSE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
	}
	else
	{
		gl.texStorage2D(texture_target, levels, internalformat, (glw::GLuint)std::pow((double)2, (double)levels),
						(glw::GLuint)std::pow((double)2, (double)levels));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
	}

	gl.bindTexture(texture_target, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

	/* FBO creation. */
	gl.createFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");

	for (glw::GLuint i = 0; i < levels; ++i)
	{
		gl.namedFramebufferTexture(m_fbo, attachment, m_to, i);

		SubTestAttachmentError(attachment, texture_target, i, levels);

		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		if (is_color_attachment)
		{
			gl.drawBuffer(attachment);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");

			gl.readBuffer(attachment);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer has failed");
		}

		SubTestStatus(attachment, texture_target, i, levels);

		if (GL_TEXTURE_2D_MULTISAMPLE != texture_target)
		{
			Clear();

			if (!SubTestContent(attachment, texture_target, internalformat, i, levels))
			{
				return false;
			}
		}

		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
	}

	return true;
}

/** @brief Check error and log.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *  @param [in] texture_target         Texture target.
 *  @param [in] level                  Tested level.
 *  @param [in] levels                 Number of levels.
 *
 *  @return True if no error, false otherwise.
 */
bool TextureAttachmentTest::SubTestAttachmentError(glw::GLenum attachment, glw::GLenum texture_target,
												   glw::GLuint level, glw::GLuint levels)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (glw::GLenum error = gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "NamedFramebufferTexture for " << glu::getFramebufferAttachmentStr(attachment)
			<< " attachment of " << glu::getTextureTargetStr(texture_target) << " texture and texture level " << level
			<< " of texture with " << levels << " levels failed with error value " << glu::getErrorStr(error) << "."
			<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Check status and log.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *  @param [in] texture_target         Texture target.
 *  @param [in] level                  Tested level.
 *  @param [in] levels                 Number of levels.
 *
 *  @return True if FRAMEBUFFER_COMPLETE, false otherwise.
 */
bool TextureAttachmentTest::SubTestStatus(glw::GLenum attachment, glw::GLenum texture_target, glw::GLuint level,
										  glw::GLuint levels)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);

	if (GL_FRAMEBUFFER_COMPLETE != status)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Named Framebuffer Texture Attachment test failed because of framebuffer "
			<< glu::getFramebufferStatusStr(status) << " status with " << glu::getTextureTargetStr(texture_target)
			<< " texture set up as " << glu::getFramebufferAttachmentStr(attachment) << " attachment and texture level "
			<< level << " of texture with " << levels << " levels." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Check framebuffer content and log.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *  @param [in] texture_target         Texture target.
 *  @param [in] internalformat         Tested internal format.
 *  @param [in] level                  Tested level.
 *  @param [in] levels                 Number of levels.
 *
 *  @return True if FRAMEBUFFER_COMPLETE, false otherwise.
 */
bool TextureAttachmentTest::SubTestContent(glw::GLenum attachment, glw::GLenum texture_target,
										   glw::GLenum internalformat, glw::GLuint level, glw::GLuint levels)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check framebuffer's color content. */
	if (GL_RGBA8 == internalformat)
	{
		glw::GLfloat color[4] = { 0.f };

		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, color);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

		for (int i = 0; i < 4 /* color components */; ++i)
		{
			if (de::abs(s_reference_color[i] - color[i]) > 0.0625 /* precision */)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed with "
					<< glu::getTextureTargetStr(texture_target) << " texture set up as "
					<< glu::getFramebufferAttachmentStr(attachment) << " attachment and texture level " << level
					<< " of texture with " << levels << " levels. The color content of the framebuffer was ["
					<< color[0] << ", " << color[1] << ", " << color[2] << ", " << color[3] << "], but ["
					<< s_reference_color[0] << ", " << s_reference_color[1] << ", " << s_reference_color[2] << ", "
					<< s_reference_color[3] << "] was expected." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	/* Check framebuffer's depth content. */
	if ((GL_DEPTH_COMPONENT24 == internalformat) || (GL_DEPTH24_STENCIL8 == internalformat))
	{
		glw::GLfloat depth = 0.f;

		gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

		if (de::abs(s_reference_depth - depth) > 0.0625 /* precision */)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed "
				<< "with texture set up as " << glu::getFramebufferAttachmentStr(attachment)
				<< " attachment and texture level " << level << " of texture with " << levels
				<< " levels. The depth content of the framebuffer was [" << depth << "], but [" << s_reference_depth
				<< "] was expected." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	/* Check framebuffer's stencil content. */
	if ((GL_STENCIL_INDEX8 == internalformat) || (GL_DEPTH24_STENCIL8 == internalformat))
	{
		glw::GLint stencil = 0;

		gl.readPixels(0, 0, 1, 1, GL_STENCIL_INDEX, GL_INT, &stencil);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

		if (s_reference_stencil != stencil)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed "
				<< "with texture set up as " << glu::getFramebufferAttachmentStr(attachment)
				<< " attachment and texture level " << level << " of texture with " << levels
				<< " levels. The stencil content of the framebuffer was [" << stencil << "], but ["
				<< s_reference_stencil << "] was expected." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

/** @brief Query max texture levels.
 *
 *  @param [in] texture_target         Texture target.
 *
 *  @return Max texture levels.
 */
glw::GLuint TextureAttachmentTest::MaxTextureLevels(glw::GLenum texture_target)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint max_texture_size = 1024 /* Specification default. */;

	switch (texture_target)
	{
	case GL_TEXTURE_RECTANGLE:
	case GL_TEXTURE_2D_MULTISAMPLE:
		return 1;

	case GL_TEXTURE_2D:
		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		return (glw::GLuint)std::log((double)max_texture_size);

	case GL_TEXTURE_CUBE_MAP:
		gl.getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_texture_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		return (glw::GLuint)std::log((double)max_texture_size);

	default:
		throw 0;
	}

	/* For compiler warnings only. */
	return 0;
}

/** @brief Clear texture.
 */
void TextureAttachmentTest::Clear()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Setup clear values. */
	gl.clearColor(s_reference_color[0], s_reference_color[1], s_reference_color[2], s_reference_color[3]);
	gl.clearDepth(s_reference_depth);
	gl.clearStencil(s_reference_stencil);

	/* Clear rbo/fbo. */
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}

/** @brief Clean up GL state.
 */
void TextureAttachmentTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Cleanup. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_to)
	{
		gl.deleteTextures(1, &m_to);

		m_to = 0;
	}

	/* Returning to default clear values. */
	gl.clearColor(0.f, 0.f, 0.f, 0.f);
	gl.clearDepth(1.f);
	gl.clearStencil(0);

	/* Errors clean up. */
	while (gl.getError())
		;
}

/** Tested targets. */
const glw::GLenum TextureAttachmentTest::s_targets[] = { GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D, GL_TEXTURE_2D_MULTISAMPLE,
														 GL_TEXTURE_CUBE_MAP };

/** Tested targets count. */
const glw::GLuint TextureAttachmentTest::s_targets_count = sizeof(s_targets) / sizeof(s_targets[0]);

const glw::GLfloat TextureAttachmentTest::s_reference_color[4]		   = { 0.25, 0.5, 0.75, 1.0 }; //!< Reference color.
const glw::GLint   TextureAttachmentTest::s_reference_color_integer[4] = { 1, 2, 3,
																		 4 }; //!< Reference color for integer format.
const glw::GLfloat TextureAttachmentTest::s_reference_depth   = 0.5;		  //!< Reference depth value.
const glw::GLint   TextureAttachmentTest::s_reference_stencil = 7;			  //!< Reference stencil value.

/******************************** Framebuffer Texture Layer Attachment Test Implementation   ********************************/

/** @brief Framebuffer Texture Layer Attachment Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
TextureLayerAttachmentTest::TextureLayerAttachmentTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_texture_layer_attachment", "Framebuffer Texture Layer Attachment Test")
	, m_fbo(0)
	, m_to(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Framebuffer Texture Layer Attachment Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult TextureLayerAttachmentTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;

		gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

		for (glw::GLuint i = 0; i < s_targets_count; ++i)
		{
			glw::GLuint layers_counts[] = { (GL_TEXTURE_CUBE_MAP_ARRAY == (glw::GLuint)s_targets[i]) ? 6u : 1u,
											(GL_TEXTURE_CUBE_MAP_ARRAY == (glw::GLuint)s_targets[i]) ? 192u : 192u,
											MaxTextureLayers(s_targets[i]) };

			glw::GLuint layers_counts_count = sizeof(layers_counts) / sizeof(layers_counts[0]);

			for (glw::GLuint j = 1; j <= MaxTextureLevels(s_targets[i]); ++j)
			{
				for (glw::GLuint k = 0; k < layers_counts_count; ++k)
				{
					for (glw::GLint l = 0; l < max_color_attachments; ++l)
					{
						is_ok &= Test(GL_COLOR_ATTACHMENT0 + l, true, s_targets[i], GL_RGBA8, j, layers_counts[k]);
						Clean();
					}

					if (GL_TEXTURE_3D != s_targets[i])
					{
						is_ok &=
							Test(GL_DEPTH_ATTACHMENT, false, s_targets[i], GL_DEPTH_COMPONENT24, j, layers_counts[k]);
						Clean();

						is_ok &= Test(GL_DEPTH_STENCIL_ATTACHMENT, false, s_targets[i], GL_DEPTH24_STENCIL8, j,
									  layers_counts[k]);
						Clean();

						is_ok &=
							Test(GL_STENCIL_ATTACHMENT, false, s_targets[i], GL_STENCIL_INDEX8, j, layers_counts[k]);
						Clean();
					}
				}
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Test texture layer attachment.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *  @param [in] is_color_attachment    Is color attachment tested.
 *  @param [in] texture_target         Texture target.
 *  @param [in] internalformat         Tested internal format.
 *  @param [in] level                  Tested level.
 *  @param [in] levels                 Number of levels.
 *  @param [in] layers                 Number of layers.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool TextureLayerAttachmentTest::Test(glw::GLenum attachment, bool is_color_attachment, glw::GLenum texture_target,
									  glw::GLenum internalformat, glw::GLuint levels, glw::GLint layers)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* RBO creation. */
	gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(texture_target, m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	// Lower the layers count when multiple levels are requested to limit the amount of memory required
	layers = deMax32(1, (glw::GLint)((deUint64)layers / (1ull<<(deUint64)(2*(levels-1)))));
	if (GL_TEXTURE_CUBE_MAP_ARRAY == texture_target)
	{
		layers = deMax32(6, (layers / 6) * 6);
	}

	if (GL_TEXTURE_2D_MULTISAMPLE_ARRAY == texture_target)
	{
		gl.texStorage3DMultisample(texture_target, 1, internalformat, (glw::GLuint)std::pow((double)2, (double)levels),
								   (glw::GLuint)std::pow((double)2, (double)levels), layers, GL_FALSE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
	}
	else
	{
		gl.texStorage3D(texture_target, levels, internalformat, (glw::GLuint)std::pow((double)2, (double)levels),
						(glw::GLuint)std::pow((double)2, (double)levels), layers);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
	}

	gl.bindTexture(texture_target, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

	/* FBO creation. */
	gl.createFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");

	for (glw::GLuint i = 0; i < levels; ++i)
	{
		glw::GLuint j = 0;
		glw::GLuint k = 1;

		/* 3D textures are mipmapped also in depth directio, so number of layers to be tested must be limited. */
		glw::GLuint layers_at_level = (GL_TEXTURE_3D == texture_target) ?
										  (de::min(layers, layers / (glw::GLint)std::pow(2.0, (double)i))) :
										  layers;

		while (j < layers_at_level) /* Only layers with Fibonacci number index are tested to reduce the test time. */
		{
			/* Attach texture layer. */
			gl.namedFramebufferTextureLayer(m_fbo, attachment, m_to, i, j);

			if (!SubTestAttachmentError(attachment, texture_target, i, j, levels, layers))
			{
				return false;
			}

			gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

			if (is_color_attachment)
			{
				gl.drawBuffer(attachment);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");

				gl.readBuffer(attachment);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer has failed");
			}

			if (!SubTestStatus(attachment, texture_target, i, j, levels, layers))
			{
				return false;
			}

			if (GL_TEXTURE_2D_MULTISAMPLE_ARRAY != texture_target)
			{
				Clear();

				if (!SubTestContent(attachment, texture_target, internalformat, i, j, levels, layers))
				{
					return false;
				}
			}

			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

			/* Fibonacci number iteration. */
			int l = j;
			j	 = j + k;
			k	 = l;
		}
	}

	return true;
}

/** @brief Check error and log.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *  @param [in] texture_target         Texture target.
 *  @param [in] level                  Tested level.
 *  @param [in] layer                  Tested layer.
 *  @param [in] levels                 Number of levels.
 *  @param [in] layers                 Number of layers.
 *
 *  @return True if no error, false otherwise.
 */
bool TextureLayerAttachmentTest::SubTestAttachmentError(glw::GLenum attachment, glw::GLenum texture_target,
														glw::GLuint level, glw::GLint layer, glw::GLuint levels,
														glw::GLint layers)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check and log. */
	if (glw::GLenum error = gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "NamedFramebufferTexture for " << glu::getFramebufferAttachmentStr(attachment)
			<< " attachment of " << glu::getTextureTargetStr(texture_target) << " texture at level " << level
			<< " and at layer " << layer << " where texture has " << levels << " levels and " << layers
			<< " layers failed with error value " << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Check framebuffer completness.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *  @param [in] texture_target         Texture target.
 *  @param [in] level                  Tested level.
 *  @param [in] layer                  Tested layer.
 *  @param [in] levels                 Number of levels.
 *  @param [in] layers                 Number of layers.
 *
 *  @return True if framebuffer is complete, false otherwise.
 */
bool TextureLayerAttachmentTest::SubTestStatus(glw::GLenum attachment, glw::GLenum texture_target, glw::GLuint level,
											   glw::GLint layer, glw::GLuint levels, glw::GLint layers)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check framebuffer status. */
	glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);

	if (GL_FRAMEBUFFER_COMPLETE != status)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed because of framebuffer "
			<< glu::getFramebufferStatusStr(status) << " with " << glu::getTextureTargetStr(texture_target)
			<< " texture set up as " << glu::getFramebufferAttachmentStr(attachment) << " attachment and texture level "
			<< level << " and texture layer " << layer << " of texture with " << levels << " levels and " << layers
			<< " layers." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Check framebuffer cntent.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *  @param [in] texture_target         Texture target.
 *  @param [in] internalformat         Tested internal format.
 *  @param [in] level                  Tested level.
 *  @param [in] layer                  Tested layer.
 *  @param [in] levels                 Number of levels.
 *  @param [in] layers                 Number of layers.
 *
 *  @return True if framebuffer content is equal to the reference, false otherwise.
 */
bool TextureLayerAttachmentTest::SubTestContent(glw::GLenum attachment, glw::GLenum texture_target,
												glw::GLenum internalformat, glw::GLuint level, glw::GLint layer,
												glw::GLuint levels, glw::GLint layers)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check framebuffer's color content. */
	if (GL_RGBA8 == internalformat)
	{
		glw::GLfloat color[4] = { 0.f };

		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, color);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

		for (int i = 0; i < 4 /* color components */; ++i)
		{
			if (de::abs(s_reference_color[i] - color[i]) > 0.0625 /* precision */)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed with "
					<< glu::getTextureTargetStr(texture_target) << " texture set up as "
					<< glu::getFramebufferAttachmentStr(attachment) << " attachment and texture level " << level
					<< " and texture layer " << layer << " of texture with " << levels << " levels and " << layers
					<< " layers. The color content of the framebuffer was [" << color[0] << ", " << color[1] << ", "
					<< color[2] << ", " << color[3] << "], but [" << s_reference_color[0] << ", "
					<< s_reference_color[1] << ", " << s_reference_color[2] << ", " << s_reference_color[3]
					<< "] was expected." << tcu::TestLog::EndMessage;
				return false;
			}
		}
	}

	/* Check framebuffer's depth content. */
	if ((GL_DEPTH_COMPONENT24 == internalformat) || (GL_DEPTH24_STENCIL8 == internalformat))
	{
		glw::GLfloat depth = 0.f;

		gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

		if (de::abs(s_reference_depth - depth) > 0.0625 /* precision */)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed "
				<< "with texture set up as " << glu::getFramebufferAttachmentStr(attachment)
				<< " attachment and texture level " << level << " and texture layer " << layer << " of texture with "
				<< levels << " levels and " << layers << " layers. The depth content of the framebuffer was [" << depth
				<< "], but [" << s_reference_depth << "] was expected." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	/* Check framebuffer's stencil content. */
	if ((GL_STENCIL_INDEX8 == internalformat) || (GL_DEPTH24_STENCIL8 == internalformat))
	{
		glw::GLint stencil = 0;

		gl.readPixels(0, 0, 1, 1, GL_STENCIL_INDEX, GL_INT, &stencil);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

		if (s_reference_stencil != stencil)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed "
				<< "with texture set up as " << glu::getFramebufferAttachmentStr(attachment)
				<< " attachment and texture level " << level << " and texture layer " << layer << " of texture with "
				<< levels << " levels and " << layers << " layers. The stencil content of the framebuffer was ["
				<< stencil << "], but [" << s_reference_stencil << "] was expected." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

/** @brief Clear framebuffer.
 */
void TextureLayerAttachmentTest::Clear()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Setup clear values. */
	gl.clearColor(s_reference_color[0], s_reference_color[1], s_reference_color[2], s_reference_color[3]);
	gl.clearDepth(s_reference_depth);
	gl.clearStencil(s_reference_stencil);

	/* Clear rbo/fbo. */
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}

/** @brief Query maximum number of texture levels.
 *
 *  @return True if max number of texture levels, false otherwise.
 */
glw::GLuint TextureLayerAttachmentTest::MaxTextureLevels(glw::GLenum texture_target)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint max_texture_size = 1024 /* Specification default. */;

	switch (texture_target)
	{
	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
		return 1;

	case GL_TEXTURE_2D_ARRAY:

		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		return (glw::GLuint)std::log((double)max_texture_size);

	case GL_TEXTURE_CUBE_MAP_ARRAY:

		gl.getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE , &max_texture_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		return (glw::GLuint)std::log((double)max_texture_size);

	case GL_TEXTURE_3D:

		gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max_texture_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		return (glw::GLuint)std::log((double)max_texture_size);
	default:
		throw 0;
	}

	/* For compiler warnings only. */
	return 0;
}

/** @brief Query maximum number of texture layers.
 *
 *  @return True if max number of texture layers, false otherwise.
 */
glw::GLuint TextureLayerAttachmentTest::MaxTextureLayers(glw::GLenum texture_target)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint max_texture_size = 1024 /* Specification default. */;

	switch (texture_target)
	{
	case GL_TEXTURE_3D:
		gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max_texture_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		return max_texture_size;

	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
	case GL_TEXTURE_2D_ARRAY:

		gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max_texture_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		return max_texture_size;

	case GL_TEXTURE_CUBE_MAP_ARRAY:
		gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max_texture_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

		return (max_texture_size / 6) * 6; /* Make sure that max_texture_size is dividable by 6 */

	default:
		throw 0;
	}

	/* For compiler warnings only. */
	return 0;
}

/** @brief Clean up GL state.
 */
void TextureLayerAttachmentTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Cleanup. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_to)
	{
		gl.deleteTextures(1, &m_to);

		m_to = 0;
	}

	/* Returning to default clear values. */
	gl.clearColor(0.f, 0.f, 0.f, 0.f);
	gl.clearDepth(1.f);
	gl.clearStencil(0);

	/* Errors clean up. */
	while (gl.getError())
		;
}

const glw::GLenum TextureLayerAttachmentTest::s_targets[] = //!< Targets to be tested.
	{ GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_3D };

const glw::GLuint TextureLayerAttachmentTest::s_targets_count =
	sizeof(s_targets) / sizeof(s_targets[0]); //!< Number of tested targets.

const glw::GLfloat TextureLayerAttachmentTest::s_reference_color[4] = { 0.25, 0.5, 0.75, 1.0 }; //!< Reference color.
const glw::GLint   TextureLayerAttachmentTest::s_reference_color_integer[4] = { 1, 2, 3,
																			  4 }; //!< Reference integer color.
const glw::GLfloat TextureLayerAttachmentTest::s_reference_depth   = 0.5;		   //!< Reference depth.
const glw::GLint   TextureLayerAttachmentTest::s_reference_stencil = 7;			   //!< Reference stencil index.

/******************************** Named Framebuffer Read / Draw Buffer Test Implementation   ********************************/

/** @brief Named Framebuffer Read / Draw Buffer Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
DrawReadBufferTest::DrawReadBufferTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_read_draw_buffer", "Framebuffer Read and Draw Buffer Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Named Framebuffer Read / Draw Buffer Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult DrawReadBufferTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Framebuffers' objects */
	glw::GLuint framebuffer = 0;

	/* Get number of color attachments. */
	glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;

	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	std::vector<glw::GLuint> renderbuffers(max_color_attachments);

	for (glw::GLint i = 0; i < max_color_attachments; ++i)
	{
		renderbuffers[i] = 0;
	}

	try
	{
		/* Prepare framebuffer... */
		gl.genFramebuffers(1, &framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.genRenderbuffers(max_color_attachments, &(renderbuffers[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

		/* .. with renderbuffer color attachments. */
		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

			gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, renderbuffers[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
		}

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
												<< tcu::TestLog::EndMessage;

			throw 0;
		}

		/* Clear each of the framebuffer's attachments with unique color using NamedFramebufferDrawBuffer for attachment selection. */
		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.clearColor((float)i / (float)max_color_attachments, (float)i / (float)max_color_attachments,
						  (float)i / (float)max_color_attachments, (float)i / (float)max_color_attachments);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");

			gl.namedFramebufferDrawBuffer(framebuffer, GL_COLOR_ATTACHMENT0 + i);

			if (glw::GLenum error = gl.getError())
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "NamedFramebufferDrawBuffer unexpectedly generated "
					<< glu::getErrorStr(error) << " error with GL_COLOR_ATTACHMENT" << i << ". Test fails."
					<< tcu::TestLog::EndMessage;
				is_ok = false;
			}

			gl.clear(GL_COLOR_BUFFER_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear has failed");
		}

		/* Fetch framebuffer's content and compare it with reference using NamedFramebufferReadBuffer for attachment selection. */
		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.namedFramebufferReadBuffer(framebuffer, GL_COLOR_ATTACHMENT0 + i);

			if (glw::GLenum error = gl.getError())
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "NamedFramebufferReadBuffer unexpectedly generated "
					<< glu::getErrorStr(error) << " error with GL_COLOR_ATTACHMENT" << i << ". Test fails."
					<< tcu::TestLog::EndMessage;
				is_ok = false;
			}

			glw::GLfloat rgba[4] = { -1.f, -1.f, -1.f, -1.f };

			gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, rgba);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

			float expected_value = (float)i / (float)max_color_attachments;

			for (glw::GLuint j = 0; j < 4 /* number of components */; ++j)
			{
				if (de::abs(expected_value - rgba[j]) > 0.0001 /* Precision */)
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message
						<< "Named Framebuffer Draw And Read Buffer failed because resulting color value was ["
						<< rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << "] but ["
						<< expected_value << ", " << expected_value << ", " << expected_value << ", " << expected_value
						<< "] had been expected." << tcu::TestLog::EndMessage;

					is_ok = false;

					break;
				}
			}
		}

		/* Check that NamedFramebufferDrawBuffer accepts GL_NONE as mode. */
		gl.namedFramebufferDrawBuffer(framebuffer, GL_NONE);

		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "NamedFramebufferDrawBuffer unexpectedly generated "
				<< glu::getErrorStr(error) << " error with GL_NONE mode. Test fails." << tcu::TestLog::EndMessage;
			is_ok = false;
		}

		/* Check that NamedFramebufferReadBuffer accepts GL_NONE as mode. */
		gl.namedFramebufferReadBuffer(framebuffer, GL_NONE);

		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "NamedFramebufferReadBuffer unexpectedly generated "
				<< glu::getErrorStr(error) << " error with GL_NONE mode. Test fails." << tcu::TestLog::EndMessage;
			is_ok = false;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (framebuffer)
	{
		gl.deleteFramebuffers(1, &framebuffer);

		framebuffer = 0;
	}

	for (glw::GLint i = 0; i < max_color_attachments; ++i)
	{
		if (renderbuffers[i])
		{
			gl.deleteRenderbuffers(1, &(renderbuffers[i]));
		}
	}

	gl.clearColor(0.f, 0.f, 0.f, 0.f);

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Named Framebuffer Draw Buffers Test Implementation   ********************************/

/** @brief Named Framebuffer Draw Buffers Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
DrawBuffersTest::DrawBuffersTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_draw_buffers", "Framebuffer Draw Buffers Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Named Framebuffer Read / Draw Buffer Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult DrawBuffersTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Framebuffers' objects */
	glw::GLuint framebuffer = 0;

	/* Get number of color attachments. */
	glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;

	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	std::vector<glw::GLuint> renderbuffers(max_color_attachments);
	std::vector<glw::GLuint> color_attachments(max_color_attachments);

	for (glw::GLint i = 0; i < max_color_attachments; ++i)
	{
		renderbuffers[i]	 = 0;
		color_attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	}

	try
	{
		/* Prepare framebuffer... */
		gl.genFramebuffers(1, &framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.genRenderbuffers(max_color_attachments, &(renderbuffers[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

		/* .. with renderbuffer color attachments. */
		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

			gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, renderbuffers[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
		}

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
												<< tcu::TestLog::EndMessage;

			throw 0;
		}

		/* Set up all attachments as draw buffer. */
		gl.namedFramebufferDrawBuffers(framebuffer, max_color_attachments, &(color_attachments[0]));

		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "NamedFramebufferDrawBuffers unexpectedly generated "
				<< glu::getErrorStr(error) << " error. Test fails." << tcu::TestLog::EndMessage;
			is_ok = false;
		}

		/* Clear each of the framebuffer's attachments with unique color using NamedFramebufferDrawBuffer for attachment selection. */
		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.clearColor(s_rgba[0], s_rgba[1], s_rgba[2], s_rgba[3]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");

			gl.clear(GL_COLOR_BUFFER_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear has failed");
		}

		/* Fetch framebuffer's content and compare it with reference using NamedFramebufferReadBuffer for attachment selection. */
		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.readBuffer(GL_COLOR_ATTACHMENT0 + i);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer has failed");

			glw::GLfloat rgba[4] = { -1.f, -1.f, -1.f, -1.f };

			gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, rgba);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

			for (glw::GLuint j = 0; j < 4 /* number of components */; ++j)
			{
				if (de::abs(s_rgba[j] - rgba[j]) > 0.0001 /* Precision */)
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message
						<< "Named Framebuffer Draw Buffers test have failed because resulting color value was ["
						<< rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << "] but [" << s_rgba[0]
						<< ", " << s_rgba[1] << ", " << s_rgba[2] << ", " << s_rgba[3] << "] had been expected."
						<< tcu::TestLog::EndMessage;

					is_ok = false;

					break;
				}
			}
		}

		/* Check that NamedFramebufferDrawBuffers accepts GL_NONE as mode. */
		glw::GLenum none_bufs = GL_NONE;
		gl.namedFramebufferDrawBuffers(framebuffer, 1, &none_bufs);

		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "NamedFramebufferDrawBuffers unexpectedly generated "
				<< glu::getErrorStr(error) << " error with GL_NONE mode. Test fails." << tcu::TestLog::EndMessage;
			is_ok = false;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (framebuffer)
	{
		gl.deleteFramebuffers(1, &framebuffer);

		framebuffer = 0;
	}

	for (glw::GLint i = 0; i < max_color_attachments; ++i)
	{
		if (renderbuffers[i])
		{
			gl.deleteRenderbuffers(1, &(renderbuffers[i]));
		}
	}

	gl.clearColor(0.f, 0.f, 0.f, 0.f);

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

const glw::GLfloat DrawBuffersTest::s_rgba[4] = { 0.f, 0.25f, 0.5f, 0.75f };

/******************************** Named Framebuffer Invalidate Data Test Implementation   ********************************/

/** @brief Named Framebuffer Invalidate Data Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
InvalidateDataTest::InvalidateDataTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_invalidate_data", "Framebuffer Invalidate Data Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Named Framebuffer Read / Draw Buffer Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult InvalidateDataTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Framebuffers' objects */
	glw::GLuint framebuffer = 0;

	/* Get number of color attachments. */
	glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;

	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	std::vector<glw::GLuint> renderbuffers(max_color_attachments);
	std::vector<glw::GLuint> color_attachments(max_color_attachments);
	static const glw::GLenum default_attachments[]	 = { GL_COLOR, GL_DEPTH, GL_STENCIL };
	static const glw::GLuint default_attachments_count = sizeof(default_attachments) / sizeof(default_attachments[0]);

	for (glw::GLint i = 0; i < max_color_attachments; ++i)
	{
		renderbuffers[i]	 = 0;
		color_attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	}

	try
	{
		/* Invalidate Default Framebuffer data */
		gl.invalidateNamedFramebufferData(0, default_attachments_count, &(default_attachments[0]));
		is_ok &= CheckErrorAndLog(default_attachments, default_attachments_count);

		for (glw::GLuint i = 0; i < default_attachments_count; ++i)
		{
			gl.invalidateNamedFramebufferData(0, 1, &(default_attachments[i]));
			is_ok &= CheckErrorAndLog(default_attachments[i]);
		}

		/* Prepare framebuffer... */
		gl.genFramebuffers(1, &framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.genRenderbuffers(max_color_attachments, &(renderbuffers[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

		/* .. with renderbuffer color attachments. */
		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

			gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, renderbuffers[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
		}

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
												<< tcu::TestLog::EndMessage;

			throw 0;
		}

		gl.invalidateNamedFramebufferData(framebuffer, max_color_attachments, &(color_attachments[0]));
		is_ok &= CheckErrorAndLog(&(color_attachments[0]), max_color_attachments);

		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.invalidateNamedFramebufferData(framebuffer, 1, &(color_attachments[i]));
			is_ok &= CheckErrorAndLog(color_attachments[i]);
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (framebuffer)
	{
		gl.deleteFramebuffers(1, &framebuffer);

		framebuffer = 0;
	}

	for (glw::GLint i = 0; i < max_color_attachments; ++i)
	{
		if (renderbuffers[i])
		{
			gl.deleteRenderbuffers(1, &(renderbuffers[i]));
		}
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Check error and log.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *
 *  @return True if no error, false otherwise.
 */
bool InvalidateDataTest::CheckErrorAndLog(const glw::GLenum attachment)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check error. */
	if (glw::GLenum error = gl.getError())
	{
		/* There is an error. Log. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "InvalidateDataTest unexpectedly generated "
											<< glu::getErrorStr(error) << " error for attachment "
											<< glu::getFramebufferAttachmentStr(attachment) << ". Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Check error and log.
 *
 *  @param [in] attachments             Framebuffer attachments.
 *  @param [in] attachments_count       Framebuffer attachments count.
 *
 *  @return True if no error, false otherwise.
 */
bool InvalidateDataTest::CheckErrorAndLog(const glw::GLenum attachments[], glw::GLuint count)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check error. */
	if (glw::GLenum error = gl.getError())
	{
		/* There is an error. Log. */
		std::string attachments_names = "";

		for (glw::GLuint i = 0; i < count; ++i)
		{
			attachments_names.append(glu::getFramebufferAttachmentStr(attachments[i]).toString());

			if ((count - 1) != i)
			{
				attachments_names.append(", ");
			}
		}

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "InvalidateDataTest unexpectedly generated "
											<< glu::getErrorStr(error) << " error for following attachments ["
											<< attachments_names << "]. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/******************************** Named Framebuffer Invalidate Sub Data Test Implementation   ********************************/

/** @brief Named Framebuffer Invalidate Sub Data Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
InvalidateSubDataTest::InvalidateSubDataTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_invalidate_subdata", "Framebuffer Invalidate Sub Data Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Named Framebuffer Read / Draw Buffer Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult InvalidateSubDataTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Framebuffers' objects */
	glw::GLuint framebuffer = 0;

	/* Get number of color attachments. */
	glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;

	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	std::vector<glw::GLuint> renderbuffers(max_color_attachments);
	std::vector<glw::GLuint> color_attachments(max_color_attachments);
	static const glw::GLenum default_attachments[]	 = { GL_COLOR, GL_DEPTH, GL_STENCIL };
	static const glw::GLuint default_attachments_count = sizeof(default_attachments) / sizeof(default_attachments[0]);

	for (glw::GLint i = 0; i < max_color_attachments; ++i)
	{
		renderbuffers[i]	 = 0;
		color_attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	}

	try
	{
		/* Invalidate Default Framebuffer data */
		gl.invalidateNamedFramebufferSubData(0, default_attachments_count, &(default_attachments[0]), 0, 0, 1, 1);
		is_ok &= CheckErrorAndLog(default_attachments, default_attachments_count);

		for (glw::GLuint i = 0; i < default_attachments_count; ++i)
		{
			gl.invalidateNamedFramebufferSubData(0, 1, &(default_attachments[i]), 0, 0, 1, 1);
			is_ok &= CheckErrorAndLog(default_attachments[i]);
		}

		/* Prepare framebuffer... */
		gl.genFramebuffers(1, &framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.genRenderbuffers(max_color_attachments, &(renderbuffers[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

		/* .. with renderbuffer color attachments. */
		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

			gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 4, 4);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, renderbuffers[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
		}

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
												<< tcu::TestLog::EndMessage;

			throw 0;
		}

		gl.invalidateNamedFramebufferSubData(framebuffer, max_color_attachments, &(color_attachments[0]), 1, 1, 2, 2);
		is_ok &= CheckErrorAndLog(&(color_attachments[0]), max_color_attachments);

		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			gl.invalidateNamedFramebufferSubData(framebuffer, 1, &(color_attachments[i]), 1, 1, 2, 2);
			is_ok &= CheckErrorAndLog(color_attachments[i]);
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (framebuffer)
	{
		gl.deleteFramebuffers(1, &framebuffer);

		framebuffer = 0;
	}

	for (glw::GLint i = 0; i < max_color_attachments; ++i)
	{
		if (renderbuffers[i])
		{
			gl.deleteRenderbuffers(1, &(renderbuffers[i]));
		}
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Check error and log.
 *
 *  @param [in] attachment             Framebuffer attachment.
 *
 *  @return True if no error, false otherwise.
 */
bool InvalidateSubDataTest::CheckErrorAndLog(const glw::GLenum attachment)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check error. */
	if (glw::GLenum error = gl.getError())
	{
		/* There is an error. Log. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "InvalidateSubDataTest unexpectedly generated "
											<< glu::getErrorStr(error) << " error for attachment "
											<< glu::getFramebufferAttachmentStr(attachment) << ". Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Check error and log.
 *
 *  @param [in] attachments             Framebuffer attachments.
 *  @param [in] attachments_count       Framebuffer attachments count.
 *
 *  @return True if no error, false otherwise.
 */
bool InvalidateSubDataTest::CheckErrorAndLog(const glw::GLenum attachments[], glw::GLuint count)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check error. */
	if (glw::GLenum error = gl.getError())
	{
		/* There is an error. Log. */
		std::string attachments_names = "";

		for (glw::GLuint i = 0; i < count; ++i)
		{
			attachments_names.append(glu::getFramebufferAttachmentStr(attachments[i]).toString());

			if ((count - 1) != i)
			{
				attachments_names.append(", ");
			}
		}

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "InvalidateSubDataTest unexpectedly generated "
											<< glu::getErrorStr(error) << " error for following attachments ["
											<< attachments_names << "]. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/******************************** Clear Named Framebuffer Test Implementation   ********************************/

/** @brief Clear Named Framebuffer Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ClearTest::ClearTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_clear", "Clear Named Framebuffer Test")
	, m_fbo(0)
	, m_renderbuffers(0)
	, m_renderbuffers_count(0)
{
	/* Intentionally left blank. */
}

/** @brief Compare two floats (template specialization).
 *
 *  @param [in] first        First  float to be compared.
 *  @param [in] second       Second float to be compared.
 *
 *  @return True if floats are equal within +-(1.f/64.f) precision range, false otherwise.
 */
template <>
bool ClearTest::Compare<glw::GLfloat>(const glw::GLfloat first, const glw::GLfloat second)
{
	return (de::abs(first - second) < (1.f / 64.f) /* Precission. */);
}

/** @brief Compare two objects (template general specialization).
 *
 *  @param [in] first        First  objetc to be compared.
 *  @param [in] second       Second object to be compared.
 *
 *  @return True if floats are equal, false otherwise.
 */
template <typename T>
bool ClearTest::Compare(const T first, const T second)
{
	return (first == second);
}

/** @brief Clear color buffer (float specialization), check errors and log.
 *
 *  @param [in] buffer      Buffer to be cleared.
 *  @param [in] drawbuffer  Drawbuffer to be cleared.
 *  @param [in] value       Value to be cleared with.
 *
 *  @return True if succeeded without errors, false otherwise.
 */
template <>
bool ClearTest::ClearColor<glw::GLfloat>(glw::GLenum buffer, glw::GLint drawbuffer, glw::GLfloat value)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLfloat value_vector[4] = { value, 0, 0, 0 };

	gl.clearNamedFramebufferfv(m_fbo, buffer, drawbuffer, value_vector);

	if (glw::GLenum error = gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "ClearNamedFramebufferfv unexpectedly generated " << glu::getErrorStr(error)
			<< " error. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Clear color buffer (int specialization), check errors and log.
 *
 *  @param [in] buffer      Buffer to be cleared.
 *  @param [in] drawbuffer  Drawbuffer to be cleared.
 *  @param [in] value       Value to be cleared with.
 *
 *  @return True if succeeded without errors, false otherwise.
 */
template <>
bool ClearTest::ClearColor<glw::GLint>(glw::GLenum buffer, glw::GLint drawbuffer, glw::GLint value)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint value_vector[4] = { value, 0, 0, 0 };

	gl.clearNamedFramebufferiv(m_fbo, buffer, drawbuffer, value_vector);

	if (glw::GLenum error = gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "ClearNamedFramebufferiv unexpectedly generated " << glu::getErrorStr(error)
			<< " error. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Clear color buffer (uint specialization), check errors and log.
 *
 *  @param [in] buffer      Buffer to be cleared.
 *  @param [in] drawbuffer  Drawbuffer to be cleared.
 *  @param [in] value       Value to be cleared with.
 *
 *  @return True if succeeded without errors, false otherwise.
 */
template <>
bool ClearTest::ClearColor<glw::GLuint>(glw::GLenum buffer, glw::GLint drawbuffer, glw::GLuint value)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint value_vector[4] = { value, 0, 0, 0 };

	gl.clearNamedFramebufferuiv(m_fbo, buffer, drawbuffer, value_vector);

	if (glw::GLenum error = gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "ClearNamedFramebufferuiv unexpectedly generated " << glu::getErrorStr(error)
			<< " error. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Format of the buffer (float specialization).
 *
 *  @return Format.
 */
template <>
glw::GLenum ClearTest::Format<GLfloat>()
{
	return GL_RED;
}

/** @brief Format of the buffer (int and uint specialization).
 *
 *  @return Format.
 */
template <typename T>
glw::GLenum ClearTest::Format()
{
	return GL_RED_INTEGER;
}

/** @brief Type of the buffer (float specialization).
 *
 *  @return Type.
 */
template <>
glw::GLenum ClearTest::Type<glw::GLfloat>()
{
	return GL_FLOAT;
}

/** @brief Type of the buffer (int specialization).
 *
 *  @return Type.
 */
template <>
glw::GLenum ClearTest::Type<glw::GLint>()
{
	return GL_INT;
}

/** @brief Type of the buffer (uint specialization).
 *
 *  @return Type.
 */
template <>
glw::GLenum ClearTest::Type<glw::GLuint>()
{
	return GL_UNSIGNED_INT;
}

/** @brief Test DSA Clear function (color).
 *
 *  @param [in] buffer      Buffer to be cleared.
 *  @param [in] attachment  Attachment to be tested.
 *  @param [in] value       Value to be cleared with.
 *
 *  @return True if test succeeded, false otherwise.
 */
template <typename T>
bool ClearTest::TestClearColor(glw::GLenum buffer, glw::GLenum attachment, T value)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.drawBuffer(attachment);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");

	/* Clear. */
	if (ClearColor<T>(buffer, 0, value))
	{
		/* Fetching framebuffer content. */
		T pixel = (T)0;

		gl.readBuffer(attachment);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer has failed");

		gl.readPixels(0, 0, 1, 1, Format<T>(), Type<T>(), &pixel);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixel has failed");

		/* Comparison with reference value. */
		if (Compare(pixel, value))
		{
			return true;
		}

		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "ClearNamedFramebuffer did not cleared color attachment "
			<< glu::getFramebufferAttachmentStr(attachment) << " of the framebuffer." << tcu::TestLog::EndMessage;
	}

	return false;
}

/** @brief Test DSA Clear function (depth/stencil).
 *
 *  @param [in] stencil     Stencil value to be cleared with.
 *  @param [in] depth       Depth value to be cleared with.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool ClearTest::TestClearDepthAndStencil(glw::GLfloat depth, glw::GLint stencil)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Clearing depth and stencil. */
	gl.clearNamedFramebufferfi(m_fbo, GL_DEPTH_STENCIL, 0, depth, stencil);

	if (glw::GLenum error = gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "ClearNamedFramebufferufi unexpectedly generated " << glu::getErrorStr(error)
			<< " error. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	/* Clear. */
	/* Fetching framebuffer content. */
	glw::GLfloat the_depth   = 0.f;
	glw::GLint   the_stencil = 0;

	gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &the_depth);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixel has failed");

	gl.readPixels(0, 0, 1, 1, GL_STENCIL_INDEX, GL_INT, &the_stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixel has failed");

	/* Comparison with reference value. */
	if (Compare(the_depth, depth) || Compare(the_stencil, stencil))
	{
		return true;
	}

	m_context.getTestContext().getLog()
		<< tcu::TestLog::Message
		<< "ClearNamedFramebufferfi did not cleared depth/stencil attachment of the framebuffer."
		<< tcu::TestLog::EndMessage;

	return true;
}

/** @brief Iterate Clear Named Framebuffer Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ClearTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Fixed point color test. */
		PrepareFramebuffer(GL_COLOR, GL_R8);

		for (glw::GLint i = 0; i < (glw::GLint)m_renderbuffers_count; ++i)
		{
			is_ok &= TestClearColor<glw::GLfloat>(GL_COLOR, GL_COLOR_ATTACHMENT0 + i, 0.5);
		}

		Clean();

		/* Floating point color test. */
		PrepareFramebuffer(GL_COLOR, GL_R32F);

		for (glw::GLint i = 0; i < (glw::GLint)m_renderbuffers_count; ++i)
		{
			is_ok &= TestClearColor<glw::GLfloat>(GL_COLOR, GL_COLOR_ATTACHMENT0 + i, 0.5);
		}

		Clean();

		/* Signed integer color test. */
		PrepareFramebuffer(GL_COLOR, GL_R8I);

		for (glw::GLint i = 0; i < (glw::GLint)m_renderbuffers_count; ++i)
		{
			is_ok &= TestClearColor<glw::GLint>(GL_COLOR, GL_COLOR_ATTACHMENT0 + i, -16);
		}

		Clean();

		/* Unsigned integer color test. */
		PrepareFramebuffer(GL_COLOR, GL_R8UI);

		for (glw::GLint i = 0; i < (glw::GLint)m_renderbuffers_count; ++i)
		{
			is_ok &= TestClearColor<glw::GLuint>(GL_COLOR, GL_COLOR_ATTACHMENT0 + i, 16);
		}

		Clean();

		/* Depth / stencil test. */
		PrepareFramebuffer(GL_DEPTH_STENCIL, GL_DEPTH24_STENCIL8);

		is_ok &= TestClearDepthAndStencil(1, 1);

		Clean();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Prepare framebuffer.
 *
 *  @param [in] buffer          Buffer to be prepared.
 *  @param [in] internalformat  Internal format to be prepared
 */
void ClearTest::PrepareFramebuffer(glw::GLenum buffer, glw::GLenum internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check that ther is no other fbo. */
	if ((0 != m_fbo) || (DE_NULL != m_renderbuffers))
	{
		throw 0;
	}

	/* Prepare framebuffer... */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

	if (buffer == GL_COLOR)
	{
		glw::GLint max_color_attachments =
			8; /* OpenGL 4.5 specification default (see Implementation Dependent Values tables). */

		gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

		m_renderbuffers = new glw::GLuint[max_color_attachments];

		if (m_renderbuffers)
		{
			/* ... with renderbuffer color attachments. */

			gl.genRenderbuffers(max_color_attachments, m_renderbuffers);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

			m_renderbuffers_count = max_color_attachments;

			for (glw::GLint i = 0; i < max_color_attachments; ++i)
			{
				gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers[i]);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

				gl.renderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

				gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER,
										   m_renderbuffers[i]);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
			}
		}
	}

	if (buffer == GL_DEPTH_STENCIL)
	{
		/* ... with depth and stencil attachments. */

		m_renderbuffers = new glw::GLuint[1];

		if (m_renderbuffers)
		{
			gl.genRenderbuffers(1, m_renderbuffers);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

			gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

			m_renderbuffers_count = 1;

			gl.renderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
									   m_renderbuffers[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
		}
	}

	/* Check that framebuffer is complete. */
	if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}
}

/** @brief Clean up GL state.
 */
void ClearTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Releasing objects. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (DE_NULL != m_renderbuffers)
	{
		if (m_renderbuffers_count)
		{
			gl.deleteRenderbuffers(m_renderbuffers_count, m_renderbuffers);
		}

		delete[] m_renderbuffers;

		m_renderbuffers		  = DE_NULL;
		m_renderbuffers_count = 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Blit Named Framebuffer Test Implementation   ********************************/

/** @brief Named Framebuffer blit Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
BlitTest::BlitTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_blit", "Framebuffer Blit Test")
	, m_fbo_src(0)
	, m_rbo_color_src(0)
	, m_rbo_depth_stencil_src(0)
	, m_fbo_dst(0)
	, m_rbo_color_dst(0)
	, m_rbo_depth_stencil_dst(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Named Framebuffer Blit Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult BlitTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		PrepareFramebuffers();

		is_ok = Test();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Prepare framebuffer.
 */
void BlitTest::PrepareFramebuffers()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare source framebuffer */
	gl.genFramebuffers(1, &m_fbo_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

	gl.genRenderbuffers(1, &m_rbo_color_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_color_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 2, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	gl.genRenderbuffers(1, &m_rbo_depth_stencil_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_depth_stencil_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 2, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	/* Check that framebuffer is complete. */
	if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}

	/* Prepare destination framebuffer */
	gl.genFramebuffers(1, &m_fbo_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

	gl.genRenderbuffers(1, &m_rbo_color_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_color_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 3, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	gl.genRenderbuffers(1, &m_rbo_depth_stencil_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_depth_stencil_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 3, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	/* Check that framebuffer is complete. */
	if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}
}

/** @brief Do the blit test.
 */
bool BlitTest::Test()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	ClearFramebuffer(1.f, 0.f, 0.f, 0.5f, 1);

	gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 1, 1, 0, 0, 1, 1,
							GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);

	if (CheckErrorAndLog())
	{
		ClearFramebuffer(0.f, 1.f, 0.f, 0.25f, 2);

		gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 1, 1, 1, 0, 2, 1, GL_COLOR_BUFFER_BIT, GL_LINEAR);
		gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 1, 1, 1, 0, 2, 1,
								GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);

		if (CheckErrorAndLog())
		{
			ClearFramebuffer(0.f, 0.f, 1.f, 0.125f, 3);

			gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 2, 2, 2, 0, 3, 1,
									GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);

			if (CheckErrorAndLog())
			{
				ClearFramebuffer(1.f, 1.f, 0.f, 0.0625f, 4);

				gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 1, 1, 0, 1, 3, 2,
										GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);

				if (CheckErrorAndLog())
				{
					gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_dst);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

					if (CheckColor() && CheckDepth() && CheckStencil())
					{
						return true;
					}
				}
			}
		}
	}

	return false;
}

/** @brief Check error and log.
 *
 *  @return true if no error, false otherwise.
 */
bool BlitTest::CheckErrorAndLog()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Error query. */
	if (glw::GLenum error = gl.getError())
	{
		/* Log. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "BlitNamedFramebuffer unexpectedly generated "
											<< glu::getErrorStr(error) << " error." << tcu::TestLog::EndMessage;

		/* Returning result. */
		return false;
	}

	/* Returning result. */
	return true;
}

/** @brief Check color and log.
 *
 *  @return true if color matches reference, false otherwise.
 */
bool BlitTest::CheckColor()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Reference values. */
	static const glw::GLfloat reference[2][3][4] = {
		{ { 1.f, 0.f, 0.f, 1.f }, { 0.f, 1.f, 0.f, 1.f }, { 0.f, 0.f, 1.f, 1.f } },
		{ { 1.f, 1.f, 0.f, 1.f }, { 1.f, 1.f, 0.f, 1.f }, { 1.f, 1.f, 0.f, 1.f } }
	};

	/* Copy buffer. */
	glw::GLfloat color[2][3][4] = { { { 0 } } };

	/* Reading from GL. */
	gl.readPixels(0, 0, 3, 2, GL_RGBA, GL_FLOAT, color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

	/* Comparison against the reference. */
	for (glw::GLuint j = 0; j < 2; ++j)
	{
		for (glw::GLuint i = 0; i < 3; ++i)
		{
			for (glw::GLuint k = 0; k < 4; ++k)
			{
				if (de::abs(reference[j][i][k] - color[j][i][k]) > (1.f / 64.f) /* Precision. */)
				{
					/* Log. */
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "Blitted framebuffer color buffer contains [[" << color[0][0][0]
						<< ", " << color[0][0][1] << ", " << color[0][0][2] << ", " << color[0][0][3] << "], ["
						<< color[0][1][0] << ", " << color[0][1][1] << ", " << color[0][1][2] << ", " << color[0][1][3]
						<< "], [" << color[0][2][0] << ", " << color[0][2][1] << ", " << color[0][2][2] << ", "
						<< color[0][2][3] << "],\n[" << color[1][0][0] << ", " << color[1][0][1] << ", "
						<< color[1][0][2] << ", " << color[1][0][3] << "], [" << color[1][1][0] << ", "
						<< color[1][1][1] << ", " << color[1][1][2] << ", " << color[1][1][3] << "], ["
						<< color[1][2][0] << ", " << color[1][2][1] << ", " << color[1][2][2] << ", " << color[1][2][3]
						<< "]], but\n"
						<< reference[0][0][0] << ", " << reference[0][0][1] << ", " << reference[0][0][2] << ", "
						<< reference[0][0][3] << "], [" << reference[0][1][0] << ", " << reference[0][1][1] << ", "
						<< reference[0][1][2] << ", " << reference[0][1][3] << "], [" << reference[0][2][0] << ", "
						<< reference[0][2][1] << ", " << reference[0][2][2] << ", " << reference[0][2][3] << "],\n["
						<< reference[1][0][0] << ", " << reference[1][0][1] << ", " << reference[1][0][2] << ", "
						<< reference[1][0][3] << "], [" << reference[1][1][0] << ", " << reference[1][1][1] << ", "
						<< reference[1][1][2] << ", " << reference[1][1][3] << "], [" << reference[1][2][0] << ", "
						<< reference[1][2][1] << ", " << reference[1][2][2] << ", " << reference[1][2][3]
						<< "]] was expected.\n"
						<< tcu::TestLog::EndMessage;

					return false;
				}
			}
		}
	}

	return true;
}

/** @brief Check depth and log.
 *
 *  @return true if depth matches reference, false otherwise.
 */
bool BlitTest::CheckDepth()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Reference values. */
	static const glw::GLfloat reference[2][3] = { { 0.5, 0.25, 0.125 }, { 0.0625, 0.0625, 0.0625 } };

	/* Copy buffer. */
	glw::GLfloat depth[2][3] = { { 0 } };

	/* Reading from GL. */
	gl.readPixels(0, 0, 3, 2, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

	/* Comparison against the reference. */
	for (glw::GLuint j = 0; j < 2; ++j)
	{
		for (glw::GLuint i = 0; i < 3; ++i)
		{
			if (de::abs(reference[j][i] - depth[j][i]) > (1.f / 64.f) /* Precision. */)
			{
				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Blitted framebuffer depth buffer contains [" << depth[0][0] << ", "
					<< depth[0][1] << ", " << depth[0][2] << ", \n"
					<< depth[1][0] << ", " << depth[1][1] << ", " << depth[1][2] << "], but " << reference[0][0] << ", "
					<< reference[0][1] << ", " << reference[0][2] << ", \n"
					<< reference[1][0] << ", " << reference[1][1] << ", " << reference[1][2] << "] was expected."
					<< tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	return true;
}

/** @brief Check stencil and log.
 *
 *  @return true if stencil matches reference, false otherwise.
 */
bool BlitTest::CheckStencil()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Reference values. */
	static const glw::GLint reference[2][3] = { { 1, 2, 3 }, { 4, 4, 4 } };

	/* Copy buffer. */
	glw::GLint stencil[2][3] = { { 0 } };

	/* Reading from GL. */
	gl.readPixels(0, 0, 3, 2, GL_STENCIL_INDEX, GL_INT, stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

	/* Comparison against the reference. */
	for (glw::GLuint j = 0; j < 2; ++j)
	{
		for (glw::GLuint i = 0; i < 3; ++i)
		{
			if (reference[j][i] != stencil[j][i])
			{
				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Blitted framebuffer stencil buffer contains [" << stencil[0][0] << ", "
					<< stencil[0][1] << ", " << stencil[0][2] << ", \n"
					<< stencil[1][0] << ", " << stencil[1][1] << ", " << stencil[1][2] << "], but " << reference[0][0]
					<< ", " << reference[0][1] << ", " << reference[0][2] << ", \n"
					<< reference[1][0] << ", " << reference[1][1] << ", " << reference[1][2] << "] was expected."
					<< tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	return true;
}

/** @brief Clear framebuffer.
 *
 *  @param [in] red         Color component.
 *  @param [in] green       Color component.
 *  @param [in] blue        Color component.
 *  @param [in] alpha       Color component.
 *  @param [in] depth       Depth component.
 *  @param [in] stencil     Stencil index.
 */
void BlitTest::ClearFramebuffer(glw::GLfloat red, glw::GLfloat green, glw::GLfloat blue, glw::GLfloat depth,
								glw::GLint stencil)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Setup clear values. */
	gl.clearColor(red, green, blue, 1.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");

	gl.clearDepth(depth);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");

	gl.clearStencil(stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");

	/* Clearing. */
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");
}

/** @brief Clean up GL state.
 */
void BlitTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Releasing objects. */
	if (m_fbo_src)
	{
		gl.deleteFramebuffers(1, &m_fbo_src);

		m_fbo_src = 0;
	}

	if (m_fbo_dst)
	{
		gl.deleteFramebuffers(1, &m_fbo_dst);

		m_fbo_dst = 0;
	}

	if (m_rbo_color_src)
	{
		gl.deleteRenderbuffers(1, &m_rbo_color_src);

		m_rbo_color_src = 0;
	}

	if (m_rbo_color_dst)
	{
		gl.deleteRenderbuffers(1, &m_rbo_color_dst);

		m_rbo_color_dst = 0;
	}

	if (m_rbo_depth_stencil_src)
	{
		gl.deleteRenderbuffers(1, &m_rbo_depth_stencil_src);

		m_rbo_depth_stencil_src = 0;
	}

	if (m_rbo_depth_stencil_dst)
	{
		gl.deleteRenderbuffers(1, &m_rbo_depth_stencil_dst);

		m_rbo_depth_stencil_dst = 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Framebuffer Check Status Test Implementation   ********************************/

/** @brief Check Status Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CheckStatusTest::CheckStatusTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_check_status", "Framebuffer Check Status Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Check Status Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CheckStatusTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool maybe_ok = true;
	bool is_error = false;

	try
	{
		/* The specification is not clear about framebuffer completness. OpenGL 4.5 core profile
		 specification in chapter 9.4.2 says:
		 "The framebuffer object bound to target is said to be framebuffer complete if all
		 the following conditions are true [...]"
		 It does not say that framebuffer is incomplete when any of the conditions are not met.
		 Due to this wording, except for obvious cases (incomplete attachment and missing attachments)
		 other tests ar optional and may result in QP_TEST_RESULT_COMPATIBILITY_WARNING when fail. */
		is_ok &= IncompleteAttachmentTestCase();
		is_ok &= MissingAttachmentTestCase();

		maybe_ok &= IncompleteMultisampleRenderbufferTestCase();
		maybe_ok &= IncompleteMultisampleTextureTestCase();
		maybe_ok &= IncompleteLayerTargetsTestCase();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		if (maybe_ok)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Pass with Compatibility Warning");
		}
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Incomplete Attachment Test Case
 *
 *  @return True if test case succeeded, false otherwise.
 */
bool CheckStatusTest::IncompleteAttachmentTestCase()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Test result */
	bool is_ok	= true;
	bool is_error = false;

	/* Test objects. */
	glw::GLuint fbo = 0;
	glw::GLuint rbo = 0;

	try
	{
		gl.genFramebuffers(1, &fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.genRenderbuffers(1, &rbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		glw::GLenum status = 0;

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT != (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_ATTACHMENT value. "
				<< glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Releasing obnjects. */
	if (fbo)
	{
		gl.deleteFramebuffers(1, &fbo);
	}

	if (rbo)
	{
		gl.deleteRenderbuffers(1, &rbo);
	}

	if (is_error)
	{
		throw 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	return is_ok;
}

/** Missing Attachment Test Case
 *
 *  @return True if test case succeeded, false otherwise.
 */
bool CheckStatusTest::MissingAttachmentTestCase()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Test result */
	bool is_ok	= true;
	bool is_error = false;

	/* Test objects. */
	glw::GLuint fbo = 0;

	try
	{
		gl.genFramebuffers(1, &fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		glw::GLenum status = 0;

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT !=
			(status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT value. "
				<< glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Releasing obnjects. */
	if (fbo)
	{
		gl.deleteRenderbuffers(1, &fbo);
	}

	if (is_error)
	{
		throw 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	return is_ok;
}

/** Incomplete Multisample Renderbuffer Test Case
 *
 *  @return True if test case succeeded, false otherwise.
 */
bool CheckStatusTest::IncompleteMultisampleRenderbufferTestCase()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Test result */
	bool is_ok	= true;
	bool is_error = false;

	/* Test objects. */
	glw::GLuint fbo	= 0;
	glw::GLuint rbo[2] = { 0 };

	try
	{
		gl.genFramebuffers(1, &fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.genRenderbuffers(2, rbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_R8, 1, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_R8, 1, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbo[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		glw::GLenum status = 0;

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE != (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_MULTISAMPLE value. "
				<< glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Releasing obnjects. */
	if (fbo)
	{
		gl.deleteFramebuffers(1, &fbo);
	}

	for (glw::GLuint i = 0; i < 2; ++i)
	{
		if (rbo[i])
		{
			gl.deleteRenderbuffers(1, &rbo[i]);
		}
	}

	if (is_error)
	{
		throw 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	return is_ok;
}

/** Incomplete Multisample Texture Test Case
 *
 *  @return True if test case succeeded, false otherwise.
 */
bool CheckStatusTest::IncompleteMultisampleTextureTestCase()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Test result */
	bool is_ok	= true;
	bool is_error = false;

	/* Test objects. */
	glw::GLuint fbo   = 0;
	glw::GLuint rbo   = 0;
	glw::GLuint to[2] = { 0 };

	try
	{
		gl.genFramebuffers(1, &fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.genTextures(2, to);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_R8, 1, 1, GL_FALSE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample has failed");

		gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to[0], 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_R8, 1, 1, GL_TRUE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample has failed");

		gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to[1], 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

		gl.genRenderbuffers(1, &rbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_R8, 1, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		glw::GLenum status = 0;

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE != (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_MULTISAMPLE value. "
				<< glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Releasing obnjects. */
	if (fbo)
	{
		gl.deleteFramebuffers(1, &fbo);
	}

	for (glw::GLuint i = 0; i < 2; ++i)
	{
		if (to[i])
		{
			gl.deleteTextures(1, &to[i]);
		}
	}

	if (rbo)
	{
		gl.deleteRenderbuffers(1, &rbo);
	}

	if (is_error)
	{
		throw 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	return is_ok;
}

/** Incomplete Layer Targets Test Case
 *
 *  @return True if test case succeeded, false otherwise.
 */
bool CheckStatusTest::IncompleteLayerTargetsTestCase()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Test result */
	bool is_ok	= true;
	bool is_error = false;

	/* Test objects. */
	glw::GLuint fbo   = 0;
	glw::GLuint to[2] = { 0 };

	try
	{
		gl.genFramebuffers(1, &fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		gl.genTextures(2, to);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_3D, to[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texStorage3D(GL_TEXTURE_3D, 1, GL_R8, 2, 2, 2);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample has failed");

		gl.framebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, to[0], 0, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

		gl.bindTexture(GL_TEXTURE_2D, to[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8, 1, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample has failed");

		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, to[1], 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		glw::GLenum status = 0;

		/* Check that framebuffer is complete. */
		if (GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS != (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS value. "
				<< glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Releasing obnjects. */
	if (fbo)
	{
		gl.deleteFramebuffers(1, &fbo);
	}

	for (glw::GLuint i = 0; i < 2; ++i)
	{
		if (to[i])
		{
			gl.deleteTextures(1, &to[i]);
		}
	}

	if (is_error)
	{
		throw 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	return is_ok;
}

/******************************** Get Named Framebuffer Parameters Test Implementation   ********************************/

/** @brief Get Named Framebuffer Parameters Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetParametersTest::GetParametersTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_get_parameters", "Get Named Framebuffer Parameters Test")
	, m_fbo(0)
	, m_rbo(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Check Status Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetParametersTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		is_ok &= TestDefaultFramebuffer();

		PrepareFramebuffer();

		is_ok &= TestCustomFramebuffer();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Prepare framebuffer.
 */
void GetParametersTest::PrepareFramebuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

	gl.genRenderbuffers(1, &m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, 1, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	/* Check that framebuffer is complete. */
	if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unexpectedly framebuffer was incomplete."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}
}

/** Default framebuffer Test Case
 *
 *  @return True if test case succeeded, false otherwise.
 */
bool GetParametersTest::TestDefaultFramebuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	static const glw::GLenum pnames[] = { GL_DOUBLEBUFFER,
										  GL_IMPLEMENTATION_COLOR_READ_FORMAT,
										  GL_IMPLEMENTATION_COLOR_READ_TYPE,
										  GL_SAMPLES,
										  GL_SAMPLE_BUFFERS,
										  GL_STEREO };

	static const glw::GLchar* pnames_strings[] = { "GL_DOUBLEBUFFER",
												   "GL_IMPLEMENTATION_COLOR_READ_FORMAT",
												   "GL_IMPLEMENTATION_COLOR_READ_TYPE",
												   "GL_SAMPLES",
												   "GL_SAMPLE_BUFFERS",
												   "GL_STEREO" };

	glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);

	for (glw::GLuint i = 0; i < pnames_count; ++i)
	{
		glw::GLint parameter_legacy = 0;
		glw::GLint parameter_dsa	= 0;

		gl.getFramebufferParameteriv(GL_FRAMEBUFFER, pnames[i], &parameter_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");

		gl.getNamedFramebufferParameteriv(0, pnames[i], &parameter_dsa);

		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GetNamedFramebufferParameteriv unexpectedly generated "
				<< glu::getErrorStr(error) << " error when called with " << pnames_strings[i]
				<< " parameter name for default framebuffer." << tcu::TestLog::EndMessage;

			is_ok = false;

			continue;
		}

		if (parameter_legacy != parameter_dsa)
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedFramebufferParameteriv returned "
												<< parameter_dsa << ", but " << parameter_legacy << " was expected for "
												<< pnames_strings[i] << " parameter name of default object."
												<< tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}

	return is_ok;
}

/** Framebuffer Object Test Case
 *
 *  @return True if test case succeeded, false otherwise.
 */
bool GetParametersTest::TestCustomFramebuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	static const glw::GLenum pnames[] = { GL_DOUBLEBUFFER,
										  GL_IMPLEMENTATION_COLOR_READ_FORMAT,
										  GL_IMPLEMENTATION_COLOR_READ_TYPE,
										  GL_SAMPLES,
										  GL_SAMPLE_BUFFERS,
										  GL_STEREO,
										  GL_FRAMEBUFFER_DEFAULT_WIDTH,
										  GL_FRAMEBUFFER_DEFAULT_HEIGHT,
										  GL_FRAMEBUFFER_DEFAULT_LAYERS,
										  GL_FRAMEBUFFER_DEFAULT_SAMPLES,
										  GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS };

	static const glw::GLchar* pnames_strings[] = { "GL_DOUBLEBUFFER",
												   "GL_IMPLEMENTATION_COLOR_READ_FORMAT",
												   "GL_IMPLEMENTATION_COLOR_READ_TYPE",
												   "GL_SAMPLES",
												   "GL_SAMPLE_BUFFERS",
												   "GL_STEREO",
												   "FRAMEBUFFER_DEFAULT_WIDTH",
												   "FRAMEBUFFER_DEFAULT_HEIGHT",
												   "FRAMEBUFFER_DEFAULT_LAYERS",
												   "FRAMEBUFFER_DEFAULT_SAMPLES",
												   "FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS" };

	glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);

	for (glw::GLuint i = 0; i < pnames_count; ++i)
	{
		glw::GLint parameter_legacy = 0;
		glw::GLint parameter_dsa	= 0;

		gl.getFramebufferParameteriv(GL_FRAMEBUFFER, pnames[i], &parameter_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");

		gl.getNamedFramebufferParameteriv(m_fbo, pnames[i], &parameter_dsa);

		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GetNamedFramebufferParameteriv unexpectedly generated "
				<< glu::getErrorStr(error) << " error when called with " << pnames_strings[i]
				<< " parameter name for framebuffer object." << tcu::TestLog::EndMessage;

			is_ok = false;

			continue;
		}

		if (parameter_legacy != parameter_dsa)
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedFramebufferParameteriv returned "
												<< parameter_dsa << ", but " << parameter_legacy << " was expected for "
												<< pnames_strings[i] << " parameter name of framebuffer object."
												<< tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}

	return is_ok;
}

/** @brief Clean up GL state.
 */
void GetParametersTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Releasing obnjects. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_rbo)
	{
		gl.deleteRenderbuffers(1, &m_rbo);

		m_rbo = 0;
	}

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Get Named Framebuffer Attachment Parameters Test Implementation   ********************************/

/** @brief Get Named Framebuffer Parameters Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetAttachmentParametersTest::GetAttachmentParametersTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_get_attachment_parameters",
					 "Get Named Framebuffer Attachment Parameters Test")
	, m_fbo(0)
{
	memset(m_rbo, 0, sizeof(m_rbo));
	memset(m_to, 0, sizeof(m_to));
}

/** @brief Iterate Get Named Framebuffer Attachment Parameters Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetAttachmentParametersTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Default framebuffer. */
		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

		is_ok &= TestDefaultFramebuffer();

		/* Framebuffer object with renderbuffer attachments (depth only). */
		CreateRenderbufferFramebuffer(true, false);

		is_ok &= TestRenderbufferFramebuffer(false);

		Clean();

		/* Framebuffer object with renderbuffer attachments (stencil only). */
		CreateRenderbufferFramebuffer(false, true);

		is_ok &= TestRenderbufferFramebuffer(false);

		Clean();

		/* Framebuffer object with renderbuffer attachments (depth-stencil merged). */
		CreateRenderbufferFramebuffer(true, true);

		is_ok &= TestRenderbufferFramebuffer(true);

		Clean();

		/* Framebuffer object with texture attachments (depth only). */
		CreateTextureFramebuffer(true, false);

		is_ok &= TestTextureFramebuffer(false);

		Clean();

		/* Framebuffer object with texture attachments (stencil only). */
		CreateTextureFramebuffer(false, true);

		is_ok &= TestTextureFramebuffer(false);

		Clean();

		/* Framebuffer object with texture attachments (depth-stencil merged). */
		CreateTextureFramebuffer(true, true);

		is_ok &= TestTextureFramebuffer(true);

		Clean();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Create framebuffer with renderbuffer
 *
 *  @param [in] depth   Prepare framebuffer with depth buffer.
 *  @param [in] stencil   Prepare framebuffer with stencil buffer.
 *
 *  @note If both depth and stencil, the joined dept_stencil buffer will be created.
 */
void GetAttachmentParametersTest::CreateRenderbufferFramebuffer(bool depth, bool stencil)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

	gl.genRenderbuffers(2, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	if (depth && (!stencil))
	{
		gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 1, 2);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbo[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
	}

	if ((!depth) && stencil)
	{
		gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 1, 2);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
	}

	if (depth && stencil)
	{
		gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1, 2);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
	}

	/* Check that framebuffer is complete. */
	if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unexpectedly framebuffer was incomplete."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}
}

/** Create framebuffer with tetxure
 *
 *  @param [in] depth   Prepare framebuffer with depth buffer.
 *  @param [in] stencil   Prepare framebuffer with stencil buffer.
 *
 *  @note If both depth and stencil, the joined dept_stencil buffer will be created.
 */
void GetAttachmentParametersTest::CreateTextureFramebuffer(bool depth, bool stencil)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");

	gl.genTextures(2, m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindTexture(GL_TEXTURE_2D, m_to[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to[0], 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	if (depth && (!stencil))
	{
		gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT24, 1, 2);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_to[1], 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
	}

	if ((!depth) && stencil)
	{
		gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_STENCIL_INDEX8, 1, 2);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_to[1], 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
	}

	if (depth && stencil)
	{
		gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");

		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 1, 2);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_to[1], 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
	}

	/* Check that framebuffer is complete. */
	if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unexpectedly framebuffer was incomplete."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}
}

/** Test default framebuffer.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool GetAttachmentParametersTest::TestDefaultFramebuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	static const glw::GLenum attachments[] = { GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK_LEFT,
											   GL_BACK_RIGHT, GL_DEPTH,		  GL_STENCIL };

	static const glw::GLchar* attachments_strings[] = { "GL_FRONT_LEFT", "GL_FRONT_RIGHT", "GL_BACK_LEFT",
														"GL_BACK_RIGHT", "GL_DEPTH",	   "GL_STENCIL" };

	static const glw::GLuint attachments_count = sizeof(attachments) / sizeof(attachments[0]);

	for (glw::GLuint j = 0; j < attachments_count; ++j)
	{
		glw::GLint parameter_legacy = 0;
		glw::GLint parameter_dsa	= 0;

		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
											   &parameter_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");

		gl.getNamedFramebufferAttachmentParameteriv(0, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
													&parameter_dsa);

		/* Error check. */
		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
				<< glu::getErrorStr(error)
				<< " error when called with GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter name for "
				<< attachments_strings[j] << " attachment of default framebuffer." << tcu::TestLog::EndMessage;

			is_ok = false;

			continue;
		}

		if (parameter_legacy != parameter_dsa)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned " << parameter_dsa
				<< ", but " << parameter_legacy
				<< " was expected for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter name of default framebuffer."
				<< tcu::TestLog::EndMessage;

			is_ok = false;

			continue;
		}

		if (parameter_dsa != GL_NONE)
		{
			static const glw::GLenum optional_pnames[] = {
				GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,		  GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
				GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,	  GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
				GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,	 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
				GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
			};

			static const glw::GLchar* optional_pnames_strings[] = {
				"GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",		"GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
				"GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",		"GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
				"GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",		"GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
				"GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE", "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING"
			};

			static const glw::GLuint optional_pnames_count = sizeof(optional_pnames) / sizeof(optional_pnames[0]);

			for (glw::GLuint i = 0; i < optional_pnames_count; ++i)
			{
				glw::GLint optional_parameter_legacy = 0;
				glw::GLint optional_parameter_dsa	= 0;

				gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], optional_pnames[i],
													   &optional_parameter_legacy);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");

				gl.getNamedFramebufferAttachmentParameteriv(0, attachments[j], optional_pnames[i],
															&optional_parameter_dsa);

				if (glw::GLenum error = gl.getError())
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
						<< glu::getErrorStr(error) << " error when called with " << optional_pnames_strings[i]
						<< " parameter name for " << attachments_strings[j]
						<< " attachment of default framebuffer. The GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE was "
						<< parameter_legacy << "." << tcu::TestLog::EndMessage;

					is_ok = false;

					continue;
				}

				if (optional_parameter_legacy != optional_parameter_dsa)
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned "
						<< optional_parameter_dsa << ", but " << optional_parameter_legacy << " was expected for "
						<< optional_pnames_strings << " parameter name  for " << attachments_strings[j]
						<< " attachment of default framebuffer." << tcu::TestLog::EndMessage;

					is_ok = false;

					continue;
				}
			}
		}
	}

	return is_ok;
}

/** Test framebuffer object (with renderbuffer).
 *
 *  @param [in] depth_stencil       Has framebuffer depth_stencil attachment.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool GetAttachmentParametersTest::TestRenderbufferFramebuffer(bool depth_stencil)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	static const glw::GLenum attachments[] = { GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL_ATTACHMENT,
											   GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };

	static const glw::GLchar* attachments_strings[] = { "GL_DEPTH_ATTACHMENT", "GL_STENCIL_ATTACHMENT",
														"GL_DEPTH_STENCIL_ATTACHMENT", "GL_COLOR_ATTACHMENT0",
														"GL_COLOR_ATTACHMENT1" };

	static const glw::GLuint attachments_count = sizeof(attachments) / sizeof(attachments[0]);

	for (glw::GLuint j = 0; j < attachments_count; ++j)
	{
		glw::GLint parameter_legacy = 0;
		glw::GLint parameter_dsa	= 0;

		/* Omit DEPTH_STENCIL_ATTACHMENT attachment if the renderbuffer is not depth-stencil. */
		if (attachments[j] == GL_DEPTH_STENCIL_ATTACHMENT)
		{
			if (!depth_stencil)
			{
				continue;
			}
		}

		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
											   &parameter_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");

		gl.getNamedFramebufferAttachmentParameteriv(m_fbo, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
													&parameter_dsa);

		/* Error check. */
		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
				<< glu::getErrorStr(error)
				<< " error when called with GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter name for "
				<< attachments_strings[j] << " attachment of renderbuffer framebuffer object."
				<< tcu::TestLog::EndMessage;

			is_ok = false;

			continue;
		}

		if (parameter_legacy != parameter_dsa)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned " << parameter_dsa
				<< ", but " << parameter_legacy << " was expected for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter "
												   "name of renderbuffer framebuffer object."
				<< tcu::TestLog::EndMessage;

			is_ok = false;

			continue;
		}

		if (parameter_dsa != GL_NONE)
		{
			static const glw::GLenum optional_pnames[] = {
				GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,   GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
				GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,	GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
				GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,	GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
				GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,  GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
				GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
			};

			static const glw::GLchar* optional_pnames_strings[] = {
				"GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",   "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",
				"GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",	"GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
				"GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",	"GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
				"GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",  "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",
				"GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING"
			};

			static const glw::GLuint optional_pnames_count = sizeof(optional_pnames) / sizeof(optional_pnames[0]);

			for (glw::GLuint i = 0; i < optional_pnames_count; ++i)
			{
				/* Omit FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE pname when DEPTH_STENCIL_ATTACHMENT attachment is used. */
				if (attachments[j] == GL_DEPTH_STENCIL_ATTACHMENT)
				{
					if (optional_pnames[i] == GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE)
					{
						continue;
					}
				}

				glw::GLint optional_parameter_legacy = 0;
				glw::GLint optional_parameter_dsa	= 0;

				gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], optional_pnames[i],
													   &optional_parameter_legacy);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");

				gl.getNamedFramebufferAttachmentParameteriv(m_fbo, attachments[j], optional_pnames[i],
															&optional_parameter_dsa);

				if (glw::GLenum error = gl.getError())
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
						<< glu::getErrorStr(error) << " error when called with " << optional_pnames_strings[i]
						<< " parameter name for " << attachments_strings[j]
						<< " attachment of renderbuffer framebuffer object. The GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE "
						   "was "
						<< parameter_legacy << "." << tcu::TestLog::EndMessage;

					is_ok = false;

					continue;
				}

				if (optional_parameter_legacy != optional_parameter_dsa)
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned "
						<< optional_parameter_dsa << ", but " << optional_parameter_legacy << " was expected for "
						<< optional_pnames_strings << " parameter name  for " << attachments_strings[j]
						<< " attachment of renderbuffer framebuffer object." << tcu::TestLog::EndMessage;

					is_ok = false;

					continue;
				}
			}
		}
	}

	return is_ok;
}

/** Test framebuffer object (with texture).
 *
 *  @param [in] depth_stencil       Has framebuffer depth_stencil attachment.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool GetAttachmentParametersTest::TestTextureFramebuffer(bool depth_stencil)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	static const glw::GLenum attachments[] = { GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL_ATTACHMENT,
											   GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };

	static const glw::GLchar* attachments_strings[] = { "GL_DEPTH_ATTACHMENT", "GL_STENCIL_ATTACHMENT",
														"GL_DEPTH_STENCIL_ATTACHMENT", "GL_COLOR_ATTACHMENT0",
														"GL_COLOR_ATTACHMENT1" };

	static const glw::GLuint attachments_count = sizeof(attachments) / sizeof(attachments[0]);

	for (glw::GLuint j = 0; j < attachments_count; ++j)
	{
		/* Omit DEPTH_STENCIL_ATTACHMENT attachment if the renderbuffer is not depth-stencil. */
		if (attachments[j] == GL_DEPTH_STENCIL_ATTACHMENT)
		{
			if (!depth_stencil)
			{
				continue;
			}
		}

		glw::GLint parameter_legacy = 0;
		glw::GLint parameter_dsa	= 0;

		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
											   &parameter_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");

		gl.getNamedFramebufferAttachmentParameteriv(m_fbo, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
													&parameter_dsa);

		/* Error check. */
		if (glw::GLenum error = gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
				<< glu::getErrorStr(error)
				<< " error when called with GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter name for "
				<< attachments_strings[j] << " attachment of texture framebuffer object." << tcu::TestLog::EndMessage;

			is_ok = false;

			continue;
		}

		if (parameter_legacy != parameter_dsa)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned " << parameter_dsa
				<< ", but " << parameter_legacy << " was expected for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter "
												   "name of texture framebuffer object."
				<< tcu::TestLog::EndMessage;

			is_ok = false;

			continue;
		}

		if (parameter_dsa != GL_NONE)
		{
			static const glw::GLenum optional_pnames[] = { GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
														   GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
														   GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
														   GL_FRAMEBUFFER_ATTACHMENT_LAYERED,
														   GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER,
														   GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
														   GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
														   GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
														   GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
														   GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
														   GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
														   GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
														   GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING };

			static const glw::GLchar* optional_pnames_strings[] = { "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
																	"GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
																	"GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
																	"GL_FRAMEBUFFER_ATTACHMENT_LAYERED",
																	"GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",
																	"GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",
																	"GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
																	"GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
																	"GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
																	"GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
																	"GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
																	"GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",
																	"GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING" };

			static const glw::GLuint optional_pnames_count = sizeof(optional_pnames) / sizeof(optional_pnames[0]);

			for (glw::GLuint i = 0; i < optional_pnames_count; ++i)
			{
				/* Omit FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE pname when DEPTH_STENCIL_ATTACHMENT attachment is used. */
				if (attachments[j] == GL_DEPTH_STENCIL_ATTACHMENT)
				{
					if (optional_pnames[i] == GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE)
					{
						continue;
					}
				}

				glw::GLint optional_parameter_legacy = 0;
				glw::GLint optional_parameter_dsa	= 0;

				gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], optional_pnames[i],
													   &optional_parameter_legacy);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");

				gl.getNamedFramebufferAttachmentParameteriv(m_fbo, attachments[j], optional_pnames[i],
															&optional_parameter_dsa);

				if (glw::GLenum error = gl.getError())
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
						<< glu::getErrorStr(error) << " error when called with " << optional_pnames_strings[i]
						<< " parameter name for " << attachments_strings[j]
						<< " attachment of texture framebuffer object. The GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE was "
						<< parameter_legacy << "." << tcu::TestLog::EndMessage;

					is_ok = false;

					continue;
				}

				if (optional_parameter_legacy != optional_parameter_dsa)
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned "
						<< optional_parameter_dsa << ", but " << optional_parameter_legacy << " was expected for "
						<< optional_pnames_strings << " parameter name  for " << attachments_strings[j]
						<< " attachment of texture framebuffer object." << tcu::TestLog::EndMessage;

					is_ok = false;

					continue;
				}
			}
		}
	}

	return is_ok;
}

/** @brief Clean up GL state.
 */
void GetAttachmentParametersTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Releasing obnjects. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	/* Releasing renderbuffers. */
	for (glw::GLuint i = 0; i < 2; ++i)
	{
		if (m_rbo[i])
		{
			gl.deleteRenderbuffers(1, &m_rbo[i]);

			m_rbo[i] = 0;
		}
	}

	/* Releasing textures. */
	for (glw::GLuint i = 0; i < 2; ++i)
	{
		if (m_to[i])
		{
			gl.deleteTextures(1, &m_to[i]);

			m_to[i] = 0;
		}
	}

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Framebuffer Creation Errors Test Implementation   ********************************/

/** @brief Creation Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationErrorsTest::CreationErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_creation_errors", "Framebuffer Objects Creation Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok = true;

	/* Framebuffer object */
	glw::GLuint framebuffer = 0;

	/* Check direct state creation of negative numbers of framebuffers. */
	gl.createFramebuffers(-1, &framebuffer);

	glw::GLenum error = GL_NO_ERROR;

	if (GL_INVALID_VALUE != (error = gl.getError()))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "CreateFramebuffers generated " << glu::getErrorStr(error)
			<< " error when called with negative number of framebuffers, but GL_INVALID_VALUE was expected."
			<< tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Cleanup (sanity). */
	if (framebuffer)
	{
		gl.deleteFramebuffers(1, &framebuffer);
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/******************************** Renderbuffer Attachment Errors Test Implementation   ********************************/

/** @brief Renderbuffer Attachment Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
RenderbufferAttachmentErrorsTest::RenderbufferAttachmentErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_renderbuffer_attachment_errors", "Renderbuffer Attachment Errors Test")
	, m_fbo_valid(0)
	, m_rbo_valid(0)
	, m_fbo_invalid(0)
	, m_rbo_invalid(0)
	, m_color_attachment_invalid(0)
	, m_attachment_invalid(0)
	, m_renderbuffer_target_invalid(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Renderbuffer Attachment Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult RenderbufferAttachmentErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		/* Invalid Framebuffer ID. */
		gl.namedFramebufferRenderbuffer(m_fbo_invalid, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_valid);

		is_ok &= ExpectError(GL_INVALID_OPERATION, false, true, false, true, true);

		/* Invalid color attachment. */
		gl.namedFramebufferRenderbuffer(m_fbo_valid, m_color_attachment_invalid, GL_RENDERBUFFER, m_rbo_valid);

		is_ok &= ExpectError(GL_INVALID_OPERATION, true, false, true, true, true);

		/* Invalid attachment. */
		gl.namedFramebufferRenderbuffer(m_fbo_valid, m_attachment_invalid, GL_RENDERBUFFER, m_rbo_valid);

		is_ok &= ExpectError(GL_INVALID_ENUM, true, false, false, true, true);

		/* Invalid Renderbuffer Target. */
		gl.namedFramebufferRenderbuffer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_renderbuffer_target_invalid, m_rbo_valid);

		is_ok &= ExpectError(GL_INVALID_ENUM, true, true, false, false, true);

		/* Invalid Renderbuffer ID. */
		gl.namedFramebufferRenderbuffer(m_fbo_valid, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_invalid);

		is_ok &= ExpectError(GL_INVALID_OPERATION, true, true, false, true, false);
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Prepare test objects.
 */
void RenderbufferAttachmentErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genFramebuffers(1, &m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genRenderbuffers(1, &m_rbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Invalid objects. */
	while (gl.isFramebuffer(++m_fbo_invalid))
		;
	while (gl.isRenderbuffer(++m_rbo_invalid))
		;

	/* Max color attachments query. */
	glw::GLint max_color_attachments = 8; /* Spec default. */
	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	/* Invalid color attachment */
	m_color_attachment_invalid = GL_COLOR_ATTACHMENT0 + max_color_attachments;

	/* Invalid attachment. */
	bool is_attachment = true;

	while (is_attachment)
	{
		++m_attachment_invalid;

		is_attachment = false;

		if ((GL_DEPTH_ATTACHMENT == m_attachment_invalid) || (GL_STENCIL_ATTACHMENT == m_attachment_invalid) ||
			(GL_DEPTH_STENCIL_ATTACHMENT == m_attachment_invalid))
		{
			is_attachment = true;
		}

		if (GL_COLOR_ATTACHMENT0 < m_attachment_invalid)
		{
			/* If this unlikely happen this mean that we cannot create invalid attachment which is not DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT and
			 GL_COLOR_ATTACHMENTm where m IS any positive integer number (for m < MAX_COLOR_ATTACHMENTS attachments are valid, and for m >= MAX_COLOR_ATTACHMENTS is invalid, but
			 INVALID_OPERATION shall be generated instead of INVALID_ENUM. Such a situation may need change in the test or in the specification. */
			throw 0;
		}
	}

	/* Invalid renderbuffer target. */
	m_renderbuffer_target_invalid = GL_RENDERBUFFER + 1;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] framebuffer         Framebuffer name to be logged.
 *  @param [in] attachment          Attachment name to be logged.
 *  @param [in] renderbuffertarget  Renderbuffertarget name to be logged.
 *  @param [in] renderbuffer        Renderbuffer name to be logged.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool RenderbufferAttachmentErrorsTest::ExpectError(glw::GLenum expected_error, bool framebuffer, bool attachment,
												   bool color_attachment, bool renderbuffertarget, bool renderbuffer)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "NamedFramebufferRenderbuffer called with "
			<< (framebuffer ? "valid" : "invalid") << " framebuffer, " << (attachment ? "valid" : "invalid")
			<< (color_attachment ? " color" : "") << " attachment, " << (renderbuffertarget ? "valid" : "invalid")
			<< " renderbuffer target, " << (renderbuffer ? "valid" : "invalid")
			<< " renderbuffer was expected to generate " << glu::getErrorStr(expected_error) << ", but "
			<< glu::getErrorStr(error) << " was observed instead." << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void RenderbufferAttachmentErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_fbo_valid)
	{
		gl.deleteFramebuffers(1, &m_fbo_valid);
		m_fbo_valid = 0;
	}

	if (m_rbo_valid)
	{
		gl.deleteRenderbuffers(1, &m_rbo_valid);
		m_rbo_valid = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_fbo_invalid				  = 0;
	m_rbo_invalid				  = 0;
	m_attachment_invalid		  = 0;
	m_color_attachment_invalid	= 0;
	m_renderbuffer_target_invalid = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Texture Attachment Errors Test Implementation   ********************************/

/** @brief Texture Attachment Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
TextureAttachmentErrorsTest::TextureAttachmentErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_texture_attachment_errors", "Texture Attachment Errors Test")
	, m_fbo_valid(0)
	, m_to_valid(0)
	, m_to_3d_valid(0)
	, m_to_array_valid(0)
	, m_to_cubearray_valid(0)
	, m_tbo_valid(0)
	, m_fbo_invalid(0)
	, m_to_invalid(0)
	, m_to_layer_invalid(0)
	, m_color_attachment_invalid(0)
	, m_attachment_invalid(0)
	, m_level_invalid(0)
	, m_max_3d_texture_size(2048)		 /* OpenGL 4.5 Core Profile default values (Table 23.53). */
	, m_max_3d_texture_depth(2048)		 /* == m_max_3d_texture_size or value of GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV. */
	, m_max_array_texture_layers(2048)   /* OpenGL 4.5 Core Profile default values (Table 23.53). */
	, m_max_cube_map_texture_size(16384) /* OpenGL 4.5 Core Profile default values (Table 23.53). */
{
	/* Intentionally left blank. */
}

/** @brief Iterate Texture Attachment Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult TextureAttachmentErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		/********** NamedFramebufferTexture **************/

		/* Invalid Framebuffer ID. */
		gl.namedFramebufferTexture(m_fbo_invalid, GL_COLOR_ATTACHMENT0, m_to_valid, 0);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTexture", false, true, false, true, true, "", true);

		/* Invalid Color Attachment. */
		gl.namedFramebufferTexture(m_fbo_valid, m_color_attachment_invalid, m_to_valid, 0);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTexture", true, false, true, true, true, "", true);

		/* Invalid Attachment. */
		gl.namedFramebufferTexture(m_fbo_valid, m_attachment_invalid, m_to_valid, 0);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferTexture", true, false, false, true, true, "", true);

		/* Invalid Texture ID. */
		gl.namedFramebufferTexture(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_invalid, 0);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTexture", true, true, false, false, true, "", true);

		/* Invalid Level. */
		gl.namedFramebufferTexture(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_valid, m_level_invalid);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTexture", true, true, false, true, false, "", true);

		/* Buffer texture. */
		gl.namedFramebufferTexture(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_tbo_valid, 0);

		is_ok &=
			ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTexture", true, true, false, true, true, "buffer", true);

		/********** NamedFramebufferTextureLayer **************/

		/* Invalid Framebuffer ID. */
		gl.namedFramebufferTextureLayer(m_fbo_invalid, GL_COLOR_ATTACHMENT0, m_to_array_valid, 0, 0);

		is_ok &=
			ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", false, true, false, true, true, "", true);

		/* Invalid Color Attachment. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, m_color_attachment_invalid, m_to_array_valid, 0, 0);

		is_ok &=
			ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", true, false, true, true, true, "", true);

		/* Invalid Attachment. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, m_attachment_invalid, m_to_array_valid, 0, 0);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferTextureLayer", true, false, false, true, true, "", true);

		/* Invalid Texture ID. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_invalid, 0, 0);

		is_ok &=
			ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", true, true, false, false, true, "", true);

		/* Invalid Level. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_array_valid, m_level_invalid, 0);

		is_ok &=
			ExpectError(GL_INVALID_VALUE, "NamedFramebufferTextureLayer", true, true, false, true, false, "", true);

		/* Buffer texture. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_tbo_valid, 0, 0);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", true, true, false, true, true,
							 "buffer", true);

		/* Check that INVALID_VALUE error is generated by NamedFramebufferTextureLayer if texture is a three-dimensional
		 texture, and layer is larger than the value of MAX_3D_TEXTURE_SIZE or GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV (if available) minus one. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_3d_valid, 0, m_max_3d_texture_depth);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTextureLayer", true, true, false, true, true,
							 "3D texture", false);

		/* Check that INVALID_VALUE error is generated by NamedFramebufferTextureLayer if texture is an array texture,
		 and layer is larger than the value of MAX_ARRAY_TEXTURE_LAYERS minus one. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_array_valid, 0,
										m_max_array_texture_layers);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTextureLayer", true, true, false, true, true, "array",
							 false);

		/* Check that INVALID_VALUE error is generated by NamedFramebufferTextureLayer if texture is a cube map array texture,
		 and (layer / 6) is larger than the value of MAX_CUBE_MAP_TEXTURE_SIZE minus one (see section 9.8).
		 Check that INVALID_VALUE error is generated by NamedFramebufferTextureLayer if texture is non-zero
		 and layer is negative. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_cubearray_valid, 0,
										m_max_cube_map_texture_size);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTextureLayer", true, true, false, true, true,
							 "cuba map array", false);

		/* Check that INVALID_OPERATION error is generated by NamedFramebufferTextureLayer if texture is non-zero
		 and is not the name of a three-dimensional, two-dimensional multisample array, one- or two-dimensional array,
		 or cube map array texture. */
		gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_layer_invalid, 0, 0);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", true, true, false, false, true,
							 "rectangle", true);
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Prepare test GL objects.
 */
void TextureAttachmentErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genFramebuffers(1, &m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genTextures(1, &m_to_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(GL_TEXTURE_2D, m_to_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.genTextures(1, &m_tbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(GL_TEXTURE_BUFFER, m_tbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genTextures(1, &m_to_3d_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(GL_TEXTURE_3D, m_to_3d_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genTextures(1, &m_to_array_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_array_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genTextures(1, &m_to_cubearray_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_to_cubearray_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genTextures(1, &m_to_layer_invalid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(GL_TEXTURE_RECTANGLE, m_to_layer_invalid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Invalid objects. */
	while (gl.isFramebuffer(++m_fbo_invalid))
		;
	while (gl.isTexture(++m_to_invalid))
		;

	/* Max color attachments query. */
	glw::GLint max_color_attachments = 8; /* Spec default. */
	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	/* Invalid color attachment */
	m_color_attachment_invalid = GL_COLOR_ATTACHMENT0 + max_color_attachments;

	/* Invalid attachment. */
	bool is_attachment = true;

	while (is_attachment)
	{
		++m_attachment_invalid;

		is_attachment = false;

		if ((GL_DEPTH_ATTACHMENT == m_attachment_invalid) || (GL_STENCIL_ATTACHMENT == m_attachment_invalid) ||
			(GL_DEPTH_STENCIL_ATTACHMENT == m_attachment_invalid))
		{
			is_attachment = true;
		}

		for (glw::GLint i = 0; i < max_color_attachments; ++i)
		{
			if (GL_COLOR_ATTACHMENT0 == m_attachment_invalid)
			{
				is_attachment = true;
			}
		}
	}

	/* Maximum values */
	gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &m_max_3d_texture_size);
	gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &m_max_array_texture_layers);
	gl.getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &m_max_cube_map_texture_size);

	if (m_context.getContextInfo().isExtensionSupported("GL_NV_deep_texture3D"))
	{
		gl.getIntegerv(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV, &m_max_3d_texture_depth);
	}
	else
	{
		m_max_3d_texture_depth = m_max_3d_texture_size;
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	/* Invalid level. */
	m_level_invalid = -1;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] framebuffer         Framebuffer name to be logged.
 *  @param [in] attachment          Attachment name to be logged.
 *  @param [in] texture             Texture name to be logged.
 *  @param [in] level               Level # to be logged.
 *  @param [in] buffer_texture      Is this buffer texture (special logging case).
 *
 *  @return True if test succeeded, false otherwise.
 */
bool TextureAttachmentErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function_name,
											  bool framebuffer, bool attachment, bool color_attachment, bool texture,
											  bool level, const glw::GLchar* texture_type, bool layer)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << function_name << " called with " << (framebuffer ? "valid" : "invalid")
			<< " framebuffer, " << (attachment ? "valid" : "invalid") << (color_attachment ? " color" : "")
			<< " attachment, " << (texture ? "valid " : "invalid ") << texture_type << " texture, "
			<< (level ? "valid" : "invalid") << " level" << (layer ? "" : ", with invalid layer number")
			<< " was expected to generate " << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
			<< " was observed instead." << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void TextureAttachmentErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_fbo_valid)
	{
		gl.deleteFramebuffers(1, &m_fbo_valid);
		m_fbo_valid = 0;
	}

	if (m_to_valid)
	{
		gl.deleteTextures(1, &m_to_valid);
		m_to_valid = 0;
	}

	if (m_tbo_valid)
	{
		gl.deleteTextures(1, &m_tbo_valid);
		m_tbo_valid = 0;
	}

	if (m_to_3d_valid)
	{
		gl.deleteTextures(1, &m_to_3d_valid);
		m_to_3d_valid = 0;
	}

	if (m_to_array_valid)
	{
		gl.deleteTextures(1, &m_to_array_valid);
		m_to_array_valid = 0;
	}

	if (m_to_cubearray_valid)
	{
		gl.deleteTextures(1, &m_to_cubearray_valid);
		m_to_cubearray_valid = 0;
	}

	if (m_to_layer_invalid)
	{
		gl.deleteTextures(1, &m_to_layer_invalid);
		m_to_layer_invalid = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_fbo_invalid		 = 0;
	m_to_invalid		 = 0;
	m_attachment_invalid = 0;
	m_level_invalid		 = 0;

	m_max_3d_texture_size		= 2048;
	m_max_3d_texture_depth		= m_max_3d_texture_size;
	m_max_array_texture_layers  = 2048;
	m_max_cube_map_texture_size = 16384;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Draw Read Buffers Errors Test Implementation   ********************************/

/** @brief Draw Read Buffers Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
DrawReadBuffersErrorsTest::DrawReadBuffersErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_draw_read_buffers_errors", "Draw Read Buffers Errors Test Test")
	, m_fbo_valid(0)
	, m_fbo_invalid(0)
	, m_attachment_color(GL_COLOR_ATTACHMENT0)
	, m_attachment_back_left(GL_BACK_LEFT)
	, m_attachment_right(GL_RIGHT)
	, m_attachment_left(GL_LEFT)
	, m_attachment_front(GL_FRONT)
	, m_attachment_front_and_back(GL_FRONT_AND_BACK)
	, m_attachment_back(GL_BACK)
	, m_attachment_invalid(0)
	, m_max_color_attachments(8) /* GL 4.5 default, updated later */
{
	m_attachments_invalid[0] = 0;
	m_attachments_invalid[1] = 0;

	m_attachments_back_invalid[0] = GL_BACK_LEFT;
	m_attachments_back_invalid[1] = GL_BACK;

	m_attachments_too_many_count = 0;

	m_attachments_too_many = DE_NULL;
}

/** @brief Iterate Draw Read Buffers Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult DrawReadBuffersErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		/*  Check that INVALID_OPERATION error is generated by
		 NamedFramebufferDrawBuffer if framebuffer is not zero or the name of an
		 existing framebuffer object. */
		gl.namedFramebufferDrawBuffer(m_fbo_invalid, m_attachment_color);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffer",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		/*  Check that INVALID_ENUM is generated by NamedFramebufferDrawBuffer if
		 buf is not an accepted value. */
		gl.namedFramebufferDrawBuffer(m_fbo_valid, m_attachment_invalid);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffer", "buf is not an accepted value.");

		/*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffer
		 if the GL is bound to a draw framebuffer object and the ith argument is
		 a value other than COLOR_ATTACHMENTi or NONE. */
		gl.namedFramebufferDrawBuffer(m_fbo_valid, m_attachment_back_left);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffer",
							 "the GL is bound to a draw framebuffer object and the ith argument is a value other than "
							 "COLOR_ATTACHMENTi or NONE.");

		/*  Check that INVALID_OPERATION error is generated by
		 NamedFramebufferDrawBuffers if framebuffer is not zero or the name of an
		 existing framebuffer object. */
		gl.namedFramebufferDrawBuffers(m_fbo_invalid, 1, &m_attachment_color);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		/*  Check that INVALID_VALUE is generated by NamedFramebufferDrawBuffers if n
		 is less than 0. */
		gl.namedFramebufferDrawBuffers(m_fbo_valid, -1, &m_attachment_color);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferDrawBuffers", "n is less than 0.");

		/*  Check that INVALID_VALUE is generated by NamedFramebufferDrawBuffers if
		 n is greater than MAX_DRAW_BUFFERS. */
		gl.namedFramebufferDrawBuffers(m_fbo_valid, m_attachments_too_many_count, m_attachments_too_many);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferDrawBuffers", "n is greater than MAX_DRAW_BUFFERS.");

		/*  Check that INVALID_ENUM is generated by NamedFramebufferDrawBuffers if
		 one of the values in bufs is not an accepted value. */
		gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_invalid);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "one of the values in bufs is not an accepted value.");

		/*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffers
		 if a symbolic constant other than GL_NONE appears more than once in
		 bufs. */
		gl.namedFramebufferDrawBuffers(m_fbo_valid, 2, m_attachments_invalid);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
							 "a symbolic constant other than GL_NONE appears more than once in bufs.");

		/*  Check that INVALID_ENUM error is generated by NamedFramebufferDrawBuffers if any value in bufs is FRONT, LEFT, RIGHT, or FRONT_AND_BACK.
		 This restriction applies to both the default framebuffer and framebuffer objects, and exists because these constants may themselves
		 refer to multiple buffers, as shown in table 17.4. */
		gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_front);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "a framebuffer object is tested and a value in bufs is FRONT.");

		gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_left);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "a framebuffer object is tested and a value in bufs is LEFT.");

		gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_right);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "a framebuffer object is tested and a value in bufs is RIGHT.");

		gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_front_and_back);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "a framebuffer object is tested and a value in bufs is FRONT_AND_BACK.");

		gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_front);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "a default framebuffer is tested and a value in bufs is FRONT.");

		gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_left);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "a default framebuffer is tested and a value in bufs is LEFT.");

		gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_right);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "a default framebuffer is tested and a value in bufs is RIGHT.");

		gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_front_and_back);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
							 "a default framebuffer is tested and a value in bufs is FRONT_AND_BACK.");

		/*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffers
		 if any value in bufs is BACK, and n is not one. */
		gl.namedFramebufferDrawBuffers(0, 2, m_attachments_back_invalid);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
							 "any value in bufs is BACK, and n is not one.");

		/*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffers if
		 the API call refers to a framebuffer object and one or more of the
		 values in bufs is anything other than NONE or one of the
		 COLOR_ATTACHMENTn tokens. */
		gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_back_left);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
							 "the API call refers to a framebuffer object and one or more of the values in bufs is "
							 "anything other than NONE or one of the COLOR_ATTACHMENTn tokens.");

		/*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffers if
		 the API call refers to the default framebuffer and one or more of the
		 values in bufs is one of the COLOR_ATTACHMENTn tokens. */
		gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_color);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
							 "the API call refers to the default framebuffer and one or more of the values in bufs is "
							 "one of the COLOR_ATTACHMENTn tokens.");

		/*  Check that INVALID_OPERATION is generated by NamedFramebufferReadBuffer
		 if framebuffer is not zero or the name of an existing framebuffer
		 object. */
		gl.namedFramebufferReadBuffer(m_fbo_invalid, m_attachment_color);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferReadBuffer",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		/*  Check that INVALID_ENUM is generated by NamedFramebufferReadBuffer if
		 src is not one of the accepted values (tables 17.4 and 17.5 of OpenGL 4.5 Core Profile Specification). */
		gl.namedFramebufferReadBuffer(m_fbo_valid, m_attachment_invalid);

		is_ok &= ExpectError(
			GL_INVALID_ENUM, "NamedFramebufferReadBuffer",
			"src is not one of the accepted values (tables 17.4 and 17.5 of OpenGL 4.5 Core Profile Specification).");

		/* Check that INVALID_OPERATION error is generated by NamedFramebufferReadBuffer if the default framebuffer is
		 affected and src is a value (other than NONE) that does not indicate any of the
		 color buffers allocated to the default framebuffer. */
		gl.namedFramebufferReadBuffer(0, GL_COLOR_ATTACHMENT0);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferReadBuffer",
							 "the default framebuffer is affected and src is a value (other than NONE) that does not "
							 "indicate any of the color buffers allocated to the default framebuffer.");

		/* Check that INVALID_OPERATION error is generated by NamedFramebufferReadBuffer if a framebuffer object is
		 affected, and src is one of the  constants from table 17.4 (other than NONE, or COLOR_ATTACHMENTm where m
		 is greater than or equal to the value of MAX_COLOR_ATTACHMENTS). */
		gl.namedFramebufferReadBuffer(m_fbo_valid, m_attachment_front_and_back);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferReadBuffer",
							 "a framebuffer object is affected, and src is one of the  constants from table 17.4.");

		gl.namedFramebufferReadBuffer(m_fbo_valid, GL_COLOR_ATTACHMENT0 + m_max_color_attachments);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferReadBuffer",
							 "a framebuffer object is affected, and src is one of the COLOR_ATTACHMENTm where mis "
							 "greater than or equal to the value of MAX_COLOR_ATTACHMENTS.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void DrawReadBuffersErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genFramebuffers(1, &m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Invalid objects. */
	while (gl.isFramebuffer(++m_fbo_invalid))
		;

	/* Invalid attachment. */
	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &m_max_color_attachments);

	bool is_attachment = true;

	while (is_attachment)
	{
		++m_attachment_invalid;

		is_attachment = false;

		/* Valid attachments are those from tables 17.4, 17.5 and a 17.6 (valid for various functions and framebuffer types).
		 (see OpenGL 4.5 Core Profile Specification) */
		switch (m_attachment_invalid)
		{
		case GL_NONE:
		case GL_FRONT_LEFT:
		case GL_FRONT_RIGHT:
		case GL_BACK_LEFT:
		case GL_BACK_RIGHT:
		case GL_FRONT:
		case GL_BACK:
		case GL_LEFT:
		case GL_RIGHT:
		case GL_FRONT_AND_BACK:
			is_attachment = true;
		}

		for (glw::GLint i = 0; i < m_max_color_attachments; ++i)
		{
			if ((glw::GLenum)(GL_COLOR_ATTACHMENT0 + i) == m_attachment_invalid)
			{
				is_attachment = true;
				break;
			}
		}
	}

	m_attachments_invalid[0] = GL_COLOR_ATTACHMENT0;
	m_attachments_invalid[1] = GL_COLOR_ATTACHMENT0;

	glw::GLint max_draw_buffers = 8; /* Spec default. */
	gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);

	m_attachments_too_many_count = max_draw_buffers + 1;

	m_attachments_too_many = new glw::GLenum[m_attachments_too_many_count];

	m_attachments_too_many[0] = GL_COLOR_ATTACHMENT0;

	for (glw::GLint i = 1; i < m_attachments_too_many_count; ++i)
	{
		m_attachments_too_many[i] = GL_NONE;
	}
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool DrawReadBuffersErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
											const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void DrawReadBuffersErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_fbo_valid)
	{
		gl.deleteFramebuffers(1, &m_fbo_valid);
		m_fbo_valid = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_fbo_invalid			 = 0;
	m_attachment_invalid	 = 0;
	m_attachments_invalid[0] = 0;
	m_attachments_invalid[1] = 0;

	delete[] m_attachments_too_many;

	m_attachments_too_many = DE_NULL;

	m_attachments_too_many_count = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Invalidate Data and SubData Errors Test Implementation   ********************************/

/** @brief Invalidate SubData Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
InvalidateDataAndSubDataErrorsTest::InvalidateDataAndSubDataErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "invalidate_data_and_subdata_errors", "Invalidate Data and SubData Errors Test")
	, m_fbo_valid(0)
	, m_rbo(0)
	, m_fbo_invalid(0)
	, m_fbo_attachment_valid(0)
	, m_fbo_attachment_invalid(0)
	, m_color_attachment_invalid(0)
	, m_default_attachment_invalid(0)

{
}

/** @brief Iterate Invalidate Data and SubData Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult InvalidateDataAndSubDataErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		/******* InvalidateNamedFramebufferData *******/

		/*  Check that INVALID_OPERATION error is generated by InvalidateNamedFramebufferData if framebuffer is not zero or the name of an existing framebuffer object. */
		gl.invalidateNamedFramebufferData(m_fbo_invalid, 1, &m_fbo_attachment_valid);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "InvalidateNamedFramebufferData",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		/*  Check that INVALID_ENUM error is generated by InvalidateNamedFramebufferData if a framebuffer object is affected, and
		 any element of of attachments is not one of the values in table {COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT }. */
		gl.invalidateNamedFramebufferData(m_fbo_valid, 1, &m_fbo_attachment_invalid);

		is_ok &= ExpectError(GL_INVALID_ENUM, "InvalidateNamedFramebufferData",
							 "a framebuffer object is affected, and any element of of attachments is not one of the "
							 "values in table { COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, "
							 "DEPTH_STENCIL_ATTACHMENT }.");

		/*  Check that INVALID_OPERATION error is generated by InvalidateNamedFramebufferData if attachments contains COLOR_ATTACHMENTm
		 where m is greater than or equal to the value of MAX_COLOR_ATTACHMENTS. */
		gl.invalidateNamedFramebufferData(m_fbo_valid, 1, &m_color_attachment_invalid);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "InvalidateNamedFramebufferData",
							 "attachments contains COLOR_ATTACHMENTm where m is greater than or equal to the value of "
							 "MAX_COLOR_ATTACHMENTS");

		/*  Check that INVALID_ENUM error is generated by
		 InvalidateNamedFramebufferData if the default framebuffer is affected,
		 and any elements of attachments are not one of:
		 -  FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, and BACK_RIGHT, identifying that
		 specific buffer,
		 -  COLOR, which is treated as BACK_LEFT for a double-buffered context
		 and FRONT_LEFT for a single-buffered context,
		 -  DEPTH, identifying the depth buffer,
		 -  STENCIL, identifying the stencil buffer. */
		gl.invalidateNamedFramebufferData(0, 1, &m_default_attachment_invalid);

		is_ok &= ExpectError(GL_INVALID_ENUM, "InvalidateNamedFramebufferData",
							 "the default framebuffer is affected, and any elements of attachments are not one of "
							 "FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, COLOR, DEPTH, STENCIL.");

		/******* InvalidateNamedFramebufferSubData *******/

		/*  Check that INVALID_OPERATION error is generated by InvalidateNamedFramebufferSubData if framebuffer is not zero or the name of an existing framebuffer object. */
		gl.invalidateNamedFramebufferSubData(m_fbo_invalid, 1, &m_fbo_attachment_valid, 0, 0, 1, 1);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "InvalidateNamedFramebufferSubData",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		/*  Check that INVALID_VALUE error is generated by InvalidateNamedFramebufferSubData if numAttachments, width, or height is negative. */
		gl.invalidateNamedFramebufferSubData(m_fbo_valid, -1, &m_fbo_attachment_valid, 0, 0, 1, 1);

		is_ok &= ExpectError(GL_INVALID_VALUE, "InvalidateNamedFramebufferSubData", "numAttachments is negative.");

		gl.invalidateNamedFramebufferSubData(m_fbo_valid, 1, &m_fbo_attachment_valid, 0, 0, -1, 1);

		is_ok &= ExpectError(GL_INVALID_VALUE, "InvalidateNamedFramebufferSubData", "width is negative.");

		gl.invalidateNamedFramebufferSubData(m_fbo_valid, 1, &m_fbo_attachment_valid, 0, 0, 1, -1);

		is_ok &= ExpectError(GL_INVALID_VALUE, "InvalidateNamedFramebufferSubData", "height is negative.");

		/*  Check that INVALID_ENUM error is generated by InvalidateNamedFramebufferSubData if a framebuffer object is affected, and
		 any element of of attachments is not one of the values in table {COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT }. */
		gl.invalidateNamedFramebufferSubData(m_fbo_valid, 1, &m_fbo_attachment_invalid, 0, 0, 1, 1);

		is_ok &= ExpectError(GL_INVALID_ENUM, "InvalidateNamedFramebufferSubData",
							 "a framebuffer object is affected, and any element of of attachments is not one of the "
							 "values in table { COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, "
							 "DEPTH_STENCIL_ATTACHMENT }.");

		/*  Check that INVALID_OPERATION error is generated by InvalidateNamedFramebufferSubData if attachments contains COLOR_ATTACHMENTm
		 where m is greater than or equal to the value of MAX_COLOR_ATTACHMENTS. */
		gl.invalidateNamedFramebufferSubData(m_fbo_valid, 1, &m_color_attachment_invalid, 0, 0, 1, 1);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "InvalidateNamedFramebufferSubData",
							 "attachments contains COLOR_ATTACHMENTm where m is greater than or equal to the value of "
							 "MAX_COLOR_ATTACHMENTS");

		/*  Check that INVALID_ENUM error is generated by InvalidateNamedFramebufferSubData if the default framebuffer is affected,
		 and any elements of attachments are not one of:
		 -  FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, and BACK_RIGHT, identifying that
		 specific buffer,
		 -  COLOR, which is treated as BACK_LEFT for a double-buffered context
		 and FRONT_LEFT for a single-buffered context,
		 -  DEPTH, identifying the depth buffer,
		 -  STENCIL, identifying the stencil buffer. */
		gl.invalidateNamedFramebufferSubData(0, 1, &m_default_attachment_invalid, 0, 0, 1, 1);

		is_ok &= ExpectError(GL_INVALID_ENUM, "InvalidateNamedFramebufferSubData",
							 "the default framebuffer is affected, and any elements of attachments are not one of "
							 "FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, COLOR, DEPTH, STENCIL.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void InvalidateDataAndSubDataErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid attachments. */
	m_fbo_attachment_valid = GL_COLOR_ATTACHMENT0;

	/* Valid objects. */
	gl.genFramebuffers(1, &m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genRenderbuffers(1, &m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, m_fbo_attachment_valid, GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
	{
		throw 0;
	}

	/* Invalid objects. */
	while (gl.isFramebuffer(++m_fbo_invalid))
		;

	/* Invalid framebuffer object attachment. */
	while (true)
	{
		if (GL_COLOR_ATTACHMENT0 < m_fbo_attachment_invalid)
		{
			/* If this unlikely happen this mean that we cannot create invalid attachment which is not DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT and
			 GL_COLOR_ATTACHMENTm where m IS any number (for m < MAX_COLOR_ATTACHMENTS attachments are valid, and for m >= MAX_COLOR_ATTACHMENTS is invalid, but
			 INVALID_OPERATION shall be generated instead of INVALID_ENUM. Such a situation may need change in the test or in the specification. */
			throw 0;
		}

		switch (++m_fbo_attachment_invalid)
		{
		case GL_DEPTH_ATTACHMENT:
		case GL_STENCIL_ATTACHMENT:
		case GL_DEPTH_STENCIL_ATTACHMENT:
			continue;
		}

		break;
	}

	/* Invalid color attachment. */
	glw::GLint max_color_attachments = 8; /* Spec default. */

	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	m_color_attachment_invalid = GL_COLOR_ATTACHMENT0 + max_color_attachments;

	/* Invalid default attachment. */
	while (true)
	{
		switch (++m_default_attachment_invalid)
		{
		case GL_FRONT_LEFT:
		case GL_FRONT_RIGHT:
		case GL_BACK_LEFT:
		case GL_BACK_RIGHT:
		case GL_COLOR:
		case GL_DEPTH:
		case GL_STENCIL:
			continue;
		}

		break;
	}
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool InvalidateDataAndSubDataErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
													 const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void InvalidateDataAndSubDataErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_fbo_valid)
	{
		gl.deleteFramebuffers(1, &m_fbo_valid);
		m_fbo_valid = 0;
	}

	if (m_rbo)
	{
		gl.deleteRenderbuffers(1, &m_rbo);

		m_rbo = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_fbo_invalid				 = 0;
	m_fbo_attachment_valid		 = 0;
	m_fbo_attachment_invalid	 = 0;
	m_default_attachment_invalid = 0;
	m_color_attachment_invalid   = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Clear Named Framebuffer Errors Test Implementation   ********************************/

/** @brief Clear Named Framebuffer Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ClearNamedFramebufferErrorsTest::ClearNamedFramebufferErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_clear_errors", "Clear Named Framebuffer Errors Test")
	, m_fbo_valid(0)
	, m_rbo_color(0)
	, m_rbo_depth_stencil(0)
	, m_fbo_invalid(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Clear Named Framebuffer Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ClearNamedFramebufferErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		glw::GLint   icolor[4] = {};
		glw::GLuint  ucolor[4] = {};
		glw::GLfloat fcolor[4] = {};

		/*  Check that INVALID_OPERATION is generated by ClearNamedFramebuffer* if
		 framebuffer is not zero or the name of an existing framebuffer object. */
		gl.clearNamedFramebufferiv(m_fbo_invalid, GL_COLOR, 0, icolor);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "ClearNamedFramebufferiv",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		gl.clearNamedFramebufferuiv(m_fbo_invalid, GL_COLOR, 0, ucolor);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "ClearNamedFramebufferuiv",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		gl.clearNamedFramebufferfv(m_fbo_invalid, GL_COLOR, 0, fcolor);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "ClearNamedFramebufferfv",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		gl.clearNamedFramebufferfi(m_fbo_invalid, GL_DEPTH_STENCIL, 0, fcolor[0], icolor[0]);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "ClearNamedFramebufferfi",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		/*  Check that INVALID_ENUM is generated by ClearNamedFramebufferiv if buffer
		 is not COLOR or STENCIL. */
		gl.clearNamedFramebufferiv(m_fbo_valid, GL_DEPTH, 0, icolor);

		is_ok &=
			ExpectError(GL_INVALID_ENUM, "ClearNamedFramebufferiv", "buffer is not COLOR or STENCIL (it is DEPTH).");

		/*  Check that INVALID_ENUM is generated by ClearNamedFramebufferuiv if buffer
		 is not COLOR. */
		gl.clearNamedFramebufferuiv(m_fbo_valid, GL_DEPTH, 0, ucolor);

		is_ok &= ExpectError(GL_INVALID_ENUM, "ClearNamedFramebufferuiv", "buffer is not COLOR (it is DEPTH).");

		/*  Check that INVALID_ENUM is generated by ClearNamedFramebufferfv buffer
		 is not COLOR or DEPTH. */
		gl.clearNamedFramebufferfv(m_fbo_valid, GL_STENCIL, 0, fcolor);

		is_ok &=
			ExpectError(GL_INVALID_ENUM, "ClearNamedFramebufferfv", "buffer is not COLOR or DEPTH (it is STENCIL).");

		/*  Check that INVALID_ENUM is generated by ClearNamedFramebufferfi if buffer
		 is not DEPTH_STENCIL. */
		gl.clearNamedFramebufferfi(m_fbo_valid, GL_COLOR, 0, fcolor[0], icolor[0]);

		is_ok &= ExpectError(GL_INVALID_ENUM, "ClearNamedFramebufferfi", "buffer is not DEPTH_STENCIL.");

		/*  Check that INVALID_VALUE is generated by ClearNamedFramebuffer* if buffer is COLOR drawbuffer is
		 negative, or greater than the value of MAX_DRAW_BUFFERS minus one. */
		gl.clearNamedFramebufferiv(m_fbo_valid, GL_COLOR, -1, icolor);

		is_ok &= ExpectError(
			GL_INVALID_VALUE, "ClearNamedFramebufferiv",
			"buffer is COLOR drawbuffer is negative, or greater than the value of MAX_DRAW_BUFFERS minus one.");

		gl.clearNamedFramebufferuiv(m_fbo_valid, GL_COLOR, -1, ucolor);

		is_ok &= ExpectError(
			GL_INVALID_VALUE, "ClearNamedFramebufferuiv",
			"buffer is COLOR drawbuffer is negative, or greater than the value of MAX_DRAW_BUFFERS minus one.");

		/*  Check that INVALID_VALUE is generated by ClearNamedFramebuffer* if buffer is DEPTH, STENCIL or
		 DEPTH_STENCIL and drawbuffer is not zero. */

		gl.clearNamedFramebufferiv(m_fbo_valid, GL_STENCIL, 1, icolor);

		is_ok &= ExpectError(GL_INVALID_VALUE, "ClearNamedFramebufferiv",
							 "buffer is DEPTH, STENCIL or DEPTH_STENCIL and drawbuffer is not zero.");

		gl.clearNamedFramebufferfv(m_fbo_valid, GL_DEPTH, 1, fcolor);

		is_ok &= ExpectError(GL_INVALID_VALUE, "ClearNamedFramebufferfv",
							 "buffer is DEPTH, STENCIL or DEPTH_STENCIL and drawbuffer is not zero.");

		gl.clearNamedFramebufferfi(m_fbo_valid, GL_DEPTH_STENCIL, 1, fcolor[0], icolor[0]);

		is_ok &= ExpectError(GL_INVALID_VALUE, "ClearNamedFramebufferfi",
							 "buffer is DEPTH, STENCIL or DEPTH_STENCIL and drawbuffer is not zero.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void ClearNamedFramebufferErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genFramebuffers(1, &m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genRenderbuffers(1, &m_rbo_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, 1, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	gl.genRenderbuffers(1, &m_rbo_depth_stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_depth_stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	/* Invalid objects. */
	while (gl.isFramebuffer(++m_fbo_invalid))
		;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool ClearNamedFramebufferErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
												  const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void ClearNamedFramebufferErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_fbo_valid)
	{
		gl.deleteFramebuffers(1, &m_fbo_valid);
		m_fbo_valid = 0;
	}

	if (m_rbo_color)
	{
		gl.deleteRenderbuffers(1, &m_rbo_color);
		m_rbo_color = 0;
	}

	if (m_rbo_depth_stencil)
	{
		gl.deleteRenderbuffers(1, &m_rbo_depth_stencil);
		m_rbo_depth_stencil = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_fbo_invalid = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Check Status Errors Test Implementation   ********************************/

/** @brief Clear Named Framebuffer Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CheckStatusErrorsTest::CheckStatusErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_check_status_errors", "Check Status Errors Test")
	, m_fbo_valid(0)
	, m_fbo_invalid(0)
	, m_target_invalid(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Clear Named Framebuffer Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CheckStatusErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		/*  Check that INVALID_ENUM is generated by CheckNamedFramebufferStatus if
		 target is not DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER. */
		gl.checkNamedFramebufferStatus(m_fbo_valid, m_target_invalid);

		is_ok &= ExpectError(GL_INVALID_ENUM, "CheckNamedFramebufferStatus",
							 "target is not DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER.");

		/*  Check that INVALID_OPERATION is generated by CheckNamedFramebufferStatus
		 if framebuffer is not zero or the name of an existing framebuffer
		 object. */
		gl.checkNamedFramebufferStatus(m_fbo_invalid, GL_FRAMEBUFFER);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "CheckNamedFramebufferStatus",
							 "framebuffer is not zero or the name of an existing framebuffer object.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void CheckStatusErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genFramebuffers(1, &m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Invalid target. */
	bool is_target = true;

	while (is_target)
	{
		is_target = false;

		++m_target_invalid;

		if (GL_FRAMEBUFFER == m_target_invalid)
		{
			is_target = true;
		}

		if (GL_READ_FRAMEBUFFER == m_target_invalid)
		{
			is_target = true;
		}

		if (GL_DRAW_FRAMEBUFFER == m_target_invalid)
		{
			is_target = true;
		}
	}
	/* Invalid objects. */
	while (gl.isFramebuffer(++m_fbo_invalid))
		;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool CheckStatusErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
										const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void CheckStatusErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_fbo_valid)
	{
		gl.deleteFramebuffers(1, &m_fbo_valid);
		m_fbo_valid = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_fbo_invalid	= 0;
	m_target_invalid = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Get Parameter Errors Test Implementation   ********************************/

/** @brief Get Parameter Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetParameterErrorsTest::GetParameterErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_get_parameter_errors", "Get Parameter Errors Test")
	, m_fbo_valid(0)
	, m_fbo_invalid(0)
	, m_parameter_invalid(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Get Parameter Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetParameterErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		glw::GLint return_values_dummy_storage[4];

		/*  Check that INVALID_OPERATION is generated by
		 GetNamedFramebufferParameteriv if framebuffer is not zero or the name of
		 an existing framebuffer object. */
		gl.getNamedFramebufferParameteriv(m_fbo_invalid, GL_SAMPLES, return_values_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferParameteriv",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		/*  Check that INVALID_ENUM is generated by GetNamedFramebufferParameteriv
		 if pname is not one of the accepted parameter names. */
		gl.getNamedFramebufferParameteriv(m_fbo_valid, m_parameter_invalid, return_values_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_ENUM, "GetNamedFramebufferParameteriv",
							 "pname is not one of the accepted parameter names.");

		/*  Check that INVALID_OPERATION is generated if a default framebuffer is
		 queried, and pname is not one of DOUBLEBUFFER,
		 IMPLEMENTATION_COLOR_READ_FORMAT, IMPLEMENTATION_COLOR_READ_TYPE,
		 SAMPLES, SAMPLE_BUFFERS or STEREO. */
		gl.getNamedFramebufferParameteriv(0, GL_FRAMEBUFFER_DEFAULT_WIDTH, return_values_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferParameteriv",
							 "a default framebuffer is queried, and pname is not one of DOUBLEBUFFER, "
							 "IMPLEMENTATION_COLOR_READ_FORMAT, IMPLEMENTATION_COLOR_READ_TYPE, SAMPLES, "
							 "SAMPLE_BUFFERS or STEREO.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void GetParameterErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genFramebuffers(1, &m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Invalid target. */
	bool is_parameter = true;

	while (is_parameter)
	{
		is_parameter = false;

		++m_parameter_invalid;

		static const glw::GLenum valid_parameters[] = { GL_FRAMEBUFFER_DEFAULT_WIDTH,
														GL_FRAMEBUFFER_DEFAULT_HEIGHT,
														GL_FRAMEBUFFER_DEFAULT_LAYERS,
														GL_FRAMEBUFFER_DEFAULT_SAMPLES,
														GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS,
														GL_DOUBLEBUFFER,
														GL_IMPLEMENTATION_COLOR_READ_FORMAT,
														GL_IMPLEMENTATION_COLOR_READ_TYPE,
														GL_SAMPLES,
														GL_SAMPLE_BUFFERS,
														GL_STEREO };

		static const glw::GLuint valid_parameters_count = sizeof(valid_parameters) / sizeof(valid_parameters[0]);

		for (glw::GLuint i = 0; i < valid_parameters_count; ++i)
		{
			if (valid_parameters[i] == m_parameter_invalid)
			{
				is_parameter = true;
			}
		}
	}

	/* Invalid objects. */
	while (gl.isFramebuffer(++m_fbo_invalid))
		;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool GetParameterErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
										 const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void GetParameterErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_fbo_valid)
	{
		gl.deleteFramebuffers(1, &m_fbo_valid);
		m_fbo_valid = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_fbo_invalid		= 0;
	m_parameter_invalid = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Get Attachment Parameter Errors Test Implementation   ********************************/

/** @brief Get Attachment Parameter Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetAttachmentParameterErrorsTest::GetAttachmentParameterErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_get_attachment_parameter_errors", "Get Attachment Parameter Errors Test")
	, m_fbo_valid(0)
	, m_rbo_color(0)
	, m_rbo_depth_stencil(0)
	, m_fbo_invalid(0)
	, m_parameter_invalid(0)
	, m_attachment_invalid(0)
	, m_default_attachment_invalid(0)
	, m_max_color_attachments(8) /* Spec default. */
{
	/* Intentionally left blank. */
}

/** @brief Iterate Get Attachment Parameter Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetAttachmentParameterErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		glw::GLint return_values_dummy_storage[4];

		/*  Check that GL_INVALID_OPERATION is generated by
		 GetNamedFramebufferAttachmentParameteriv if framebuffer is not zero or
		 the name of an existing framebuffer object. */
		gl.getNamedFramebufferAttachmentParameteriv(
			m_fbo_invalid, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, return_values_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
							 "framebuffer is not zero or the name of an existing framebuffer object.");

		/*  Check that INVALID_ENUM is generated by
		 GetNamedFramebufferAttachmentParameteriv if pname is not valid for the
		 value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, as described above. */
		gl.getNamedFramebufferAttachmentParameteriv(
			m_fbo_valid, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, return_values_dummy_storage);

		is_ok &= ExpectError(
			GL_INVALID_ENUM, "GetNamedFramebufferAttachmentParameteriv",
			"pname is not valid for the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, as described above.");

		/*  Check that INVALID_ENUM error is generated if a framebuffer object is queried, attachment
		 is not one of the attachments in table 9.2 (COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT), and attachment is not
		 COLOR_ATTACHMENTm where m is greater than or equal to the value of MAX_COLOR_ATTACHMENTS. */
		gl.getNamedFramebufferAttachmentParameteriv(
			m_fbo_valid, m_attachment_invalid, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, return_values_dummy_storage);

		is_ok &= ExpectError(
			GL_INVALID_ENUM, "GetNamedFramebufferAttachmentParameteriv",
			"attachment is not one of the accepted framebuffer attachment points, as described in specification.");

		/*  Check that INVALID_OPERATION is generated by
		 GetNamedFramebufferAttachmentParameteriv if the value of
		 FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE and pname is not
		 FRAMEBUFFER_ATTACHMENT_OBJECT_NAME or
		 FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE. */
		gl.getNamedFramebufferAttachmentParameteriv(
			m_fbo_valid, GL_COLOR_ATTACHMENT1, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, return_values_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
							 "the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE and pname is not "
							 "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME or FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE.");

		/*  Check that INVALID_OPERATION is generated by
		 GetNamedFramebufferAttachmentParameteriv if attachment is
		 DEPTH_STENCIL_ATTACHMENT and pname is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE. */
		gl.getNamedFramebufferAttachmentParameteriv(m_fbo_valid, GL_DEPTH_STENCIL_ATTACHMENT,
													GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
													return_values_dummy_storage);

		is_ok &=
			ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
						"attachment is DEPTH_STENCIL_ATTACHMENT and pname is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE.");

		/*  Check that an INVALID_ENUM error is generated if the default framebuffer is
		 queried and attachment is not one the values FRONT, FRONT_LEFT, FRONT_RIGHT,
		 BACK, BACK_LEFT, BACK_RIGHT, DEPTH, STENCIL. */
		gl.getNamedFramebufferAttachmentParameteriv(
			0, m_default_attachment_invalid, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, return_values_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_ENUM, "GetNamedFramebufferAttachmentParameteriv",
							 "the default framebuffer is queried and attachment is not one the values FRONT, "
							 "FRONT_LEFT, FRONT_RIGHT, BACK, BACK_LEFT, BACK_RIGHT, DEPTH, STENCIL.");

		/*  Check that an INVALID_OPERATION error is generated if a framebuffer object is
		 bound to target and attachment is COLOR_ATTACHMENTm where m is greater than or
		 equal to the value of MAX_COLOR_ATTACHMENTS. */
		gl.getNamedFramebufferAttachmentParameteriv(m_fbo_valid, GL_COLOR_ATTACHMENT0 + m_max_color_attachments,
													GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
													return_values_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
							 "a framebuffer object is bound to target and attachment is COLOR_ATTACHMENTm where m is "
							 "equal to the value of MAX_COLOR_ATTACHMENTS.");

		gl.getNamedFramebufferAttachmentParameteriv(m_fbo_valid, GL_COLOR_ATTACHMENT0 + m_max_color_attachments + 1,
													GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
													return_values_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
							 "a framebuffer object is bound to target and attachment is COLOR_ATTACHMENTm where m is "
							 "greater than the value of MAX_COLOR_ATTACHMENTS.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void GetAttachmentParameterErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genFramebuffers(1, &m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.genRenderbuffers(1, &m_rbo_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, 1, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	gl.genRenderbuffers(1, &m_rbo_depth_stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_depth_stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");

	/* Max color attachments. */
	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &m_max_color_attachments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	/* Invalid attachment. */
	bool is_attachment = true;

	while (is_attachment)
	{
		is_attachment = false;

		if ((GL_DEPTH_ATTACHMENT == m_attachment_invalid) || (GL_STENCIL_ATTACHMENT == m_attachment_invalid) ||
			(GL_DEPTH_STENCIL_ATTACHMENT == m_attachment_invalid))
		{
			++m_attachment_invalid;
			is_attachment = true;
		}

		if (GL_COLOR_ATTACHMENT0 < m_attachment_invalid)
		{
			/* If this unlikely happen this mean that we cannot create invalid attachment which is not DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT and
			 GL_COLOR_ATTACHMENTm where m IS any number (for m < MAX_COLOR_ATTACHMENTS attachments are valid, and for m >= MAX_COLOR_ATTACHMENTS is invalid, but
			 INVALID_OPERATION shall be generated instead of INVALID_ENUM. Such a situation may need change in the test or in the specification. */
			throw 0;
		}
	}

	/* Invalid default framebuffer attachment. */
	bool is_default_attachment = true;

	while (is_default_attachment)
	{
		is_default_attachment = false;

		static const glw::GLenum valid_values[] = { GL_FRONT,	 GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK,
													GL_BACK_LEFT, GL_BACK_RIGHT, GL_DEPTH,		 GL_STENCIL };

		static const glw::GLuint valid_values_count = sizeof(valid_values) / sizeof(valid_values[0]);

		for (glw::GLuint i = 0; i < valid_values_count; ++i)
		{
			if (valid_values[i] == m_default_attachment_invalid)
			{
				m_default_attachment_invalid++;
				is_default_attachment = true;
				break;
			}
		}
	}

	/* Invalid parameter. */
	bool is_parameter = true;

	while (is_parameter)
	{
		is_parameter = false;

		++m_parameter_invalid;

		static const glw::GLenum valid_parameters[] = { GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
														GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
														GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
														GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
														GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
														GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
														GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
														GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING,
														GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
														GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
														GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
														GL_FRAMEBUFFER_ATTACHMENT_LAYERED,
														GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER };

		static const glw::GLuint valid_parameters_count = sizeof(valid_parameters) / sizeof(valid_parameters[0]);

		for (glw::GLuint i = 0; i < valid_parameters_count; ++i)
		{
			if (valid_parameters[i] == m_parameter_invalid)
			{
				is_parameter = true;
			}
		}
	}

	/* Invalid objects. */
	while (gl.isFramebuffer(++m_fbo_invalid))
		;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool GetAttachmentParameterErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
												   const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void GetAttachmentParameterErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_fbo_valid)
	{
		gl.deleteFramebuffers(1, &m_fbo_valid);
		m_fbo_valid = 0;
	}

	if (m_rbo_color)
	{
		gl.deleteRenderbuffers(1, &m_rbo_color);
		m_rbo_color = 0;
	}

	if (m_rbo_depth_stencil)
	{
		gl.deleteRenderbuffers(1, &m_rbo_depth_stencil);
		m_rbo_depth_stencil = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_fbo_invalid				 = 0;
	m_parameter_invalid			 = 0;
	m_attachment_invalid		 = 0;
	m_default_attachment_invalid = 0;
	m_max_color_attachments		 = 8;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Functional Test Implementation   ********************************/

/** @brief Get Attachment Parameter Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
FunctionalTest::FunctionalTest(deqp::Context& context)
	: deqp::TestCase(context, "framebuffers_renderbuffers_functional", "Functional Test")
	, m_fbo_1st(0)
	, m_fbo_2nd(0)
	, m_rbo_color(0)
	, m_rbo_depth_stencil(0)
	, m_to_color(0)
	, m_po(0)
	, m_vao_stencil_pass_quad(0)
	, m_vao_depth_pass_quad(0)
	, m_vao_color_pass_quad(0)
	, m_bo_stencil_pass_quad(0)
	, m_bo_depth_pass_quad(0)
	, m_bo_color_pass_quad(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Get Attachment Parameter Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult FunctionalTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Test. */
		is_ok &= PrepareFirstFramebuffer();
		is_ok &= PrepareSecondFramebuffer();
		is_ok &= ClearFramebuffers();
		PrepareProgram();
		PrepareBuffersAndVertexArrays();
		is_ok &= DrawAndBlit();
		is_ok &= CheckSecondFramebufferContent();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Prepare first framebuffer.
 *
 *  @return True if there is no error, false otherwise.
 */
bool FunctionalTest::PrepareFirstFramebuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Failure of this part shall result in test failure (it is DSA functionality failure). */
	try
	{
		gl.createFramebuffers(1, &m_fbo_1st);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");

		gl.createRenderbuffers(1, &m_rbo_color);
		gl.createRenderbuffers(1, &m_rbo_depth_stencil);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateRenderbuffers has failed");

		gl.namedRenderbufferStorage(m_rbo_color, GL_R8, 8, 8);
		gl.namedRenderbufferStorage(m_rbo_depth_stencil, GL_DEPTH24_STENCIL8, 8, 8);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedRenderbufferStorage has failed");

		gl.namedFramebufferRenderbuffer(m_fbo_1st, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color);
		gl.namedFramebufferRenderbuffer(m_fbo_1st, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedFramebufferRenderbuffer has failed");

		if (GL_FRAMEBUFFER_COMPLETE != gl.checkNamedFramebufferStatus(m_fbo_1st, GL_FRAMEBUFFER))
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "CheckNamedFramebufferStatus is incomplete."
												<< tcu::TestLog::EndMessage;

			throw 0;
		}
	}
	catch (...)
	{
		return false;
	}

	return true;
}

/** Prepare second framebuffer.
 *
 *  @return True if there is no error, false otherwise.
 */
bool FunctionalTest::PrepareSecondFramebuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Failure of this part shall result in test internal error (it does not test the DSA functionality). */
	gl.genTextures(1, &m_to_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(GL_TEXTURE_2D, m_to_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8, 4, 3);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D has failed");

	/* Failure of this part shall result in test failure (it is DSA functionality failure). */
	try
	{
		gl.createFramebuffers(1, &m_fbo_2nd);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");

		gl.namedFramebufferTexture(m_fbo_2nd, GL_COLOR_ATTACHMENT0, m_to_color, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedFramebufferTexture has failed");

		if (GL_FRAMEBUFFER_COMPLETE != gl.checkNamedFramebufferStatus(m_fbo_2nd, GL_FRAMEBUFFER))
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "CheckNamedFramebufferStatus is incomplete."
												<< tcu::TestLog::EndMessage;

			throw 0;
		}
	}
	catch (...)
	{
		return false;
	}

	return true;
}

/** Clear framebuffers.
 *
 *  @return True if there is no error, false otherwise.
 */
bool FunctionalTest::ClearFramebuffers()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Failure of this part shall result in test failure (it is DSA functionality failure). */
	try
	{
		glw::GLfloat color_value[] = { 0.f, 0.f, 0.f, 0.f };
		glw::GLfloat depth_value   = 0.f;
		glw::GLint   stencil_value = 0;

		/* 1st framebuffer. */
		gl.clearNamedFramebufferfv(m_fbo_1st, GL_COLOR, 0, color_value);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedFramebufferfv has failed");

		gl.clearNamedFramebufferfi(m_fbo_1st, GL_DEPTH_STENCIL, 0, depth_value, stencil_value);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedFramebufferfi has failed");

		/* 2nd framebuffer. */
		gl.clearNamedFramebufferfv(m_fbo_1st, GL_COLOR, 0, color_value);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedFramebufferfv has failed");
	}
	catch (...)
	{
		return false;
	}

	return true;
}

/** Prepare test's GLSL program.
 */
void FunctionalTest::PrepareProgram()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	struct Shader
	{
		glw::GLchar const* const source;
		glw::GLenum const		 type;
		glw::GLuint				 id;
	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };

	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);

	try
	{
		/* Create program. */
		m_po = gl.createProgram();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

		/* Shader compilation. */
		for (glw::GLuint i = 0; i < shader_count; ++i)
		{
			if (DE_NULL != shader[i].source)
			{
				shader[i].id = gl.createShader(shader[i].type);

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

				gl.attachShader(m_po, shader[i].id);

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

				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);

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

				gl.compileShader(shader[i].id);

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

				glw::GLint status = GL_FALSE;

				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

				if (GL_FALSE == status)
				{
					glw::GLint log_size = 0;
					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

					glw::GLchar* log_text = new glw::GLchar[log_size];

					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
														<< "\n"
														<< "Shader compilation error log:\n"
														<< log_text << "\n"
														<< "Shader source code:\n"
														<< shader[i].source << "\n"
														<< tcu::TestLog::EndMessage;

					delete[] log_text;

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

					throw 0;
				}
			}
		}

		/* Link. */
		gl.linkProgram(m_po);

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

		glw::GLint status = GL_FALSE;

		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

		if (GL_TRUE == status)
		{
			for (glw::GLuint i = 0; i < shader_count; ++i)
			{
				if (shader[i].id)
				{
					gl.detachShader(m_po, shader[i].id);

					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
				}
			}
		}
		else
		{
			glw::GLint log_size = 0;

			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

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

			glw::GLchar* log_text = new glw::GLchar[log_size];

			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
												<< log_text << "\n"
												<< tcu::TestLog::EndMessage;

			delete[] log_text;

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

			throw 0;
		}
	}
	catch (...)
	{
		if (m_po)
		{
			gl.deleteProgram(m_po);

			m_po = 0;
		}
	}

	for (glw::GLuint i = 0; i < shader_count; ++i)
	{
		if (0 != shader[i].id)
		{
			gl.deleteShader(shader[i].id);

			shader[i].id = 0;
		}
	}

	if (0 == m_po)
	{
		throw 0;
	}
}

/** Prepare Vertex Array Objects (one for each draw pass).
 */
void FunctionalTest::PrepareBuffersAndVertexArrays()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Query program attribute. */
	glw::GLuint program_attribute = gl.getAttribLocation(m_po, s_attribute);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");

	/* Create stencil pass buffer. */
	gl.genVertexArrays(1, &m_vao_stencil_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

	gl.bindVertexArray(m_vao_stencil_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

	gl.genBuffers(1, &m_bo_stencil_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_stencil_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers call failed.");

	gl.bufferData(GL_ARRAY_BUFFER, s_stencil_pass_quad_size, s_stencil_pass_quad, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.vertexAttribPointer(program_attribute, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

	gl.enableVertexAttribArray(program_attribute);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

	/* Create depth pass buffer. */
	gl.genVertexArrays(1, &m_vao_depth_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

	gl.bindVertexArray(m_vao_depth_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

	gl.genBuffers(1, &m_bo_depth_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_depth_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers call failed.");

	gl.bufferData(GL_ARRAY_BUFFER, s_depth_pass_quad_size, s_depth_pass_quad, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.vertexAttribPointer(program_attribute, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

	gl.enableVertexAttribArray(program_attribute);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

	/* Create color pass buffer. */
	gl.genVertexArrays(1, &m_vao_color_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

	gl.bindVertexArray(m_vao_color_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

	gl.genBuffers(1, &m_bo_color_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_color_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers call failed.");

	gl.bufferData(GL_ARRAY_BUFFER, s_color_pass_quad_size, s_color_pass_quad, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.vertexAttribPointer(program_attribute, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

	gl.enableVertexAttribArray(program_attribute);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
}

/** Do the test draww/blit calls.
 *
 *  @return True if there is no error in DSA functionality, false otherwise.
 */
bool FunctionalTest::DrawAndBlit()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_1st);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.viewport(0, 0, 8, 8);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

	/* Draw to stencil buffer. */
	gl.bindVertexArray(m_vao_stencil_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

	gl.stencilFunc(GL_NEVER, 0, 0xff);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc call failed.");

	gl.stencilOp(GL_INCR, GL_KEEP, GL_KEEP);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp call failed.");

	gl.stencilMask(0xff);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilMask call failed.");

	gl.colorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glColorMask call failed.");

	gl.depthMask(GL_FALSE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthMask call failed.");

	gl.enable(GL_STENCIL_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");

	gl.disable(GL_DEPTH_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

	/* Draw to depth buffer. */
	gl.bindVertexArray(m_vao_depth_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

	gl.stencilFunc(GL_ALWAYS, 0, 0xff);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc call failed.");

	gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp call failed.");

	gl.stencilMask(0xff);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilMask call failed.");

	gl.depthFunc(GL_ALWAYS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc call failed.");

	gl.disable(GL_STENCIL_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");

	gl.enable(GL_DEPTH_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");

	gl.depthMask(GL_TRUE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthMask call failed.");

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

	/* Draw to color buffer. */
	gl.bindVertexArray(m_vao_color_pass_quad);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

	gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glColorMask call failed.");

	gl.stencilFunc(GL_EQUAL, 1, 0xff);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc call failed.");

	gl.enable(GL_STENCIL_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");

	gl.enable(GL_DEPTH_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");

	gl.depthFunc(GL_GREATER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc call failed.");

	gl.depthMask(GL_FALSE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthMask call failed.");

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

	/* Blit framebuffer content. */
	gl.blitNamedFramebuffer(m_fbo_1st, m_fbo_2nd, 0, 0, 8, 8, 0, 0, 4, 3, GL_COLOR_BUFFER_BIT, GL_NEAREST);

	if (gl.getError())
	{
		return false;
	}

	return true;
}

/** Check resulting framebuffer content.
 *
 *  @return True if content matches the reference false otherwise.
 */
bool FunctionalTest::CheckSecondFramebufferContent()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_2nd);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	glw::GLubyte framebuffer_values[3][4] = {
		{ 0 } /* , ... */
	};

	static const glw::GLubyte reference_values[3][4] = { { 0, 0, 0, 0 }, { 0, 0, 255, 0 }, { 0, 0, 0, 0 } };

	gl.readPixels(0, 0, 4, 3, GL_RED, GL_UNSIGNED_BYTE, framebuffer_values);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

	for (glw::GLuint j = 0; j < 3; ++j)
	{
		for (glw::GLuint i = 0; i < 4; ++i)
		{
			if (reference_values[j][i] != framebuffer_values[j][i])
			{
				return false;
			}
		}
	}

	return true;
}

/** @brief Clean up GL state.
 */
void FunctionalTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Releas GL objects. */
	if (m_fbo_1st)
	{
		gl.deleteFramebuffers(1, &m_fbo_1st);

		m_fbo_1st = 0;
	}

	if (m_fbo_2nd)
	{
		gl.deleteFramebuffers(1, &m_fbo_2nd);

		m_fbo_2nd = 0;
	}

	if (m_rbo_color)
	{
		gl.deleteRenderbuffers(1, &m_rbo_color);

		m_rbo_color = 0;
	}

	if (m_rbo_depth_stencil)
	{
		gl.deleteRenderbuffers(1, &m_rbo_depth_stencil);

		m_rbo_depth_stencil = 0;
	}

	if (m_to_color)
	{
		gl.deleteTextures(1, &m_to_color);

		m_to_color = 0;
	}

	if (m_po)
	{
		gl.useProgram(0);

		gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_vao_stencil_pass_quad)
	{
		gl.deleteBuffers(1, &m_vao_stencil_pass_quad);

		m_vao_stencil_pass_quad = 0;
	}

	if (m_vao_depth_pass_quad)
	{
		gl.deleteBuffers(1, &m_vao_depth_pass_quad);

		m_vao_depth_pass_quad = 0;
	}

	if (m_vao_color_pass_quad)
	{
		gl.deleteBuffers(1, &m_vao_color_pass_quad);

		m_vao_color_pass_quad = 0;
	}

	if (m_bo_stencil_pass_quad)
	{
		gl.deleteBuffers(1, &m_bo_stencil_pass_quad);

		m_bo_stencil_pass_quad = 0;
	}

	if (m_bo_depth_pass_quad)
	{
		gl.deleteBuffers(1, &m_bo_depth_pass_quad);

		m_bo_depth_pass_quad = 0;
	}

	if (m_bo_color_pass_quad)
	{
		gl.deleteBuffers(1, &m_bo_color_pass_quad);

		m_bo_color_pass_quad = 0;
	}

	/* Reseting state. */
	gl.stencilFunc(GL_ALWAYS, 0, 0xff);
	gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	gl.stencilMask(0xff);
	gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	gl.depthFunc(GL_LESS);
	gl.depthMask(GL_TRUE);
	gl.disable(GL_STENCIL_TEST);
	gl.disable(GL_DEPTH_TEST);

	/* Clean errors. */
	while (gl.getError())
		;
}

/** Vertex shader source code. */
const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 330\n"
													  "\n"
													  "in vec3 position;\n"
													  "\n"
													  "void main()\n"
													  "{\n"
													  "    gl_Position = vec4(position, 1.0);\n"
													  "}\n";

/** Fragment shader source code. */
const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 330\n"
														"\n"
														"out vec4 color;\n"
														"\n"
														"void main()\n"
														"{\n"
														"    color = vec4(1.0);\n"
														"}\n";

/** Vertex shader source code attribute name. */
const glw::GLchar FunctionalTest::s_attribute[] = "position";

/** Stencil pass' geometry to be passed to vertex shader attribute. */
const glw::GLfloat FunctionalTest::s_stencil_pass_quad[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
															 0.5f,  -0.5f, 0.5f, 0.5f,  0.5f, 0.5f };

/** Depth pass' geometry to be passed to vertex shader attribute. */
const glw::GLfloat FunctionalTest::s_depth_pass_quad[] = { -1.0f, -1.0f, 1.0f,  -1.0f, 1.0f, 1.0f,
														   1.0f,  -1.0f, -1.0f, 1.0f,  1.0f, -1.0f };

/** Color pass' geometry to be passed to vertex shader attribute. */
const glw::GLfloat FunctionalTest::s_color_pass_quad[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f,
														   1.0f,  -1.0f, 0.0f, 1.0f,  1.0f, 0.0f };

const glw::GLuint FunctionalTest::s_stencil_pass_quad_size =
	sizeof(s_stencil_pass_quad); //!< Size of stencil pass' geometry.
const glw::GLuint FunctionalTest::s_depth_pass_quad_size =
	sizeof(s_depth_pass_quad); //!< Size of depth   pass' geometry.
const glw::GLuint FunctionalTest::s_color_pass_quad_size =
	sizeof(s_color_pass_quad); //!< Size of color   pass' geometry.

} // namespace Framebuffers

namespace Renderbuffers
{
/******************************** Renderbuffer Creation Test Implementation   ********************************/

/** @brief Creation Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationTest::CreationTest(deqp::Context& context)
	: deqp::TestCase(context, "renderbuffers_creation", "Renderbuffer Objects Creation Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Renderbuffers' objects */
	static const glw::GLuint renderbuffers_count = 2;

	glw::GLuint renderbuffers_legacy[renderbuffers_count] = {};
	glw::GLuint renderbuffers_dsa[renderbuffers_count]	= {};

	try
	{
		/* Check legacy state creation. */
		gl.genRenderbuffers(renderbuffers_count, renderbuffers_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

		for (glw::GLuint i = 0; i < renderbuffers_count; ++i)
		{
			if (gl.isRenderbuffer(renderbuffers_legacy[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "GenRenderbuffers has created default objects, but it should create only a names."
					<< tcu::TestLog::EndMessage;
			}
		}

		/* Check direct state creation. */
		gl.createRenderbuffers(renderbuffers_count, renderbuffers_dsa);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateRenderbuffers has failed");

		for (glw::GLuint i = 0; i < renderbuffers_count; ++i)
		{
			if (!gl.isRenderbuffer(renderbuffers_dsa[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog() << tcu::TestLog::Message
													<< "CreateRenderbuffers has not created default objects."
													<< tcu::TestLog::EndMessage;
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	for (glw::GLuint i = 0; i < renderbuffers_count; ++i)
	{
		if (renderbuffers_legacy[i])
		{
			gl.deleteRenderbuffers(1, &renderbuffers_legacy[i]);

			renderbuffers_legacy[i] = 0;
		}

		if (renderbuffers_dsa[i])
		{
			gl.deleteRenderbuffers(1, &renderbuffers_dsa[i]);

			renderbuffers_dsa[i] = 0;
		}
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Renderbuffer Storage Test Implementation   ********************************/

/** @brief Renderbuffer Storage Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
StorageTest::StorageTest(deqp::Context& context)
	: deqp::TestCase(context, "renderbuffers_storage", "Renderbuffer Objects Storage Test"), m_fbo(0), m_rbo(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult StorageTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		glw::GLint max_renderbuffer_size = 16384 /* Specification minimum. */;

		gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_renderbuffer_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

		const struct
		{
			glw::GLuint width;
			glw::GLuint height;
		} test_cases[] = { { 1, 1 },
						   { 256, 512 },
						   { 1280, 720 },
						   { (glw::GLuint)max_renderbuffer_size, 1 },
						   { 1, (glw::GLuint)max_renderbuffer_size } };

		const glw::GLuint test_cases_count = sizeof(test_cases) / sizeof(test_cases[0]);

		for (glw::GLuint i = 0; i < test_cases_count; ++i)
		{
			for (glw::GLuint j = 0; j < s_renderbuffer_internalformat_configuration_count; ++j)
			{
				if (PrepareRenderbuffer(s_renderbuffer_internalformat_configuration[j], test_cases[i].width,
										test_cases[i].height))
				{
					Clear(s_renderbuffer_internalformat_configuration[j].isColorIntegralFormat);
					is_ok &= Check(s_renderbuffer_internalformat_configuration[j], test_cases[i].width,
								   test_cases[i].height);
				}
				else
				{
					is_ok = false;
				}

				Clean();
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;

		Clean();
	}

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Prepare renderbuffer.
 *
 *  @param [in] format              Internal format to be prepared.
 *  @param [in] width               Width of the framebuffer.
 *  @param [in] height              Height of the framebuffer.
 *
 *  @return True if there is no error, false otherwise.
 */
bool StorageTest::PrepareRenderbuffer(StorageTest::RenderbufferInternalFormatConfiguration format, glw::GLuint width,
									  glw::GLuint height)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

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

	gl.createRenderbuffers(1, &m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateRenderbuffers call failed.");

	gl.namedRenderbufferStorage(m_rbo, format.internalformat, width, height);

	if (glw::GLenum error = gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Renderbuffer storage test failed because NamedRenderbufferStorage generated "
			<< glu::getErrorStr(error) << " error value. Renderbuffers format was "
			<< glu::getInternalFormatParameterStr(format.internalformat) << ", width was " << width << ", height was "
			<< height << "." << tcu::TestLog::EndMessage;
		return false;
	}

	if (format.hasRedComponent || format.hasGreenComponent || format.hasBlueComponent || format.hasAlphaComponent)
	{
		gl.namedFramebufferRenderbuffer(m_fbo, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
	}

	if (format.hasDepthComponent)
	{
		gl.namedFramebufferRenderbuffer(m_fbo, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbo);
	}

	if (format.hasStencilComponent)
	{
		gl.namedFramebufferRenderbuffer(m_fbo, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo);
	}

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		/* Log. */
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Renderbuffer storage test failed due to incomplete framebuffer status. Renderbuffers format was "
			<< glu::getInternalFormatParameterStr(format.internalformat) << ", width was " << width << ", height was "
			<< height << "." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** Clear renderbuffer.
 *
 *  @param [in] isColorIntegralFormat       Is this color integral format.
 */
void StorageTest::Clear(bool isColorIntegralFormat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	if (isColorIntegralFormat)
	{
		gl.clearBufferiv(GL_COLOR, 0, s_reference_color_integer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferiv has failed");
	}
	else
	{
		/* Setup clear values. */
		gl.clearColor(s_reference_color[0], s_reference_color[1], s_reference_color[2], s_reference_color[3]);
		gl.clearDepth(s_reference_depth);
		gl.clearStencil(s_reference_stencil);

		/* Clear rbo/fbo. */
		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	}
}

/** Check renderbuffer's content.
 *
 *  @param [in] format              Internal format to be prepared.
 *  @param [in] width               Width of the framebuffer.
 *  @param [in] height              Height of the framebuffer.
 *
 *  @return True if content matches the reference, false otherwise.
 */
bool StorageTest::Check(StorageTest::RenderbufferInternalFormatConfiguration format, glw::GLuint width,
						glw::GLuint height)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint size = width * height;

	if (format.hasRedComponent || format.hasGreenComponent || format.hasBlueComponent || format.hasAlphaComponent)
	{
		if (format.isColorIntegralFormat)
		{
			std::vector<glw::GLint> color(size * 4);

			gl.readPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_INT, &color[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

			const bool hasComponent[] = { format.hasRedComponent, format.hasGreenComponent, format.hasBlueComponent,
										  format.hasAlphaComponent };

			static const char* componentName[] = { "red", "green", "blue", "alpha" };

			for (glw::GLuint i = 0; i < size; ++i)
			{
				if (hasComponent[i % 4 /* color components count*/])
				{
					if (de::abs(s_reference_color_integer[i % 4 /* color components count*/] - color[i]) >
						2 /* Precision */)
					{
						m_context.getTestContext().getLog()
							<< tcu::TestLog::Message << "Renderbuffer storage was cleared with color "
							<< componentName[i % 4 /* color components count*/] << " component equal to "
							<< s_reference_color_integer << ", but fetched value " << color[i]
							<< " is not the same. Renderbuffers format was " << format.internalformat_name
							<< ", width was " << width << ", height was " << height << "." << tcu::TestLog::EndMessage;

						return false;
					}
				}
			}
		}
		else
		{
			std::vector<glw::GLfloat> color(size * 4);

			gl.readPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, &color[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

			const bool hasComponent[] = { format.hasRedComponent, format.hasGreenComponent, format.hasBlueComponent,
										  format.hasAlphaComponent };

			static const char* componentName[] = { "red", "green", "blue", "alpha" };

			for (glw::GLuint i = 0; i < size; ++i)
			{
				if (hasComponent[i % 4 /* color components count*/])
				{
					if (de::abs(s_reference_color[i % 4 /* color components count*/] - color[i]) >
						0.0625 /* precision */)
					{
						m_context.getTestContext().getLog()
							<< tcu::TestLog::Message << "Renderbuffer storage was cleared with color "
							<< componentName[i % 4 /* color components count*/] << " component equal to "
							<< s_reference_color[i % 4 /* color components count*/] << ", but fetched value "
							<< color[i] << " is not the same. Renderbuffers format was " << format.internalformat_name
							<< ", width was " << width << ", height was " << height << "." << tcu::TestLog::EndMessage;

						return false;
					}
				}
			}
		}
	}

	if (format.hasDepthComponent)
	{
		std::vector<glw::GLfloat> depth(size);

		gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, &depth[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

		for (glw::GLuint i = 0; i < size; ++i)
		{
			if (de::abs(s_reference_depth - depth[i]) > 0.0625 /* 1/16 precision */)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Renderbuffer storage was cleared with depth component equal to "
					<< s_reference_depth << ", but fetched value " << depth[i]
					<< " is not the same. Renderbuffers format was " << format.internalformat_name << ", width was "
					<< width << ", height was " << height << "." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	if (format.hasStencilComponent)
	{
		std::vector<glw::GLint> stencil(size);

		gl.readPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_INT, &stencil[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

		for (glw::GLuint i = 0; i < size; ++i)
		{
			if (s_reference_stencil != stencil[i])
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Renderbuffer storage was cleared with alpha component equal to "
					<< s_reference_stencil << ", but fetched value " << stencil[i]
					<< " is not the same. Renderbuffers format was " << format.internalformat_name << ", width was "
					<< width << ", height was " << height << "." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	return true;
}

/** @brief Clean up GL state.
 */
void StorageTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release objects. */
	if (m_rbo)
	{
		gl.deleteRenderbuffers(1, &m_rbo);

		m_rbo = 0;
	}

	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	/* Returning to default clear values. */
	gl.clearColor(0.f, 0.f, 0.f, 0.f);
	gl.clearDepth(1.f);
	gl.clearStencil(0);

	/* Errors clean up. */
	while (gl.getError())
		;
}

/** Internal formats to be tested*/
const struct StorageTest::RenderbufferInternalFormatConfiguration
	StorageTest::s_renderbuffer_internalformat_configuration[] = {
		{ GL_R8, "GL_R8", true, false, false, false, false, false, false },
		{ GL_R16, "GL_R16", true, false, false, false, false, false, false },
		{ GL_RG8, "GL_RG8", true, true, false, false, false, false, false },
		{ GL_RG16, "GL_RG16", true, true, false, false, false, false, false },
		{ GL_RGB565, "GL_RGB56", true, true, true, false, false, false, false },
		{ GL_RGBA4, "GL_RGBA4", true, true, true, true, false, false, false },
		{ GL_RGB5_A1, "GL_RGB5_A1", true, true, true, true, false, false, false },
		{ GL_RGBA8, "GL_RGBA8", true, true, true, true, false, false, false },
		{ GL_RGB10_A2, "GL_RGB10_A2", true, true, true, true, false, false, false },
		{ GL_RGB10_A2UI, "GL_RGB10_A2UI", true, true, true, true, false, false, true },
		{ GL_RGBA16, "GL_RGBA16", true, true, true, true, false, false, false },
		{ GL_SRGB8_ALPHA8, "GL_SRGB8_ALPHA8", true, true, true, true, false, false, false },
		{ GL_R16F, "GL_R16F", true, false, false, false, false, false, false },
		{ GL_RG16F, "GL_RG16F", true, true, false, false, false, false, false },
		{ GL_RGBA16F, "GL_RGBA16F", true, true, true, true, false, false, false },
		{ GL_R32F, "GL_R32F", true, false, false, false, false, false, false },
		{ GL_RG32F, "GL_RG32F", true, true, false, false, false, false, false },
		{ GL_RGBA32F, "GL_RGBA32F", true, true, true, true, false, false, false },
		{ GL_R11F_G11F_B10F, "GL_R11F_G11F_B10F", true, true, true, false, false, false, false },
		{ GL_R8I, "GL_R8I", true, false, false, false, false, false, true },
		{ GL_R8UI, "GL_R8UI", true, false, false, false, false, false, true },
		{ GL_R16I, "GL_R16I", true, false, false, false, false, false, true },
		{ GL_R16UI, "GL_R16UI", true, false, false, false, false, false, true },
		{ GL_R32I, "GL_R32I", true, false, false, false, false, false, true },
		{ GL_R32UI, "GL_R32UI", true, false, false, false, false, false, true },
		{ GL_RG8I, "GL_RG8I", true, true, false, false, false, false, true },
		{ GL_RG8UI, "GL_RG8UI", true, true, false, false, false, false, true },
		{ GL_RG16I, "GL_RG16I", true, true, false, false, false, false, true },
		{ GL_RG16UI, "GL_RG16UI", true, true, false, false, false, false, true },
		{ GL_RG32I, "GL_RG32I", true, true, false, false, false, false, true },
		{ GL_RG32UI, "GL_RG32UI", true, true, false, false, false, false, true },
		{ GL_RGBA8I, "GL_RGBA8I", true, true, true, true, false, false, true },
		{ GL_RGBA8UI, "GL_RGBA8UI", true, true, true, true, false, false, true },
		{ GL_RGBA16I, "GL_RGBA16I", true, true, true, true, false, false, true },
		{ GL_RGBA16UI, "GL_RGBA16UI", true, true, true, true, false, false, true },
		{ GL_RGBA32I, "GL_RGBA32I", true, true, true, true, false, false, true },
		{ GL_RGBA32UI, "GL_RGBA32UI", true, true, true, true, false, false, true },
		{ GL_DEPTH_COMPONENT16, "GL_DEPTH_COMPONENT16", false, false, false, false, true, false, false },
		{ GL_DEPTH_COMPONENT24, "GL_DEPTH_COMPONENT24", false, false, false, false, true, false, false },
		{ GL_DEPTH_COMPONENT32F, "GL_DEPTH_COMPONENT32F", false, false, false, false, true, false, false },
		{ GL_DEPTH24_STENCIL8, "GL_DEPTH24_STENCIL8", false, false, false, false, true, true, false },
		{ GL_DEPTH32F_STENCIL8, "GL_DEPTH32F_STENCIL8", false, false, false, false, true, true, false },
		{ GL_STENCIL_INDEX8, "GL_STENCIL_INDEX8", false, false, false, false, false, true, false }
	};

/** Internal formats count */
const glw::GLuint StorageTest::s_renderbuffer_internalformat_configuration_count =
	sizeof(s_renderbuffer_internalformat_configuration) / sizeof(s_renderbuffer_internalformat_configuration[0]);

const glw::GLfloat StorageTest::s_reference_color[4]		 = { 0.25, 0.5, 0.75, 1.0 }; //!< Reference color.
const glw::GLint   StorageTest::s_reference_color_integer[4] = { 1, 2, 3, 4 };			 //!< Reference integral color.
const glw::GLfloat StorageTest::s_reference_depth			 = 0.5;						 //!< Reference depth.
const glw::GLint   StorageTest::s_reference_stencil			 = 7;						 //!< Reference stencil.

/***************************** Renderbuffer Storage Multisample Test Implementation   ***************************/

/** @brief Renderbuffer Storage Multisample Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
StorageMultisampleTest::StorageMultisampleTest(deqp::Context& context)
	: deqp::TestCase(context, "renderbuffers_storage_multisample", "Renderbuffer Objects Storage Multisample Test")
{
	for (glw::GLuint i = 0; i < 2; ++i)
	{
		m_fbo[i] = 0;
		m_rbo[i] = 0;
	}
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult StorageMultisampleTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		glw::GLint max_renderbuffer_size = 16384 /* Specification minimum. */;

		gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_renderbuffer_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

		const struct
		{
			glw::GLuint width;
			glw::GLuint height;
		} test_cases[] = { { 1, 1 },
						   { (glw::GLuint)max_renderbuffer_size / 2, 1 },
						   { 1, (glw::GLuint)max_renderbuffer_size / 2 } };

		const glw::GLuint test_cases_count = sizeof(test_cases) / sizeof(test_cases[0]);

		for (glw::GLuint i = 0; i < test_cases_count; ++i)
		{
			for (glw::GLuint j = 0; j < s_renderbuffer_internalformat_configuration_count; ++j)
			{
				glw::GLint max_integer_samples = GetMaxConformantSampleCount(
					GL_RENDERBUFFER, s_renderbuffer_internalformat_configuration[j].internalformat);
				for (glw::GLint k = 0; k <= max_integer_samples; ++k)
				{
					if (PrepareRenderbuffer(s_renderbuffer_internalformat_configuration[j], test_cases[i].width,
											test_cases[i].height, k))
					{
						Bind(GL_DRAW_FRAMEBUFFER, 0);
						Clear(s_renderbuffer_internalformat_configuration[j].isColorIntegralFormat);
						Bind(GL_READ_FRAMEBUFFER, 0);
						Bind(GL_DRAW_FRAMEBUFFER, 1);
						Blit(test_cases[i].width, test_cases[i].height);
						Bind(GL_READ_FRAMEBUFFER, 1);
						is_ok &= Check(s_renderbuffer_internalformat_configuration[j], test_cases[i].width,
									   test_cases[i].height);
					}
					else
					{
						is_ok = false;
					}

					Clean();
				}
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;

		Clean();
	}

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Prepare renderbuffer.
 *
 *  @param [in] format              Internal format to be prepared.
 *  @param [in] width               Width of the framebuffer.
 *  @param [in] height              Height of the framebuffer.
 *
 *  @return True if there is no error, false otherwise.
 */
bool StorageMultisampleTest::PrepareRenderbuffer(StorageMultisampleTest::RenderbufferInternalFormatConfiguration format,
												 glw::GLuint width, glw::GLuint height, glw::GLsizei samples)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genFramebuffers(2, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.createRenderbuffers(2, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateRenderbuffers call failed.");

	for (glw::GLuint i = 0; i < 2; ++i)
	{
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

		if (i)
		{
			/* 2nd is not multisampled. */
			gl.namedRenderbufferStorageMultisample(m_rbo[i], 0, format.internalformat, width, height);

			if (glw::GLenum error = gl.getError())
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Renderbuffer storage multisample test failed because "
												"NamedRenderbufferStorageMultisample generated "
					<< glu::getErrorStr(error) << " error value. Renderbuffers format was "
					<< format.internalformat_name << ", samples was " << 0 << ", width was " << width << ", height was "
					<< height << "." << tcu::TestLog::EndMessage;
				return false;
			}
		}
		else
		{
			/* 1st is multisampled. */
			gl.namedRenderbufferStorageMultisample(m_rbo[i], samples, format.internalformat, width, height);

			if (glw::GLenum error = gl.getError())
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Renderbuffer storage multisample test failed because "
												"NamedRenderbufferStorageMultisample generated "
					<< glu::getErrorStr(error) << " error value. Renderbuffers format was "
					<< format.internalformat_name << ", samples was " << samples << ", width was " << width
					<< ", height was " << height << "." << tcu::TestLog::EndMessage;
				return false;
			}
		}

		if (format.hasRedComponent || format.hasGreenComponent || format.hasBlueComponent || format.hasAlphaComponent)
		{
			gl.namedFramebufferRenderbuffer(m_fbo[i], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo[i]);
		}

		if (format.hasDepthComponent)
		{
			gl.namedFramebufferRenderbuffer(m_fbo[i], GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbo[i]);
		}

		if (format.hasStencilComponent)
		{
			gl.namedFramebufferRenderbuffer(m_fbo[i], GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo[i]);
		}

		glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
		if (status != GL_FRAMEBUFFER_COMPLETE)
		{
			/* Log. */
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Renderbuffer storage multisample test failed due to "
				<< glu::getFramebufferStatusStr(status) << " framebuffer status. Renderbuffers format was "
				<< format.internalformat_name << ", samples was " << (i ? 0 : samples) << ", width was " << width
				<< ", height was " << height << "." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

/** Bind framebuffer to the target.
 *
 *  @param [in] target              Bind to target.
 *  @param [in] selector            Index of the framebuffer in framebuffers' arrays.
 */
void StorageMultisampleTest::Bind(glw::GLenum target, glw::GLuint selector)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Binding framebuffer. */
	gl.bindFramebuffer(target, m_fbo[selector]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
}

/** Blit one framebuffer to the second.
 *
 *  @param [in] width               Width of the framebuffer.
 *  @param [in] height              Height of the framebuffer.
 *
 *  @return True if there is no error, false otherwise.
 */
void StorageMultisampleTest::Blit(glw::GLuint width, glw::GLuint height)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Binding framebuffer. */
	gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height,
					   GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
}

/** Clear framebuffer.
 *
 *  @param [in] isColorIntegralFormat       Is framebuffer a color integral type.
 */
void StorageMultisampleTest::Clear(bool isColorIntegralFormat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (isColorIntegralFormat)
	{
		gl.clearBufferiv(GL_COLOR, 0, s_reference_color_integer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferiv has failed");
	}
	else
	{
		/* Setup clear values. */
		gl.clearColor(s_reference_color[0], s_reference_color[1], s_reference_color[2], s_reference_color[3]);
		gl.clearDepth(s_reference_depth);
		gl.clearStencil(s_reference_stencil);

		/* Clear rbo/fbo. */
		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	}
}

/** Check renderbuffer's content.
 *
 *  @param [in] format              Internal format to be prepared.
 *  @param [in] width               Width of the framebuffer.
 *  @param [in] height              Height of the framebuffer.
 *
 *  @return True if content matches the reference, false otherwise.
 */
bool StorageMultisampleTest::Check(StorageMultisampleTest::RenderbufferInternalFormatConfiguration format,
								   glw::GLuint width, glw::GLuint height)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint size = width * height;

	if (format.hasRedComponent || format.hasGreenComponent || format.hasBlueComponent || format.hasAlphaComponent)
	{
		if (format.isColorIntegralFormat)
		{
			std::vector<glw::GLint> color(size * 4);

			gl.readPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_INT, &color[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

			const bool hasComponent[] = { format.hasRedComponent, format.hasGreenComponent, format.hasBlueComponent,
										  format.hasAlphaComponent };

			static const char* componentName[] = { "red", "green", "blue", "alpha" };

			for (glw::GLuint i = 0; i < size; ++i)
			{
				if (hasComponent[i % 4 /* color components count*/])
				{
					if (de::abs(s_reference_color_integer[i % 4 /* color components count*/] - color[i]) >
						2 /* Precision */)
					{
						m_context.getTestContext().getLog()
							<< tcu::TestLog::Message << "Renderbuffer storage multisample was cleared with color "
							<< componentName[i % 4 /* color components count*/] << " component equal to "
							<< s_reference_color_integer << ", but fetched value " << color[i]
							<< " is not the same. Renderbuffers format was " << format.internalformat_name
							<< ", width was " << width << ", height was " << height << "." << tcu::TestLog::EndMessage;

						return false;
					}
				}
			}
		}
		else
		{
			std::vector<glw::GLfloat> color(size * 4);

			gl.readPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, &color[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

			const bool hasComponent[] = { format.hasRedComponent, format.hasGreenComponent, format.hasBlueComponent,
										  format.hasAlphaComponent };

			static const char* componentName[] = { "red", "green", "blue", "alpha" };

			for (glw::GLuint i = 0; i < size; ++i)
			{
				if (hasComponent[i % 4 /* color components count*/])
				{
					if (de::abs(s_reference_color[i % 4 /* color components count*/] - color[i]) >
						0.0625 /* precision */)
					{
						m_context.getTestContext().getLog()
							<< tcu::TestLog::Message << "Renderbuffer storage multisample was cleared with color "
							<< componentName[i % 4 /* color components count*/] << " component equal to "
							<< s_reference_color[i % 4 /* color components count*/] << ", but fetched value "
							<< color[i] << " is not the same. Renderbuffers format was " << format.internalformat_name
							<< ", width was " << width << ", height was " << height << "." << tcu::TestLog::EndMessage;

						return false;
					}
				}
			}
		}
	}

	if (format.hasDepthComponent)
	{
		std::vector<glw::GLfloat> depth(size);

		gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, &depth[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

		for (glw::GLuint i = 0; i < size; ++i)
		{
			if (de::abs(s_reference_depth - depth[i]) > 0.0625 /* 1/16 precision */)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "Renderbuffer storage multisample was cleared with depth component equal to "
					<< s_reference_depth << ", but fetched value " << depth[i]
					<< " is not the same. Renderbuffers format was " << format.internalformat_name << ", width was "
					<< width << ", height was " << height << "." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	if (format.hasStencilComponent)
	{
		std::vector<glw::GLint> stencil(size);

		gl.readPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_INT, &stencil[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

		for (glw::GLuint i = 0; i < size; ++i)
		{
			if (s_reference_stencil != stencil[i])
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "Renderbuffer storage multisample was cleared with alpha component equal to "
					<< s_reference_stencil << ", but fetched value " << stencil[i]
					<< " is not the same. Renderbuffers format was " << format.internalformat_name << ", width was "
					<< width << ", height was " << height << "." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	return true;
}

/** @brief Clean up GL state.
 */
void StorageMultisampleTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release objects. */
	for (glw::GLuint i = 0; i < 2; ++i)
	{
		if (m_rbo[i])
		{
			gl.deleteRenderbuffers(1, &m_rbo[i]);

			m_rbo[i] = 0;
		}

		if (m_fbo[i])
		{
			gl.deleteFramebuffers(1, &m_fbo[i]);

			m_fbo[i] = 0;
		}
	}

	/* Returning to default clear values. */
	gl.clearColor(0.f, 0.f, 0.f, 0.f);
	gl.clearDepth(1.f);
	gl.clearStencil(0);

	/* Errors clean up. */
	while (gl.getError())
		;
}

/** @brief Retrieve max conformant sample count when GL_NV_internalformat_sample_query is supported
 *
 *  @param [in] target			Target indicating usage of internal format
 *  @param [in] internalFormat		Internal format about which to retrieve information
 *
 *  @return Max conformant sample count
 */
glw::GLint StorageMultisampleTest::GetMaxConformantSampleCount(glw::GLenum target, glw::GLenum internalFormat)
{
	glw::GLint max_conformant_samples = 0;

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

	/* Return the max conformant sample count if extension is supported */
	if (m_context.getContextInfo().isExtensionSupported("GL_NV_internalformat_sample_query"))
	{
		glw::GLint gl_sample_counts = 0;
		gl.getInternalformativ(target, internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &gl_sample_counts);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_NUM_SAMPLE_COUNTS pname");

		/* Check and return the max conformant sample count */
		glw::GLint* gl_supported_samples = new glw::GLint[gl_sample_counts];
		if (gl_supported_samples)
		{
			gl.getInternalformativ(target, internalFormat, GL_SAMPLES, gl_sample_counts, gl_supported_samples);

			for (glw::GLint i = 0; i < gl_sample_counts; i++)
			{
				glw::GLint isConformant = 0;
				gl.getInternalformatSampleivNV(target, internalFormat, gl_supported_samples[i], GL_CONFORMANT_NV, 1,
											   &isConformant);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformatSampleivNV() call(s) failed");

				if (isConformant && gl_supported_samples[i] > max_conformant_samples)
				{
					max_conformant_samples = gl_supported_samples[i];
				}
			}
			delete[] gl_supported_samples;
		}
	}
	else
	{
		/* Otherwise return GL_MAX_INTEGER_SAMPLES */
		gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &max_conformant_samples);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_INTEGER_SAMPLES pname.");
	}

	return max_conformant_samples;
}

/** Tested internal format */
const struct StorageMultisampleTest::RenderbufferInternalFormatConfiguration
	StorageMultisampleTest::s_renderbuffer_internalformat_configuration[] = {
		{ GL_R8, "GL_R8", true, false, false, false, false, false, false },
		{ GL_R16, "GL_R16", true, false, false, false, false, false, false },
		{ GL_RG8, "GL_RG8", true, true, false, false, false, false, false },
		{ GL_RG16, "GL_RG16", true, true, false, false, false, false, false },
		{ GL_RGB565, "GL_RGB56", true, true, true, false, false, false, false },
		{ GL_RGBA4, "GL_RGBA4", true, true, true, true, false, false, false },
		{ GL_RGB5_A1, "GL_RGB5_A1", true, true, true, true, false, false, false },
		{ GL_RGBA8, "GL_RGBA8", true, true, true, true, false, false, false },
		{ GL_RGB10_A2, "GL_RGB10_A2", true, true, true, true, false, false, false },
		{ GL_RGB10_A2UI, "GL_RGB10_A2UI", true, true, true, true, false, false, true },
		{ GL_RGBA16, "GL_RGBA16", true, true, true, true, false, false, false },
		{ GL_SRGB8_ALPHA8, "GL_SRGB8_ALPHA8", true, true, true, true, false, false, false },
		{ GL_R16F, "GL_R16F", true, false, false, false, false, false, false },
		{ GL_RG16F, "GL_RG16F", true, true, false, false, false, false, false },
		{ GL_RGBA16F, "GL_RGBA16F", true, true, true, true, false, false, false },
		{ GL_R32F, "GL_R32F", true, false, false, false, false, false, false },
		{ GL_RG32F, "GL_RG32F", true, true, false, false, false, false, false },
		{ GL_RGBA32F, "GL_RGBA32F", true, true, true, true, false, false, false },
		{ GL_R11F_G11F_B10F, "GL_R11F_G11F_B10F", true, true, true, false, false, false, false },
		{ GL_R8I, "GL_R8I", true, false, false, false, false, false, true },
		{ GL_R8UI, "GL_R8UI", true, false, false, false, false, false, true },
		{ GL_R16I, "GL_R16I", true, false, false, false, false, false, true },
		{ GL_R16UI, "GL_R16UI", true, false, false, false, false, false, true },
		{ GL_R32I, "GL_R32I", true, false, false, false, false, false, true },
		{ GL_R32UI, "GL_R32UI", true, false, false, false, false, false, true },
		{ GL_RG8I, "GL_RG8I", true, true, false, false, false, false, true },
		{ GL_RG8UI, "GL_RG8UI", true, true, false, false, false, false, true },
		{ GL_RG16I, "GL_RG16I", true, true, false, false, false, false, true },
		{ GL_RG16UI, "GL_RG16UI", true, true, false, false, false, false, true },
		{ GL_RG32I, "GL_RG32I", true, true, false, false, false, false, true },
		{ GL_RG32UI, "GL_RG32UI", true, true, false, false, false, false, true },
		{ GL_RGBA8I, "GL_RGBA8I", true, true, true, true, false, false, true },
		{ GL_RGBA8UI, "GL_RGBA8UI", true, true, true, true, false, false, true },
		{ GL_RGBA16I, "GL_RGBA16I", true, true, true, true, false, false, true },
		{ GL_RGBA16UI, "GL_RGBA16UI", true, true, true, true, false, false, true },
		{ GL_RGBA32I, "GL_RGBA32I", true, true, true, true, false, false, true },
		{ GL_RGBA32UI, "GL_RGBA32UI", true, true, true, true, false, false, true },
		{ GL_DEPTH_COMPONENT16, "GL_DEPTH_COMPONENT16", false, false, false, false, true, false, false },
		{ GL_DEPTH_COMPONENT24, "GL_DEPTH_COMPONENT24", false, false, false, false, true, false, false },
		{ GL_DEPTH_COMPONENT32F, "GL_DEPTH_COMPONENT32F", false, false, false, false, true, false, false },
		{ GL_DEPTH24_STENCIL8, "GL_DEPTH24_STENCIL8", false, false, false, false, true, true, false },
		{ GL_DEPTH32F_STENCIL8, "GL_DEPTH32F_STENCIL8", false, false, false, false, true, true, false },
		{ GL_STENCIL_INDEX8, "GL_STENCIL_INDEX8", false, false, false, false, false, true, false }
	};

/** Tesetd internal format count */
const glw::GLuint StorageMultisampleTest::s_renderbuffer_internalformat_configuration_count =
	sizeof(s_renderbuffer_internalformat_configuration) / sizeof(s_renderbuffer_internalformat_configuration[0]);

const glw::GLfloat StorageMultisampleTest::s_reference_color[4] = { 0.25, 0.5, 0.75, 1.0 }; //!< Reference color value.
const glw::GLint   StorageMultisampleTest::s_reference_color_integer[4] = {
	1, 2, 3, 4
}; //!< Reference color value for integral color internal formats.
const glw::GLfloat StorageMultisampleTest::s_reference_depth   = 0.5; //!< Reference depth value.
const glw::GLint   StorageMultisampleTest::s_reference_stencil = 7;   //!< Reference stencil value.

/******************************** Get Named Renderbuffer Parameters Test Implementation   ********************************/

/** @brief Get Named Renderbuffer Parameters Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetParametersTest::GetParametersTest(deqp::Context& context)
	: deqp::TestCase(context, "renderbuffers_get_parameters", "Get Named Renderbuffer Parameters Test")
	, m_fbo(0)
	, m_rbo(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Check Status Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetParametersTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Test renderbuffer. */
	glw::GLuint renderbuffer = 0;

	/* Test. */
	try
	{
		static const glw::GLenum internalformats[] = { GL_RGBA8, GL_DEPTH_COMPONENT24, GL_STENCIL_INDEX8,
													   GL_DEPTH24_STENCIL8 };

		static const glw::GLuint internalformats_count = sizeof(internalformats) / sizeof(internalformats[0]);

		for (glw::GLuint i = 0; i < internalformats_count; ++i)
		{
			gl.genRenderbuffers(1, &renderbuffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");

			gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");

			gl.renderbufferStorage(GL_RENDERBUFFER, internalformats[i], 1, 2);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");

			static const glw::GLenum pnames[] = { GL_RENDERBUFFER_WIDTH,		   GL_RENDERBUFFER_HEIGHT,
												  GL_RENDERBUFFER_INTERNAL_FORMAT, GL_RENDERBUFFER_SAMPLES,
												  GL_RENDERBUFFER_RED_SIZE,		   GL_RENDERBUFFER_GREEN_SIZE,
												  GL_RENDERBUFFER_BLUE_SIZE,	   GL_RENDERBUFFER_ALPHA_SIZE,
												  GL_RENDERBUFFER_DEPTH_SIZE,	  GL_RENDERBUFFER_STENCIL_SIZE };

			static const glw::GLchar* pnames_strings[] = {
				"GL_RENDERBUFFER_WIDTH",	   "GL_RENDERBUFFER_HEIGHT",	 "GL_RENDERBUFFER_INTERNAL_FORMAT",
				"GL_RENDERBUFFER_SAMPLES",	 "GL_RENDERBUFFER_RED_SIZE",   "GL_RENDERBUFFER_GREEN_SIZE",
				"GL_RENDERBUFFER_BLUE_SIZE",   "GL_RENDERBUFFER_ALPHA_SIZE", "GL_RENDERBUFFER_DEPTH_SIZE",
				"GL_RENDERBUFFER_STENCIL_SIZE"
			};

			for (glw::GLuint j = 0; j < internalformats_count; ++j)
			{
				glw::GLint parameter_legacy = 0;
				glw::GLint parameter_dsa	= 0;

				gl.getRenderbufferParameteriv(GL_RENDERBUFFER, pnames[j], &parameter_legacy);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetRenderbufferParameteriv has failed");

				gl.getNamedRenderbufferParameteriv(renderbuffer, pnames[j], &parameter_dsa);

				if (glw::GLenum error = gl.getError())
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetNamedRenderbufferParameteriv unexpectedly generated "
						<< glu::getErrorStr(error) << " error when called with " << pnames_strings[i]
						<< " parameter name of renderbuffer with  internalformat = "
						<< glu::getInternalFormatParameterStr(internalformats[i]) << ", width = 1, height = 2."
						<< tcu::TestLog::EndMessage;

					is_ok = false;

					continue;
				}

				if (parameter_legacy != parameter_dsa)
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetNamedRenderbufferParameteriv returned " << parameter_dsa
						<< ", but " << parameter_legacy << " was expected for " << pnames_strings[i]
						<< " parameter name of renderbuffer with  internalformat = "
						<< glu::getInternalFormatParameterStr(internalformats[i]) << ", width = 1, height = 2."
						<< tcu::TestLog::EndMessage;

					is_ok = false;
				}
			}

			gl.deleteRenderbuffers(1, &renderbuffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers has failed");

			renderbuffer = 0;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	if (renderbuffer)
	{
		gl.deleteRenderbuffers(1, &renderbuffer);
	}

	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Renderbuffer Creation Errors Test Implementation   ********************************/

/** @brief Creation Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationErrorsTest::CreationErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "renderbuffers_creation_errors", "Renderbuffer Objects Creation Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok = true;

	/* Framebuffer object */
	glw::GLuint renderbuffer = 0;

	/* Check direct state creation of negative numbers of framebuffers. */
	gl.createRenderbuffers(-1, &renderbuffer);

	glw::GLenum error = GL_NO_ERROR;

	if (GL_INVALID_VALUE != (error = gl.getError()))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "CreateRenderbuffers generated " << glu::getErrorStr(error)
			<< " error when called with negative number of renderbuffers, but GL_INVALID_VALUE was expected."
			<< tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Cleanup (sanity). */
	if (renderbuffer)
	{
		gl.deleteRenderbuffers(1, &renderbuffer);
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/******************************** Storage Errors Test Implementation   ********************************/

/** @brief Storage Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
StorageErrorsTest::StorageErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "renderbuffers_storage_errors", "Storage Errors Test")
	, m_rbo_valid(0)
	, m_rbo_invalid(0)
	, m_internalformat_invalid(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult StorageErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		/*  Check that INVALID_OPERATION is generated by NamedRenderbufferStorage if
		 renderbuffer is not the name of an existing renderbuffer object. */
		gl.namedRenderbufferStorage(m_rbo_invalid, GL_RGBA8, 1, 1);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedRenderbufferStorage",
							 "renderbuffer is not the name of an existing renderbuffer object.");

		/*  Check that INVALID_VALUE is generated by NamedRenderbufferStorage if
		 either of width or height is negative, or greater than the value of
		 MAX_RENDERBUFFER_SIZE. */
		gl.namedRenderbufferStorage(m_rbo_valid, GL_RGBA8, -1, 1);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedRenderbufferStorage", "either of width is negative.");

		gl.namedRenderbufferStorage(m_rbo_valid, GL_RGBA8, 1, -1);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedRenderbufferStorage", "either of height is negative.");

		/*  Check that INVALID_ENUM is generated by NamedRenderbufferStorage if
		 internalformat is not a color-renderable, depth-renderable, or
		 stencil-renderable format. */
		gl.namedRenderbufferStorage(m_rbo_valid, m_internalformat_invalid, 1, 1);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedRenderbufferStorage", "internalformat is not a color-renderable, "
																		  "depth-renderable, or stencil-renderable "
																		  "format (it is COMPRESSED_RED).");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void StorageErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genRenderbuffers(1, &m_rbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Invalid objects. */
	while (gl.isRenderbuffer(++m_rbo_invalid))
		;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool StorageErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
									const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void StorageErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_rbo_valid)
	{
		gl.deleteRenderbuffers(1, &m_rbo_valid);
		m_rbo_valid = 0;
	}

	/*  COmpressed internal formats are not color renderable (OpenGL 4.5 Core PRofile SPecification Chapter 9.4 )*/
	m_internalformat_invalid = GL_COMPRESSED_RED;

	/* Set initial values - all test shall have the same environment. */
	m_rbo_valid   = 0;
	m_rbo_invalid = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Storage Multisample Errors Test Implementation   ********************************/

/** @brief Storage Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
StorageMultisampleErrorsTest::StorageMultisampleErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "renderbuffers_storage_multisample_errors", "Storage Multisample Errors Test")
	, m_rbo_valid(0)
	, m_rbo_invalid(0)
	, m_internalformat_invalid(0)
	, m_max_samples(0)
	, m_max_integer_samples(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult StorageMultisampleErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		/*  Check that INVALID_OPERATION is generated by NamedRenderbufferStorage if
		 renderbuffer is not the name of an existing renderbuffer object. */
		gl.namedRenderbufferStorageMultisample(m_rbo_invalid, 1, GL_RGBA8, 1, 1);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedRenderbufferStorageMultisample",
							 "renderbuffer is not the name of an existing renderbuffer object.");

		/*  Check that INVALID_VALUE is generated by
		 NamedRenderbufferStorageMultisample if samples is greater than
		 the maximum number of SAMPLES reported for GL_RGBA8. */
		gl.namedRenderbufferStorageMultisample(m_rbo_valid, m_max_samples + 1, GL_RGBA8, 1, 1);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedRenderbufferStorageMultisample",
							 "samples is greater than MAX_SAMPLES.");

		/*  Check that INVALID_VALUE is generated by NamedRenderbufferStorage if
		 either of width or height is negative, or greater than the value of
		 MAX_RENDERBUFFER_SIZE. */
		gl.namedRenderbufferStorageMultisample(m_rbo_valid, 1, GL_RGBA8, -1, 1);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedRenderbufferStorageMultisample", "either of width is negative.");

		gl.namedRenderbufferStorageMultisample(m_rbo_valid, 1, GL_RGBA8, 1, -1);

		is_ok &= ExpectError(GL_INVALID_VALUE, "NamedRenderbufferStorageMultisample", "either of height is negative.");

		/*  Check that INVALID_OPERATION is generated by
		 NamedRenderbufferStorageMultisample if internalformat is a signed or
		 unsigned integer format and samples is greater than the maximum number
		 of samples reported for GL_RGB10_A2UI */
		gl.namedRenderbufferStorageMultisample(m_rbo_valid, m_max_integer_samples + 1, GL_RGB10_A2UI, 1, 1);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedRenderbufferStorageMultisample",
							 "internalformat is a signed or unsigned integer format and samples is greater than the "
							 "value of MAX_INTEGER_SAMPLES.");

		/*  Check that INVALID_ENUM is generated by NamedRenderbufferStorage if
		 internalformat is not a color-renderable, depth-renderable, or
		 stencil-renderable format. */
		gl.namedRenderbufferStorageMultisample(m_rbo_valid, 1, m_internalformat_invalid, 1, 1);

		is_ok &= ExpectError(GL_INVALID_ENUM, "NamedRenderbufferStorageMultisample",
							 "internalformat is not a color-renderable, depth-renderable, or stencil-renderable format "
							 "(it is COMPRESSED_RED).");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void StorageMultisampleErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genRenderbuffers(1, &m_rbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Limits. */
	gl.getInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &m_max_samples);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ has failed");

	gl.getInternalformativ(GL_RENDERBUFFER, GL_RGB10_A2UI, GL_SAMPLES, 1, &m_max_integer_samples);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ has failed");

	/* Invalid objects. */
	while (gl.isRenderbuffer(++m_rbo_invalid))
		;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool StorageMultisampleErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
											   const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void StorageMultisampleErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_rbo_valid)
	{
		gl.deleteRenderbuffers(1, &m_rbo_valid);
		m_rbo_valid = 0;
	}

	/*  COmpressed internal formats are not color renderable (OpenGL 4.5 Core PRofile SPecification Chapter 9.4 )*/
	m_internalformat_invalid = GL_COMPRESSED_RED;

	/* Set initial values - all test shall have the same environment. */
	m_rbo_valid			  = 0;
	m_rbo_invalid		  = 0;
	m_max_samples		  = 0;
	m_max_integer_samples = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

/******************************** Get Parameter Errors Test Implementation   ********************************/

/** @brief Parameter Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetParameterErrorsTest::GetParameterErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "renderbuffers_get_parameters_errors", "Get Parameter Errors Test")
	, m_rbo_valid(0)
	, m_rbo_invalid(0)
	, m_parameter_invalid(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Parameter Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetParameterErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		/* Prepare objects. */
		PrepareObjects();

		glw::GLint return_value_dummy_storage;

		/*  Check that INVALID_OPERATION is generated by
		 GetNamedRenderbufferParameteriv if renderbuffer is not the name of an
		 existing renderbuffer object. */
		gl.getNamedRenderbufferParameteriv(m_rbo_invalid, GL_RENDERBUFFER_WIDTH, &return_value_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedRenderbufferParameteriv",
							 "renderbuffer is not the name of an existing renderbuffer object.");

		/*  Check that INVALID_ENUM is generated by GetNamedRenderbufferParameteriv
		 if parameter name is not one of the accepted parameter names described
		 in specification. */
		gl.getNamedRenderbufferParameteriv(m_rbo_valid, m_parameter_invalid, &return_value_dummy_storage);

		is_ok &= ExpectError(GL_INVALID_ENUM, "GetNamedRenderbufferParameteriv",
							 "parameter name is not one of the accepted parameter names described in specification.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Check Prepare test's GL objects.
 */
void GetParameterErrorsTest::PrepareObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Valid objects. */
	gl.genRenderbuffers(1, &m_rbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_valid);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Invalid parameter. */
	bool is_parameter = true;

	while (is_parameter)
	{
		is_parameter = false;

		++m_parameter_invalid;

		static const glw::GLenum valid_parameters[] = { GL_RENDERBUFFER_WIDTH,			 GL_RENDERBUFFER_HEIGHT,
														GL_RENDERBUFFER_INTERNAL_FORMAT, GL_RENDERBUFFER_SAMPLES,
														GL_RENDERBUFFER_RED_SIZE,		 GL_RENDERBUFFER_GREEN_SIZE,
														GL_RENDERBUFFER_BLUE_SIZE,		 GL_RENDERBUFFER_ALPHA_SIZE,
														GL_RENDERBUFFER_DEPTH_SIZE,		 GL_RENDERBUFFER_STENCIL_SIZE };

		static const glw::GLuint valid_parameters_count = sizeof(valid_parameters) / sizeof(valid_parameters[0]);

		for (glw::GLuint i = 0; i < valid_parameters_count; ++i)
		{
			if (valid_parameters[i] == m_parameter_invalid)
			{
				is_parameter = true;
			}
		}
	}

	/* Invalid objects. */
	while (gl.isRenderbuffer(++m_rbo_invalid))
		;
}

/** Check if error is equal to the expected, log if not.
 *
 *  @param [in] expected_error      Error to be expected.
 *  @param [in] function            Function name which is being tested (to be logged).
 *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
 *
 *  @return True if there is no error, false otherwise.
 */
bool GetParameterErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
										 const glw::GLchar* conditions)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
											<< glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
											<< " was observed instead when " << conditions << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	/* Clean additional possible errors. */
	while (gl.getError())
		;

	return is_ok;
}

/** @brief Clean up GL state.
 */
void GetParameterErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_rbo_valid)
	{
		gl.deleteRenderbuffers(1, &m_rbo_valid);
		m_rbo_valid = 0;
	}

	/* Set initial values - all test shall have the same environment. */
	m_rbo_valid   = 0;
	m_rbo_invalid = 0;

	/* Errors clean up. */
	while (gl.getError())
		;
}

} // namespace Renderbuffers
} // namespace DirectStateAccess
} // namespace gl4cts
