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

/**
 */ /*!
 * \file  gl4cShaderViewportLayerArrayTests.cpp
 * \brief Conformance tests for the ARB_shader_viewport_layer_array functionality.
 */ /*-------------------------------------------------------------------*/

#include "gl4cShaderViewportLayerArrayTests.hpp"
#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluDrawUtil.hpp"
#include "gluObjectWrapper.hpp"
#include "gluShaderProgram.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuRenderTarget.hpp"

#include <sstream>
#include <string>
#include <vector>

using namespace glw;

namespace gl4cts
{

ShaderViewportLayerArrayUtils::ShaderPipeline::ShaderPipeline(bool tessellationShader, bool geometryShader,
															  int maxViewportsLayers, const std::string& varName)
	: m_program(NULL)
	, m_hasTessellationShader(tessellationShader)
	, m_hasGeometryShader(geometryShader)
	, m_viewportLayerOffset(m_hasGeometryShader ? OFFSET_GEOMETRY :
												  m_hasTessellationShader ? OFFSET_TESSELLATION : OFFSET_VERTEX)
	, m_varName(varName)
{
	m_vs = "#version 450 core\n"
		   "#extension GL_ARB_shader_viewport_layer_array: require\n"
		   "in highp vec2 inPosition;\n"
		   "in int in<var_name>;\n"
		   "in highp vec4 inColor;\n"
		   "out int vs<var_name>;\n"
		   "out highp vec3 vsPosition;\n"
		   "out highp vec4 vsColor;\n"
		   "void main()\n"
		   "{\n"
		   "	gl_Position = vec4(inPosition, 0.0, 1.0);\n"
		   "	gl_<var_name> = (in<var_name> + <viewport_layer_offset>) % <viewport_layer_max>;\n"
		   "	vs<var_name> = in<var_name>;\n"
		   "	vsPosition = vec3(inPosition, 0.0);\n"
		   "	vsColor = inColor;\n"
		   "}\n";

	m_tcs = "#version 450 core\n"
			"layout(vertices = 3) out;\n"
			"in highp vec3 vsPosition[];\n"
			"in highp vec4 vsColor[];\n"
			"in int vs<var_name>[];\n"
			"out highp vec3 tcsPosition[];\n"
			"out highp vec4 tcsColor[];\n"
			"out int tcs<var_name>[];\n"
			"void main()\n"
			"{\n"
			"	tcsPosition[gl_InvocationID] = vsPosition[gl_InvocationID];\n"
			"	tcsColor[gl_InvocationID] = vsColor[gl_InvocationID];\n"
			"	tcs<var_name>[gl_InvocationID] = vs<var_name>[gl_InvocationID];\n"
			"	gl_TessLevelInner[0] = 3;\n"
			"	gl_TessLevelOuter[0] = 3;\n"
			"	gl_TessLevelOuter[1] = 3;\n"
			"	gl_TessLevelOuter[2] = 3;\n"
			"}\n";

	m_tes = "#version 450 core\n"
			"#extension GL_ARB_shader_viewport_layer_array: require\n"
			"layout(triangles, equal_spacing, cw) in;\n"
			"in highp vec3 tcsPosition[];\n"
			"in highp vec4 tcsColor[];\n"
			"in int tcs<var_name>[];\n"
			"out highp vec4 tesColor;\n"
			"out highp int tes<var_name>;\n"
			"void main()\n"
			"{\n"
			"	vec3 p0 = gl_TessCoord.x * tcsPosition[0];\n"
			"	vec3 p1 = gl_TessCoord.y * tcsPosition[1];\n"
			"	vec3 p2 = gl_TessCoord.z * tcsPosition[2];\n"
			"	tesColor = tcsColor[0];\n"
			"	tes<var_name> = tcs<var_name>[0];\n"
			"	gl_<var_name> = (tcs<var_name>[0] + <viewport_layer_offset>) % <viewport_layer_max>;\n"
			"	gl_Position = vec4(normalize(p0 + p1 + p2), 1.0);\n"
			"}\n";

	m_gs = "#version 450 core\n"
		   "#extension GL_ARB_shader_viewport_layer_array: require\n"
		   "layout(triangles) in;\n"
		   "layout(triangle_strip, max_vertices = 3) out;\n"
		   "in highp vec4 tesColor[];\n"
		   "in int tes<var_name>[];\n"
		   "out highp vec4 gsColor;\n"
		   "void main()\n"
		   "{\n"
		   "	for (int i = 0; i<3; i++)\n"
		   "	{\n"
		   "		gl_Position = gl_in[i].gl_Position;\n"
		   "		gl_<var_name> = (tes<var_name>[i] + <viewport_layer_offset>) % <viewport_layer_max>;\n"
		   "		gsColor = tesColor[i];\n"
		   "		EmitVertex();\n"
		   "	}\n"
		   "	EndPrimitive();\n"
		   "}\n";

	m_fs = "#version 450 core\n"
		   "in highp vec4 <input_color>;\n"
		   "out vec4 finalOutColor;\n"
		   "void main()\n"
		   "{\n"
		   "	finalOutColor = <input_color>;\n"
		   "}\n";

	this->adaptShaderToPipeline(m_vs, "<var_name>", varName);
	this->adaptShaderToPipeline(m_vs, "<viewport_layer_offset>", OFFSET_VERTEX);
	this->adaptShaderToPipeline(m_vs, "<viewport_layer_max>", maxViewportsLayers);

	this->adaptShaderToPipeline(m_tes, "<var_name>", varName);
	this->adaptShaderToPipeline(m_tes, "<viewport_layer_offset>", OFFSET_TESSELLATION);
	this->adaptShaderToPipeline(m_tes, "<viewport_layer_max>", maxViewportsLayers);

	this->adaptShaderToPipeline(m_tcs, "<var_name>", varName);

	this->adaptShaderToPipeline(m_gs, "<var_name>", varName);
	this->adaptShaderToPipeline(m_gs, "<viewport_layer_offset>", OFFSET_GEOMETRY);
	this->adaptShaderToPipeline(m_gs, "<viewport_layer_max>", maxViewportsLayers);

	this->adaptShaderToPipeline(m_fs, "<input_color>", "vsColor", "tesColor", "gsColor");
}

void ShaderViewportLayerArrayUtils::ShaderPipeline::adaptShaderToPipeline(std::string&		 shader,
																		  const std::string& varKey,
																		  const std::string& vsVersion,
																		  const std::string& tesVersion,
																		  const std::string& gsVersion)
{
	std::string varName = m_hasGeometryShader ? gsVersion : m_hasTessellationShader ? tesVersion : vsVersion;

	size_t start = 0;
	while ((start = shader.find(varKey, start)) != std::string::npos)
	{
		shader.replace(start, varKey.length(), varName);
		start += varName.length();
	}
}

void ShaderViewportLayerArrayUtils::ShaderPipeline::adaptShaderToPipeline(std::string&		 shader,
																		  const std::string& varKey,
																		  const std::string& value)
{
	this->adaptShaderToPipeline(shader, varKey, value, value, value);
}

void ShaderViewportLayerArrayUtils::ShaderPipeline::adaptShaderToPipeline(std::string&		 shader,
																		  const std::string& varKey, int value)
{
	std::ostringstream valueStr;
	valueStr << value;

	this->adaptShaderToPipeline(shader, varKey, valueStr.str(), valueStr.str(), valueStr.str());
}

ShaderViewportLayerArrayUtils::ShaderPipeline::~ShaderPipeline()
{
	if (m_program)
	{
		delete m_program;
	}
}

void ShaderViewportLayerArrayUtils::ShaderPipeline::create(const glu::RenderContext& context)
{
	glu::ProgramSources sources;
	sources.sources[glu::SHADERTYPE_VERTEX].push_back(m_vs);
	if (m_hasTessellationShader)
	{
		sources.sources[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back(m_tcs);
		sources.sources[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back(m_tes);
	}
	if (m_hasGeometryShader)
	{
		sources.sources[glu::SHADERTYPE_GEOMETRY].push_back(m_gs);
	}
	sources.sources[glu::SHADERTYPE_FRAGMENT].push_back(m_fs);

	m_program = new glu::ShaderProgram(context, sources);
	if (!m_program->isOk())
	{
		TCU_FAIL("Shader compilation failed");
	}
}

void ShaderViewportLayerArrayUtils::ShaderPipeline::use(const glu::RenderContext& context)
{
	const glw::Functions& gl = context.getFunctions();
	gl.useProgram(m_program->getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");
}

void ShaderViewportLayerArrayUtils::renderQuad(const glu::RenderContext& context, ShaderPipeline& shaderPipeline,
											   int viewportLayerIndex, tcu::Vec4 color)
{
	const glw::Functions& gl = context.getFunctions();

	deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };

	float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };

	int const viewportLayerIndices[] = { viewportLayerIndex, viewportLayerIndex, viewportLayerIndex,
										 viewportLayerIndex };

	float const colors[] = { color.x(), color.y(), color.z(), color.w(), color.x(), color.y(), color.z(), color.w(),
							 color.x(), color.y(), color.z(), color.w(), color.x(), color.y(), color.z(), color.w() };

	std::string varName = "in";
	varName += shaderPipeline.getVarName();

	glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("inPosition", 2, 4, 0, position),
											   glu::va::Int32(varName, 1, 4, 0, viewportLayerIndices),
											   glu::va::Float("inColor", 4, 4, 0, colors) };

	shaderPipeline.use(context);

	glu::PrimitiveList primitiveList = shaderPipeline.hasTessellationShader() ?
										   glu::pr::Patches(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices) :
										   glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices);

