/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2018 The Android Open Source Project
 *
 * 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 Multiview tests.
 * Tests functionality provided by the three multiview extensions.
 * Note that this file is formatted using external/openglcts/.clang-format
 */ /*--------------------------------------------------------------------*/

#include "es3fMultiviewTests.hpp"

#include "deString.h"
#include "deStringUtil.hpp"
#include "gluContextInfo.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "glw.h"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"

using tcu::TestLog;
using tcu::Vec4;

namespace deqp
{
namespace gles3
{
namespace Functional
{

static const int   NUM_CASE_ITERATIONS = 1;
static const float UNIT_SQUARE[16]	 = {
	1.0f,  1.0f,  0.05f, 1.0f, // Vertex 0
	1.0f,  -1.0f, 0.05f, 1.0f, // Vertex 1
	-1.0f, 1.0f,  0.05f, 1.0f, // Vertex 2
	-1.0f, -1.0f, 0.05f, 1.0f  // Vertex 3
};
static const float COLOR_VALUES[] = {
	1, 0, 0, 1, // Red for level 0
	0, 1, 0, 1, // Green for level 1
};

class MultiviewCase : public TestCase
{
public:
	MultiviewCase(Context& context, const char* name, const char* description, int numSamples);
	~MultiviewCase();
	void		  init();
	void		  deinit();
	IterateResult iterate();

private:
	MultiviewCase(const MultiviewCase& other);
	MultiviewCase& operator=(const MultiviewCase& other);
	void setupFramebufferObjects();
	void deleteFramebufferObjects();

	glu::ShaderProgram* m_multiviewProgram;
	deUint32			m_multiviewFbo;
	deUint32			m_arrayTexture;

	glu::ShaderProgram* m_finalProgram;

	int		  m_caseIndex;
	const int m_numSamples;
	const int m_width;
	const int m_height;
};

MultiviewCase::MultiviewCase(Context& context, const char* name, const char* description, int numSamples)
	: TestCase(context, name, description)
	, m_multiviewProgram(DE_NULL)
	, m_multiviewFbo(0)
	, m_arrayTexture(0)
	, m_finalProgram(DE_NULL)
	, m_caseIndex(0)
	, m_numSamples(numSamples)
	, m_width(512)
	, m_height(512)
{
}

MultiviewCase::~MultiviewCase()
{
	MultiviewCase::deinit();
}

void MultiviewCase::setupFramebufferObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// First create the array texture and multiview FBO.

	gl.genTextures(1, &m_arrayTexture);
	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_arrayTexture);
	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* num mipmaps */, GL_RGBA8, m_width / 2, m_height, 2 /* num levels */);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Create array texture");

	gl.genFramebuffers(1, &m_multiviewFbo);
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_multiviewFbo);
	if (m_numSamples == 1)
	{
		gl.framebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_arrayTexture, 0 /* mip level */,
										  0 /* base view index */, 2 /* num views */);
	}
	else
	{
		gl.framebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_arrayTexture,
													 0 /* mip level */, m_numSamples /* samples */,
													 0 /* base view index */, 2 /* num views */);
	}
	GLU_EXPECT_NO_ERROR(gl.getError(), "Create multiview FBO");
	deUint32 fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if (fboStatus == GL_FRAMEBUFFER_UNSUPPORTED)
	{
		throw tcu::NotSupportedError("Framebuffer unsupported", "", __FILE__, __LINE__);
	}
	else if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
	{
		throw tcu::TestError("Failed to create framebuffer object", "", __FILE__, __LINE__);
	}
}

void MultiviewCase::deleteFramebufferObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	gl.deleteTextures(1, &m_arrayTexture);
	gl.deleteFramebuffers(1, &m_multiviewFbo);
}

