/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 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 FBO depthbuffer tests.
 *//*--------------------------------------------------------------------*/

#include "es3fFboDepthbufferTests.hpp"
#include "es3fFboTestCase.hpp"
#include "es3fFboTestUtil.hpp"
#include "gluTextureUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "sglrContextUtil.hpp"
#include "glwEnums.hpp"

namespace deqp
{
namespace gles3
{
namespace Functional
{

using std::string;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec2;
using tcu::IVec3;
using tcu::IVec4;
using tcu::UVec4;
using namespace FboTestUtil;

class BasicFboDepthCase : public FboTestCase
{
public:
	BasicFboDepthCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
		: FboTestCase	(context, name, desc)
		, m_format		(format)
		, m_width		(width)
		, m_height		(height)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		const deUint32	colorFormat		= GL_RGBA8;
		deUint32		fbo				= 0;
		deUint32		colorRbo		= 0;
		deUint32		depthRbo		= 0;
		GradientShader	gradShader		(glu::TYPE_FLOAT_VEC4);
		Texture2DShader	texShader		(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
		deUint32		gradShaderID	= getCurrentContext()->createProgram(&gradShader);
		deUint32		texShaderID		= getCurrentContext()->createProgram(&texShader);
		float			clearDepth		= 1.0f;

		// Setup shaders
		gradShader.setGradient(*getCurrentContext(), gradShaderID, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
		texShader.setUniforms (*getCurrentContext(), texShaderID);

		// Setup FBO

		glGenFramebuffers(1, &fbo);
		glGenRenderbuffers(1, &colorRbo);
		glGenRenderbuffers(1, &depthRbo);

		glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
		glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);

		glBindRenderbuffer(GL_RENDERBUFFER, depthRbo);
		glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_width, m_height);

		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRbo);
		checkError();
		checkFramebufferStatus(GL_FRAMEBUFFER);

		glViewport(0, 0, m_width, m_height);

		// Clear depth to 1
		glClearBufferfv(GL_DEPTH, 0, &clearDepth);

		// Render gradient with depth = [-1..1]
		glEnable(GL_DEPTH_TEST);
		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		// Render grid pattern with depth = 0
		{
			const deUint32		format		= GL_RGBA;
			const deUint32		dataType	= GL_UNSIGNED_BYTE;
			const int			texW		= 128;
			const int			texH		= 128;
			deUint32			gridTex		= 0;
			tcu::TextureLevel	data		(glu::mapGLTransferFormat(format, dataType), texW, texH, 1);

			tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f));

			glGenTextures(1, &gridTex);
			glBindTexture(GL_TEXTURE_2D, gridTex);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());

			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}

		// Read results.
		readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
	}

private:
	deUint32		m_format;
	int				m_width;
	int				m_height;
};

class DepthWriteClampCase : public FboTestCase
{
public:
	DepthWriteClampCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
		: FboTestCase	(context, name, desc)
		, m_format		(format)
		, m_width		(width)
		, m_height		(height)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		const deUint32			colorFormat			= GL_RGBA8;
		deUint32				fbo					= 0;
		deUint32				colorRbo			= 0;
		deUint32				depthTexture		= 0;
		glu::TransferFormat		transferFmt			= glu::getTransferFormat(glu::mapGLInternalFormat(m_format));

		DepthGradientShader		depthGradShader		(glu::TYPE_FLOAT_VEC4);
		const deUint32			depthGradShaderID	= getCurrentContext()->createProgram(&depthGradShader);
		const float				clearDepth			= 1.0f;
		const tcu::Vec4			red					(1.0, 0.0, 0.0, 1.0);
		const tcu::Vec4			green				(0.0, 1.0, 0.0, 1.0);

		// Setup FBO

		glGenFramebuffers(1, &fbo);
		glGenRenderbuffers(1, &colorRbo);
		glGenTextures(1, &depthTexture);

		glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
		glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);

		glBindTexture(GL_TEXTURE_2D, depthTexture);
		glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
		checkError();
		checkFramebufferStatus(GL_FRAMEBUFFER);

		glViewport(0, 0, m_width, m_height);

		// Clear depth to 1
		glClearBufferfv(GL_DEPTH, 0, &clearDepth);

		// Test that invalid values are not written to the depth buffer

		// Render green quad, depth gradient = [-1..2]
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_ALWAYS);

		depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -1.0f, 2.0f, green);
		sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
		glDepthMask(GL_FALSE);

		// Test if any fragment has greater depth than 1; there should be none
		glDepthFunc(GL_LESS); // (1 < depth) ?
		depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, 1.0f, 1.0f, red);
		sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		// Test if any fragment has smaller depth than 0; there should be none
		glDepthFunc(GL_GREATER); // (0 > depth) ?
		depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, 0.0f, 0.0f, red);
		sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		// Read results.
		readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
	}

private:
	const deUint32		m_format;
	const int			m_width;
	const int			m_height;
};

class DepthTestClampCase : public FboTestCase
{
public:
	DepthTestClampCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
		: FboTestCase	(context, name, desc)
		, m_format		(format)
		, m_width		(width)
		, m_height		(height)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		const deUint32			colorFormat			= GL_RGBA8;
		deUint32				fbo					= 0;
		deUint32				colorRbo			= 0;
		deUint32				depthTexture		= 0;
		glu::TransferFormat		transferFmt			= glu::getTransferFormat(glu::mapGLInternalFormat(m_format));

		DepthGradientShader		depthGradShader		(glu::TYPE_FLOAT_VEC4);
		const deUint32			depthGradShaderID	= getCurrentContext()->createProgram(&depthGradShader);
		const float				clearDepth			= 1.0f;
		const tcu::Vec4			yellow				(1.0, 1.0, 0.0, 1.0);
		const tcu::Vec4			green				(0.0, 1.0, 0.0, 1.0);

		// Setup FBO

		glGenFramebuffers(1, &fbo);
		glGenRenderbuffers(1, &colorRbo);
		glGenTextures(1, &depthTexture);

		glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
		glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);

		glBindTexture(GL_TEXTURE_2D, depthTexture);
		glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
		checkError();
		checkFramebufferStatus(GL_FRAMEBUFFER);

		glViewport(0, 0, m_width, m_height);

		// Clear depth to 1
		glClearBufferfv(GL_DEPTH, 0, &clearDepth);

		// Test values used in depth test are clamped

		// Render green quad, depth gradient = [-1..2]
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_ALWAYS);

		depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -1.0f, 2.0f, green);
		sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		// Render yellow quad, depth gradient = [-0.5..3]. Gradients have equal values only outside [0, 1] range due to clamping
		glDepthFunc(GL_EQUAL);
		depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -0.5f, 3.0f, yellow);
		sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		// Read results.
		readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
	}

private:
	const deUint32		m_format;
	const int			m_width;
	const int			m_height;
};

FboDepthTests::FboDepthTests (Context& context)
	: TestCaseGroup(context, "depth", "Depth tests")
{
}

FboDepthTests::~FboDepthTests (void)
{
}

void FboDepthTests::init (void)
{
	static const deUint32 depthFormats[] =
	{
		GL_DEPTH_COMPONENT32F,
		GL_DEPTH_COMPONENT24,
		GL_DEPTH_COMPONENT16,
		GL_DEPTH32F_STENCIL8,
		GL_DEPTH24_STENCIL8
	};

	// .basic
	{
		tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic depth tests");
		addChild(basicGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
			basicGroup->addChild(new BasicFboDepthCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127));
	}

	// .depth_write_clamp
	{
		tcu::TestCaseGroup* depthClampGroup = new tcu::TestCaseGroup(m_testCtx, "depth_write_clamp", "Depth write clamping tests");
		addChild(depthClampGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
			depthClampGroup->addChild(new DepthWriteClampCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127));
	}

	// .depth_test_clamp
	{
		tcu::TestCaseGroup* depthClampGroup = new tcu::TestCaseGroup(m_testCtx, "depth_test_clamp", "Depth test value clamping tests");
		addChild(depthClampGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
			depthClampGroup->addChild(new DepthTestClampCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127));
	}
}

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