	glu::draw(context, shaderPipeline.getShaderProgram()->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
			  primitiveList, (glu::DrawUtilCallback*)DE_NULL);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::draw error");
}

bool ShaderViewportLayerArrayUtils::validateColor(tcu::Vec4 renderedColor, tcu::Vec4 referenceColor)
{
	const float epsilon = 1.1f / 31.0f; // Accommodate framebuffers with 5-bit channels.
	return de::abs(renderedColor.x() - referenceColor.x()) < epsilon &&
		   de::abs(renderedColor.y() - referenceColor.y()) < epsilon &&
		   de::abs(renderedColor.z() - referenceColor.z()) < epsilon &&
		   de::abs(renderedColor.w() - referenceColor.w()) < epsilon;
}

glw::GLint ShaderViewportIndexTestCase::createMaxViewports()
{
	const Functions&		gl			 = m_context.getRenderContext().getFunctions();
	const tcu::RenderTarget renderTarget = m_context.getRenderContext().getRenderTarget();
	const GLfloat			targetWidth  = (GLfloat)renderTarget.getWidth();

	GLint maxViewports = 0;
	gl.getIntegerv(GL_MAX_VIEWPORTS, &maxViewports);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv error");

	const int				  viewportDataSize = 4; // x + y + w + h
	std::vector<glw::GLfloat> data(maxViewports * viewportDataSize);

	GLfloat viewportWidth  = 16.0f;
	GLfloat viewportHeight = 16.0f;

	int currentX = 0;
	int currentY = 0;
	for (GLint i = 0; i < maxViewports; ++i)
	{
		GLfloat x = (GLfloat)currentX * viewportWidth;
		if (x > (targetWidth - viewportWidth))
		{
			x		 = 0.0f;
			currentX = 0;
			currentY++;
		}
		GLfloat y = (GLfloat)currentY * viewportHeight;

		data[i * viewportDataSize + 0] = x;
		data[i * viewportDataSize + 1] = y;
		data[i * viewportDataSize + 2] = viewportWidth;
		data[i * viewportDataSize + 3] = viewportHeight;

		m_viewportData.push_back(tcu::Vec4(x, y, viewportWidth, viewportHeight));

		currentX++;
	}

	gl.viewportArrayv(0, maxViewports, data.data());
	GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");

	return maxViewports;
}