void MultiviewCase::init()
{
	const glu::ContextInfo& contextInfo = m_context.getContextInfo();
	bool					mvsupported = contextInfo.isExtensionSupported("GL_OVR_multiview");
	if (!mvsupported)
	{
		TCU_THROW(NotSupportedError, "Multiview is not supported");
	}

	if (m_numSamples > 1)
	{
		bool msaasupported = contextInfo.isExtensionSupported("GL_OVR_multiview_multisampled_render_to_texture");
		if (!msaasupported)
		{
			TCU_THROW(NotSupportedError, "Implicit MSAA multiview is not supported");
		}
	}

	const char* multiviewVertexShader = "#version 300 es\n"
										"#extension GL_OVR_multiview : enable\n"
										"layout(num_views=2) in;\n"
										"layout(location = 0) in mediump vec4 a_position;\n"
										"uniform mediump vec4 uColor[2];\n"
										"out mediump vec4 vColor;\n"
										"void main() {\n"
										"  vColor = uColor[gl_ViewID_OVR];\n"
										"  gl_Position = a_position;\n"
										"}\n";

	const char* multiviewFragmentShader = "#version 300 es\n"
										  "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
										  "in mediump vec4 vColor;\n"
										  "void main() {\n"
										  "  dEQP_FragColor = vColor;\n"
										  "}\n";

	m_multiviewProgram = new glu::ShaderProgram(
		m_context.getRenderContext(), glu::makeVtxFragSources(multiviewVertexShader, multiviewFragmentShader));
	DE_ASSERT(m_multiviewProgram);
	if (!m_multiviewProgram->isOk())
	{
		m_testCtx.getLog() << *m_multiviewProgram;
		TCU_FAIL("Failed to compile multiview shader");
	}

	// Draw the first layer on the left half of the screen and the second layer
	// on the right half.
	const char* finalVertexShader = "#version 300 es\n"
									"layout(location = 0) in mediump vec4 a_position;\n"
									"out highp vec3 vTexCoord;\n"
									"void main() {\n"
									"  vTexCoord.x = fract(a_position.x + 1.0);\n"
									"  vTexCoord.y = .5 * (a_position.y + 1.0);\n"
									"  vTexCoord.z = a_position.x;\n"
									"  gl_Position = a_position;\n"
									"}\n";

	const char* finalFragmentShader = "#version 300 es\n"
									  "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
									  "uniform lowp sampler2DArray uArrayTexture;\n"
									  "in highp vec3 vTexCoord;\n"
									  "void main() {\n"
									  "  highp vec3 uvw = vTexCoord;\n"
									  "  uvw.z = floor(vTexCoord.z + 1.0);\n"
									  "  dEQP_FragColor = texture(uArrayTexture, uvw);\n"
									  "}\n";

	m_finalProgram = new glu::ShaderProgram(m_context.getRenderContext(),
											glu::makeVtxFragSources(finalVertexShader, finalFragmentShader));
	DE_ASSERT(m_finalProgram);
	if (!m_finalProgram->isOk())
	{
		m_testCtx.getLog() << *m_finalProgram;
		TCU_FAIL("Failed to compile final shader");
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	GLU_CHECK_MSG("Case initialization finished");
}

void MultiviewCase::deinit()
{
	deleteFramebufferObjects();
	delete m_multiviewProgram;
	m_multiviewProgram = DE_NULL;
	delete m_finalProgram;
	m_finalProgram = DE_NULL;
}

MultiviewCase::IterateResult MultiviewCase::iterate()
{
	TestLog&	log			 = m_testCtx.getLog();
	deUint32	colorUniform = glGetUniformLocation(m_multiviewProgram->getProgram(), "uColor");
	std::string header = "Case iteration " + de::toString(m_caseIndex + 1) + " / " + de::toString(NUM_CASE_ITERATIONS);
	log << TestLog::Section(header, header);

	DE_ASSERT(m_multiviewProgram);

	// Create and bind the multiview FBO.

	try
	{
		setupFramebufferObjects();
	}
	catch (tcu::NotSupportedError& e)
	{
		log << TestLog::Message << "ERROR: " << e.what() << "." << TestLog::EndMessage << TestLog::EndSection;
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
		return STOP;
	}
	catch (tcu::InternalError& e)
	{
		log << TestLog::Message << "ERROR: " << e.what() << "." << TestLog::EndMessage << TestLog::EndSection;
		m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		return STOP;
	}

	log << TestLog::EndSection;

	// Draw full screen quad into the multiview framebuffer.
	// The quad should be instanced into both layers of the array texture.

	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_multiviewFbo);
	gl.viewport(0, 0, m_width / 2, m_height);
	gl.useProgram(m_multiviewProgram->getProgram());
	gl.uniform4fv(colorUniform, 2, COLOR_VALUES);
	gl.enableVertexAttribArray(0);
	gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, &UNIT_SQUARE[0]);
	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);

	// Sample from the array texture to draw a quad into the backbuffer.

	const int backbufferWidth  = m_context.getRenderTarget().getWidth();
	const int backbufferHeight = m_context.getRenderTarget().getHeight();
	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	gl.viewport(0, 0, backbufferWidth, backbufferHeight);
	gl.useProgram(m_finalProgram->getProgram());
	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_arrayTexture);
	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);

	// Read back the framebuffer, ensure that the left half is red and the
	// right half is green.

	tcu::Surface pixels(backbufferWidth, backbufferHeight);
	glu::readPixels(m_context.getRenderContext(), 0, 0, pixels.getAccess());
	bool failed = false;
	for (int y = 0; y < backbufferHeight; y++)
	{
		for (int x = 0; x < backbufferWidth; x++)
		{
			tcu::RGBA pixel = pixels.getPixel(x, y);
			if (x < backbufferWidth / 2)
			{
				if (pixel.getRed() != 255 || pixel.getGreen() != 0 || pixel.getBlue() != 0)
				{
					failed = true;
				}
			}
			else if (x > backbufferWidth / 2)
			{
				if (pixel.getRed() != 0 || pixel.getGreen() != 255 || pixel.getBlue() != 0)
				{
					failed = true;
				}
			}
			if (failed)
			{
				break;
			}
		}
	}

	deleteFramebufferObjects();

	if (failed)
	{
		log << TestLog::Image("Result image", "Result image", pixels);
	}

	log << TestLog::Message << "Test result: " << (failed ? "Failed!" : "Passed!") << TestLog::EndMessage;

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

	return (++m_caseIndex < NUM_CASE_ITERATIONS) ? CONTINUE : STOP;
}

MultiviewTests::MultiviewTests(Context& context) : TestCaseGroup(context, "multiview", "Multiview Tests")
{
}

MultiviewTests::~MultiviewTests()
{
}

void MultiviewTests::init()
{
	addChild(new MultiviewCase(m_context, "samples_1", "Multiview test without multisampling", 1));
	addChild(new MultiviewCase(m_context, "samples_2", "Multiview test with MSAAx2", 2));
	addChild(new MultiviewCase(m_context, "samples_4", "Multiview test without MSAAx4", 4));
}

} // namespace Functional
} // namespace gles3
} // namespace deqp