/** Constructor.
*
*  @param context Rendering context
*/
ShaderViewportIndexTestCase::ShaderViewportIndexTestCase(deqp::Context& context)
	: TestCase(context, "ShaderViewportIndexTestCase",
			   "Implements gl_ViewportIndex tests described in CTS_ARB_shader_viewport_layer_array")
	, m_maxViewports(0)
	, m_currentViewport(0)
{
	m_isExtensionSupported = context.getContextInfo().isExtensionSupported("GL_ARB_shader_viewport_layer_array");
}

void ShaderViewportIndexTestCase::init()
{
	if (!m_isExtensionSupported)
		return;

	m_maxViewports = this->createMaxViewports();

	m_shaderPipelines.push_back(
		ShaderViewportLayerArrayUtils::ShaderPipeline(false, false, m_maxViewports, "ViewportIndex"));
	m_shaderPipelines.push_back(
		ShaderViewportLayerArrayUtils::ShaderPipeline(true, false, m_maxViewports, "ViewportIndex"));
	m_shaderPipelines.push_back(
		ShaderViewportLayerArrayUtils::ShaderPipeline(true, true, m_maxViewports, "ViewportIndex"));

	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
	{
		iter->create(m_context.getRenderContext());
	}
}

void ShaderViewportIndexTestCase::deinit()
{
	const Functions&		gl			 = m_context.getRenderContext().getFunctions();
	const tcu::RenderTarget renderTarget = m_context.getRenderContext().getRenderTarget();

	gl.viewport(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
}

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

	const glw::Functions&	 gl			= m_context.getRenderContext().getFunctions();
	const glu::RenderContext& renderContext = m_context.getRenderContext();

	tcu::Vec4 renderColor((m_currentViewport + 1) / (float)m_maxViewports, 0.0f, 0.0f, 1.0f);
	tcu::Vec4 backgroundColor(0.0f, 0.0f, 0.0f, 1.0f);

	for (ShaderPipelineIter pipelineIter = m_shaderPipelines.begin(); pipelineIter != m_shaderPipelines.end();
		 ++pipelineIter)
	{
		// rendering

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
		gl.clear(GL_COLOR_BUFFER_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
		ShaderViewportLayerArrayUtils::renderQuad(renderContext, *pipelineIter, m_currentViewport, renderColor);
		gl.flush();
		GLU_EXPECT_NO_ERROR(gl.getError(), "Flush");

		// verification

		std::vector<std::pair<tcu::Vec2, tcu::Vec4> > expectedPixels;

		for (size_t i = 0; i < m_viewportData.size(); ++i)
		{
			tcu::Vec4 viewportData = m_viewportData[i];

			int currentViewportWithOffset =
				(m_currentViewport + pipelineIter->getViewportLayerOffset()) % m_maxViewports;

			tcu::Vec2 center(viewportData.x() + viewportData.z() * 0.5f, viewportData.y() + viewportData.w() * 0.5f);

			if (i == (unsigned int)currentViewportWithOffset)
			{
				expectedPixels.push_back(std::make_pair(center, renderColor));
			}
			else
			{
				expectedPixels.push_back(std::make_pair(center, backgroundColor));
			}
		}

		for (size_t i = 0; i < expectedPixels.size(); ++i)
		{
			glw::GLfloat rgba[4] = { -1.f, -1.f, -1.f, -1.f };
			gl.readPixels((glw::GLint)expectedPixels[i].first.x(), (glw::GLint)expectedPixels[i].first.y(), 1, 1,
						  GL_RGBA, GL_FLOAT, rgba);
			GLU_EXPECT_NO_ERROR(gl.getError(), "ReadPixels");
			bool validationResult = ShaderViewportLayerArrayUtils::validateColor(
				tcu::Vec4(rgba[0], rgba[1], rgba[2], rgba[3]), expectedPixels[i].second);
			TCU_CHECK_MSG(validationResult, "Expected pixel color did not match rendered one.");
		}
	}

	if (m_currentViewport < (m_maxViewports - 1))
	{
		m_currentViewport++;
		return CONTINUE;
	}

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

ShaderLayerFramebufferTestCaseBase::ShaderLayerFramebufferTestCaseBase(deqp::Context& context, const char* name,
																	   const char* description, bool layered)
	: TestCase(context, name, description)
	, m_layersNum(layered ? 4 : 1)
	, m_fboSize(512)
	, m_texture(0)
	, m_mainFbo(0)
	, m_currentLayer(0)
{
	m_isExtensionSupported = context.getContextInfo().isExtensionSupported("GL_ARB_shader_viewport_layer_array");
}

void ShaderLayerFramebufferTestCaseBase::init()
{
	if (!m_isExtensionSupported)
		return;

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

	this->createFBO();

	m_shaderPipelines.push_back(ShaderViewportLayerArrayUtils::ShaderPipeline(false, false, m_layersNum, "Layer"));
	m_shaderPipelines.push_back(ShaderViewportLayerArrayUtils::ShaderPipeline(true, false, m_layersNum, "Layer"));
	m_shaderPipelines.push_back(ShaderViewportLayerArrayUtils::ShaderPipeline(true, true, m_layersNum, "Layer"));

	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
	{
		iter->create(m_context.getRenderContext());
	}

	gl.viewport(0, 0, m_fboSize, m_fboSize);
}

void ShaderLayerFramebufferTestCaseBase::deinit()
{
	const Functions&		gl			 = m_context.getRenderContext().getFunctions();
	const tcu::RenderTarget renderTarget = m_context.getRenderContext().getRenderTarget();

	gl.viewport(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
}


tcu::TestNode::IterateResult ShaderLayerFramebufferTestCaseBase::iterate()
{
	if (!m_isExtensionSupported)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
		return STOP;
	}

	const glw::Functions&	 gl			= m_context.getRenderContext().getFunctions();
	const glu::RenderContext& renderContext = m_context.getRenderContext();

	tcu::Vec4 renderColor((m_currentLayer + 1) / (float)m_layersNum, 0.0f, 0.0f, 1.0f);

	for (ShaderPipelineIter pipelineIter = m_shaderPipelines.begin(); pipelineIter != m_shaderPipelines.end();
		 ++pipelineIter)
	{
		// bind main framebuffer (layered)
		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_mainFbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");

		// render
		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
		gl.clear(GL_COLOR_BUFFER_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
		ShaderViewportLayerArrayUtils::renderQuad(renderContext, *pipelineIter, m_currentLayer, renderColor);
		gl.flush();
		GLU_EXPECT_NO_ERROR(gl.getError(), "Flush");

		// calculate layer offset (same value as gl_Layer in shader)
		int currentLayerWithOffset = (m_currentLayer + pipelineIter->getViewportLayerOffset()) % m_layersNum;

		// bind framebuffer of this layer
		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbos[currentLayerWithOffset]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer() call failed.");

		// verification
		glw::GLfloat rgba[4] = { -1.f, -1.f, -1.f, -1.f };
		gl.readPixels(m_fboSize / 2, m_fboSize / 2, 1, 1, GL_RGBA, GL_FLOAT, rgba);
		GLU_EXPECT_NO_ERROR(gl.getError(), "ReadPixels");
		bool validationResult =
			ShaderViewportLayerArrayUtils::validateColor(tcu::Vec4(rgba[0], rgba[1], rgba[2], rgba[3]), renderColor);

		TCU_CHECK_MSG(validationResult, "Expected pixel color did not match rendered one.");
	}

	if (m_currentLayer < (m_layersNum - 1))
	{
		m_currentLayer++;
		return CONTINUE;
	}

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

/** Constructor.
*
*  @param context Rendering context
*/
ShaderLayerFramebufferLayeredTestCase::ShaderLayerFramebufferLayeredTestCase(deqp::Context& context)
	: ShaderLayerFramebufferTestCaseBase(
		  context, "ShaderLayerFramebufferLayeredTestCase",
		  "Implements gl_Layer tests for layered framebuffer described in CTS_ARB_shader_viewport_layer_array", true)
{
}

void ShaderLayerFramebufferLayeredTestCase::createFBO()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

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

	gl.bindTexture(GL_TEXTURE_3D, m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture() call failed.");

	gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, m_fboSize, m_fboSize, m_layersNum, 0, GL_RGBA, GL_FLOAT, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texImage3D() call failed.");

	// create main FBO

	gl.genFramebuffers(1, &m_mainFbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers() call failed.");
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_mainFbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer() call failed.");
	gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture() call failed.");

	// create FBO for each layer

	for (int i = 0; i < m_layersNum; ++i)
	{
		deUint32 layerFbo;

		gl.genFramebuffers(1, &layerFbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers() call failed.");
		gl.bindFramebuffer(GL_FRAMEBUFFER, layerFbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer() call failed.");
		gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0, i);
		GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTextureLayer() call failed.");

		m_fbos.push_back(layerFbo);
	}
}

void ShaderLayerFramebufferLayeredTestCase::deleteFBO()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.deleteFramebuffers(1, &m_mainFbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteFramebuffers");
	for (int i = 0; i < m_layersNum; ++i)
	{
		gl.deleteFramebuffers(1, &(m_fbos[i]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteFramebuffers");
	}
	gl.deleteTextures(1, &m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteTextures");
}

/** Constructor.
*
*  @param context Rendering context
*/
ShaderLayerFramebufferNonLayeredTestCase::ShaderLayerFramebufferNonLayeredTestCase(deqp::Context& context)
	: ShaderLayerFramebufferTestCaseBase(
		  context, "ShaderLayerFramebufferNonLayeredTestCase",
		  "Implements gl_Layer tests for non-layered framebuffer described in CTS_ARB_shader_viewport_layer_array",
		  false)
{
}

void ShaderLayerFramebufferNonLayeredTestCase::createFBO()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();
	deUint32		 tex;

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

	gl.bindTexture(GL_TEXTURE_2D, tex);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture() call failed.");

	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_fboSize, m_fboSize, 0, GL_RGBA, GL_FLOAT, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texImage2D() call failed.");

	// create main FBO

	gl.genFramebuffers(1, &m_mainFbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers() call failed.");
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_mainFbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer() call failed.");
	gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture() call failed.");

	// main FBO is only layer

	m_fbos.push_back(m_mainFbo);
}

void ShaderLayerFramebufferNonLayeredTestCase::deleteFBO()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.deleteFramebuffers(1, &m_mainFbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteFramebuffers");
	gl.deleteTextures(1, &m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteTextures");
}

/** Constructor.
 *
 *  @param context Rendering context.
 */
ShaderViewportLayerArray::ShaderViewportLayerArray(deqp::Context& context)
	: TestCaseGroup(context, "shader_viewport_layer_array",
					"Verify conformance of CTS_ARB_shader_viewport_layer_array implementation")
{
}

/** Initializes the test group contents. */
void ShaderViewportLayerArray::init()
{
	addChild(new ShaderViewportIndexTestCase(m_context));
	addChild(new ShaderLayerFramebufferLayeredTestCase(m_context));
	addChild(new ShaderLayerFramebufferNonLayeredTestCase(m_context));
}
} /* gl4cts namespace */
