/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 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 Multisample shader render case
 *//*--------------------------------------------------------------------*/

#include "es31fMultisampleShaderRenderCase.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuStringTemplate.hpp"
#include "gluContextInfo.hpp"
#include "gluShaderProgram.hpp"
#include "gluRenderContext.hpp"
#include "gluPixelTransfer.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deStringUtil.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace MultisampleShaderRenderUtil
{
using std::map;
using std::string;
namespace
{

static const char* const s_vertexSource =	"${GLSL_VERSION_DECL}\n"
											"in highp vec4 a_position;\n"
											"out highp vec4 v_position;\n"
											"void main (void)\n"
											"{\n"
											"	gl_Position = a_position;\n"
											"	v_position = a_position;\n"
											"}";

} // anonymous

QualityWarning::QualityWarning (const std::string& message)
	: tcu::Exception(message)
{
}

MultisampleRenderCase::MultisampleRenderCase (Context& context, const char* name, const char* desc, int numSamples, RenderTarget target, int renderSize, int flags)
	: TestCase						(context, name, desc)
	, m_numRequestedSamples			(numSamples)
	, m_renderTarget				(target)
	, m_renderSize					(renderSize)
	, m_perIterationShader			((flags & FLAG_PER_ITERATION_SHADER) != 0)
	, m_verifyTextureSampleBuffers	((flags & FLAG_VERIFY_MSAA_TEXTURE_SAMPLE_BUFFERS) != 0 && target == TARGET_TEXTURE)
	, m_numTargetSamples			(-1)
	, m_buffer						(0)
	, m_resolveBuffer				(0)
	, m_program						(DE_NULL)
	, m_fbo							(0)
	, m_fboTexture					(0)
	, m_textureSamplerProgram		(DE_NULL)
	, m_fboRbo						(0)
	, m_resolveFbo					(0)
	, m_resolveFboTexture			(0)
	, m_iteration					(0)
	, m_numIterations				(1)
	, m_renderMode					(0)
	, m_renderCount					(0)
	, m_renderVao					(0)
	, m_resolveVao					(0)
{
	DE_ASSERT(target < TARGET_LAST);
}

MultisampleRenderCase::~MultisampleRenderCase (void)
{
	MultisampleRenderCase::deinit();
}

void MultisampleRenderCase::init (void)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	deInt32					queriedSampleCount	= -1;
	const bool				supportsES32		= glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
	map<string, string>		args;

	args["GLSL_VERSION_DECL"] = supportsES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);

	// requirements

	switch (m_renderTarget)
	{
		case TARGET_DEFAULT:
		{
			if (m_context.getRenderTarget().getWidth() < m_renderSize || m_context.getRenderTarget().getHeight() < m_renderSize)
				throw tcu::NotSupportedError("Test requires render target with size " + de::toString(m_renderSize) + "x" + de::toString(m_renderSize) + " or greater");
			break;
		}

		case TARGET_TEXTURE:
		{
			deInt32 maxTextureSamples = getMaxConformantSampleCount(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8);
			if (m_numRequestedSamples > maxTextureSamples)
				throw tcu::NotSupportedError("Sample count not supported");
			break;
		}

		case TARGET_RENDERBUFFER:
		{
			deInt32 maxRboSamples = getMaxConformantSampleCount(GL_RENDERBUFFER, GL_RGBA8);
			if (m_numRequestedSamples > maxRboSamples)
				throw tcu::NotSupportedError("Sample count not supported");
			break;
		}

		default:
			DE_ASSERT(false);
	}

	// resources

	{
		gl.genBuffers(1, &m_buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");

		setupRenderData();
		GLU_EXPECT_NO_ERROR(gl.getError(), "setup data");

		gl.genVertexArrays(1, &m_renderVao);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen vao");

		// buffer for MSAA texture resolving
		{
			static const tcu::Vec4 fullscreenQuad[] =
			{
				tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
				tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
				tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
				tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
			};

			gl.genBuffers(1, &m_resolveBuffer);
			gl.bindBuffer(GL_ARRAY_BUFFER, m_resolveBuffer);
			gl.bufferData(GL_ARRAY_BUFFER, (int)sizeof(fullscreenQuad), fullscreenQuad, GL_STATIC_DRAW);
			GLU_EXPECT_NO_ERROR(gl.getError(), "setup data");
		}
	}

	// msaa targets

	if (m_renderTarget == TARGET_TEXTURE)
	{
		const deUint32 textureTarget = (m_numRequestedSamples == 0) ? (GL_TEXTURE_2D) : (GL_TEXTURE_2D_MULTISAMPLE);

		gl.genVertexArrays(1, &m_resolveVao);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen vao");

		gl.genTextures(1, &m_fboTexture);
		gl.bindTexture(textureTarget, m_fboTexture);
		if (m_numRequestedSamples == 0)
		{
			gl.texStorage2D(textureTarget, 1, GL_RGBA8, m_renderSize, m_renderSize);
			gl.texParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			gl.texParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		}
		else
			gl.texStorage2DMultisample(textureTarget, m_numRequestedSamples, GL_RGBA8, m_renderSize, m_renderSize, GL_FALSE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex");

		gl.genFramebuffers(1, &m_fbo);
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureTarget, m_fboTexture, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo");

		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
			throw tcu::TestError("fbo not complete");

		if (m_numRequestedSamples != 0)
		{
			// for shader
			gl.getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &queriedSampleCount);

			// logging
			m_testCtx.getLog() << tcu::TestLog::Message << "Asked for " << m_numRequestedSamples << " samples, got " << queriedSampleCount << " samples." << tcu::TestLog::EndMessage;

			// sanity
			if (queriedSampleCount < m_numRequestedSamples)
				throw tcu::TestError("Got less texture samples than asked for");
		}

		// texture sampler shader
		m_textureSamplerProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource(tcu::StringTemplate(s_vertexSource).specialize(args))
			<< glu::FragmentSource(genMSSamplerSource(queriedSampleCount)));
		if (!m_textureSamplerProgram->isOk())
		{
			m_testCtx.getLog() << tcu::TestLog::Section("SamplerShader", "Sampler shader") << *m_textureSamplerProgram << tcu::TestLog::EndSection;
			throw tcu::TestError("could not build program");
		}
	}
	else if (m_renderTarget == TARGET_RENDERBUFFER)
	{
		gl.genRenderbuffers(1, &m_fboRbo);
		gl.bindRenderbuffer(GL_RENDERBUFFER, m_fboRbo);
		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_numRequestedSamples, GL_RGBA8, m_renderSize, m_renderSize);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen rbo");

		gl.genFramebuffers(1, &m_fbo);
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_fboRbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo");

		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
			throw tcu::TestError("fbo not complete");

		// logging
		gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &queriedSampleCount);
		m_testCtx.getLog() << tcu::TestLog::Message << "Asked for " << m_numRequestedSamples << " samples, got " << queriedSampleCount << " samples." << tcu::TestLog::EndMessage;

		// sanity
		if (queriedSampleCount < m_numRequestedSamples)
			throw tcu::TestError("Got less renderbuffer samples samples than asked for");
	}

	// fbo for resolving the multisample fbo
	if (m_renderTarget != TARGET_DEFAULT)
	{
		gl.genTextures(1, &m_resolveFboTexture);
		gl.bindTexture(GL_TEXTURE_2D, m_resolveFboTexture);
		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, m_renderSize, m_renderSize);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex");

		gl.genFramebuffers(1, &m_resolveFbo);
		gl.bindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo);
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_resolveFboTexture, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo");

		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
			throw tcu::TestError("resolve fbo not complete");
	}

	// create verifier shader and set targetSampleCount

	{
		int realSampleCount = -1;

		if (m_renderTarget == TARGET_TEXTURE)
		{
			if (m_numRequestedSamples == 0)
				realSampleCount = 1; // non msaa texture
			else
				realSampleCount = de::max(1, queriedSampleCount); // msaa texture
		}
		else if (m_renderTarget == TARGET_RENDERBUFFER)
		{
			realSampleCount = de::max(1, queriedSampleCount); // msaa rbo
		}
		else if (m_renderTarget == TARGET_DEFAULT)
		{
			realSampleCount = de::max(1, m_context.getRenderTarget().getNumSamples());
		}
		else
			DE_ASSERT(DE_FALSE);

		// is set and is valid
		DE_ASSERT(realSampleCount != -1);
		DE_ASSERT(realSampleCount != 0);
		m_numTargetSamples = realSampleCount;
	}

	if (!m_perIterationShader)
	{
		m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource(m_numTargetSamples)) << glu::FragmentSource(genFragmentSource(m_numTargetSamples)));
		m_testCtx.getLog() << tcu::TestLog::Section("RenderShader", "Render shader") << *m_program << tcu::TestLog::EndSection;
		if (!m_program->isOk())
			throw tcu::TestError("could not build program");

	}
}

void MultisampleRenderCase::deinit (void)
{
	if (m_buffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffer);
		m_buffer = 0;
	}

	if (m_resolveBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_resolveBuffer);
		m_resolveBuffer = 0;
	}

	delete m_program;
	m_program = DE_NULL;

	if (m_fbo)
	{
		m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_fbo);
		m_fbo = 0;
	}

	if (m_fboTexture)
	{
		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_fboTexture);
		m_fboTexture = 0;
	}

	delete m_textureSamplerProgram;
	m_textureSamplerProgram = DE_NULL;

	if (m_fboRbo)
	{
		m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_fboRbo);
		m_fboRbo = 0;
	}

	if (m_resolveFbo)
	{
		m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_resolveFbo);
		m_resolveFbo = 0;
	}

	if (m_resolveFboTexture)
	{
		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_resolveFboTexture);
		m_resolveFboTexture = 0;
	}

	if (m_renderVao)
	{
		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_renderVao);
		m_renderVao = 0;
	}

	if (m_resolveVao)
	{
		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_resolveVao);
		m_resolveVao = 0;
	}
}

MultisampleRenderCase::IterateResult MultisampleRenderCase::iterate (void)
{
	// default value
	if (m_iteration == 0)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		preTest();
	}

	drawOneIteration();

	// next iteration
	++m_iteration;
	if (m_iteration < m_numIterations)
		return CONTINUE;
	else
	{
		postTest();
		return STOP;
	}
}

void MultisampleRenderCase::preDraw (void)
{
}

void MultisampleRenderCase::postDraw (void)
{
}

void MultisampleRenderCase::preTest (void)
{
}

void MultisampleRenderCase::postTest (void)
{
}

void MultisampleRenderCase::verifyResultImageAndSetResult (const tcu::Surface& resultImage)
{
	// verify using case-specific verification

	try
	{
		if (!verifyImage(resultImage))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
	}
	catch (const QualityWarning& ex)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Quality warning, error = " << ex.what() << tcu::TestLog::EndMessage;

		// Failures are more important than warnings
		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, ex.what());
	}
}

void MultisampleRenderCase::verifyResultBuffersAndSetResult (const std::vector<tcu::Surface>& resultBuffers)
{
	// verify using case-specific verification

	try
	{
		if (!verifySampleBuffers(resultBuffers))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
	}
	catch (const QualityWarning& ex)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Quality warning, error = " << ex.what() << tcu::TestLog::EndMessage;

		// Failures are more important than warnings
		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, ex.what());
	}
}

std::string	MultisampleRenderCase::getIterationDescription (int iteration) const
{
	DE_UNREF(iteration);
	DE_ASSERT(false);
	return "";
}

void MultisampleRenderCase::drawOneIteration (void)
{
	const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
	const std::string			sectionDescription	= (m_numIterations > 1) ? ("Iteration " + de::toString(m_iteration+1) + "/" + de::toString(m_numIterations) + ": " + getIterationDescription(m_iteration)) : ("Test");
	const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "Iteration" + de::toString(m_iteration), sectionDescription);

	// Per iteration shader?
	if (m_perIterationShader)
	{
		delete m_program;
		m_program = DE_NULL;

		m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
			<< glu::VertexSource(genVertexSource(m_numTargetSamples))
			<< glu::FragmentSource(genFragmentSource(m_numTargetSamples)));
		m_testCtx.getLog() << tcu::TestLog::Section("RenderShader", "Render shader") << *m_program << tcu::TestLog::EndSection;
		if (!m_program->isOk())
			throw tcu::TestError("could not build program");

	}

	// render
	{
		if (m_renderTarget == TARGET_TEXTURE || m_renderTarget == TARGET_RENDERBUFFER)
		{
			gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "bind fbo");

			m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << m_renderSceneDescription << " with render shader to fbo." << tcu::TestLog::EndMessage;
		}
		else
			m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << m_renderSceneDescription << " with render shader to default framebuffer." << tcu::TestLog::EndMessage;

		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.clear(GL_COLOR_BUFFER_BIT);
		gl.viewport(0, 0, m_renderSize, m_renderSize);
		GLU_EXPECT_NO_ERROR(gl.getError(), "clear");

		gl.bindVertexArray(m_renderVao);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer);

		// set attribs
		DE_ASSERT(!m_renderAttribs.empty());
		for (std::map<std::string, Attrib>::const_iterator it = m_renderAttribs.begin(); it != m_renderAttribs.end(); ++it)
		{
			const deInt32 location = gl.getAttribLocation(m_program->getProgram(), it->first.c_str());

			if (location != -1)
			{
				gl.vertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, it->second.stride, glu::BufferOffsetAsPointer(it->second.offset));
				gl.enableVertexAttribArray(location);
			}
		}
		GLU_EXPECT_NO_ERROR(gl.getError(), "set attrib");

		gl.useProgram(m_program->getProgram());
		preDraw();
		gl.drawArrays(m_renderMode, 0, m_renderCount);
		postDraw();
		gl.useProgram(0);
		gl.bindVertexArray(0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "draw");

		if (m_renderTarget == TARGET_TEXTURE || m_renderTarget == TARGET_RENDERBUFFER)
			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	}

	// read
	{
		if (m_renderTarget == TARGET_DEFAULT)
		{
			tcu::Surface resultImage(m_renderSize, m_renderSize);

			m_testCtx.getLog() << tcu::TestLog::Message << "Reading pixels from default framebuffer." << tcu::TestLog::EndMessage;

			// default directly
			glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");

			// set test result
			verifyResultImageAndSetResult(resultImage);
		}
		else if (m_renderTarget == TARGET_RENDERBUFFER)
		{
			tcu::Surface resultImage(m_renderSize, m_renderSize);

			// rbo by blitting to non-multisample fbo

			m_testCtx.getLog() << tcu::TestLog::Message << "Blitting result from fbo to single sample fbo. (Resolve multisample)" << tcu::TestLog::EndMessage;

			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolveFbo);
			gl.blitFramebuffer(0, 0, m_renderSize, m_renderSize, 0, 0, m_renderSize, m_renderSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
			GLU_EXPECT_NO_ERROR(gl.getError(), "blit resolve");

			m_testCtx.getLog() << tcu::TestLog::Message << "Reading pixels from single sample framebuffer." << tcu::TestLog::EndMessage;

			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_resolveFbo);
			glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");

			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);

			// set test result
			verifyResultImageAndSetResult(resultImage);
		}
		else if (m_renderTarget == TARGET_TEXTURE && !m_verifyTextureSampleBuffers)
		{
			const deInt32	posLocation		= gl.getAttribLocation(m_textureSamplerProgram->getProgram(), "a_position");
			const deInt32	samplerLocation	= gl.getUniformLocation(m_textureSamplerProgram->getProgram(), "u_sampler");
			const deUint32	textureTarget	= (m_numRequestedSamples == 0) ? (GL_TEXTURE_2D) : (GL_TEXTURE_2D_MULTISAMPLE);
			tcu::Surface	resultImage		(m_renderSize, m_renderSize);

			if (m_numRequestedSamples)
				m_testCtx.getLog() << tcu::TestLog::Message << "Using sampler shader to sample the multisample texture to single sample framebuffer." << tcu::TestLog::EndMessage;
			else
				m_testCtx.getLog() << tcu::TestLog::Message << "Drawing texture to single sample framebuffer. Using sampler shader." << tcu::TestLog::EndMessage;

			if (samplerLocation == -1)
				throw tcu::TestError("Location u_sampler was -1.");

			// resolve multisample texture by averaging
			gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
			gl.clear(GL_COLOR_BUFFER_BIT);
			gl.viewport(0, 0, m_renderSize, m_renderSize);
			GLU_EXPECT_NO_ERROR(gl.getError(), "clear");

			gl.bindVertexArray(m_resolveVao);
			gl.bindBuffer(GL_ARRAY_BUFFER, m_resolveBuffer);
			gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
			gl.enableVertexAttribArray(posLocation);
			GLU_EXPECT_NO_ERROR(gl.getError(), "set attrib");

			gl.activeTexture(GL_TEXTURE0);
			gl.bindTexture(textureTarget, m_fboTexture);
			GLU_EXPECT_NO_ERROR(gl.getError(), "bind tex");

			gl.useProgram(m_textureSamplerProgram->getProgram());
			gl.uniform1i(samplerLocation, 0);

			gl.bindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo);
			gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);

			gl.useProgram(0);
			gl.bindVertexArray(0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "draw");

			m_testCtx.getLog() << tcu::TestLog::Message << "Reading pixels from single sample framebuffer." << tcu::TestLog::EndMessage;

			glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");

			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);

			// set test result
			verifyResultImageAndSetResult(resultImage);
		}
		else if (m_renderTarget == TARGET_TEXTURE && m_verifyTextureSampleBuffers)
		{
			const deInt32				posLocation		= gl.getAttribLocation(m_textureSamplerProgram->getProgram(), "a_position");
			const deInt32				samplerLocation	= gl.getUniformLocation(m_textureSamplerProgram->getProgram(), "u_sampler");
			const deInt32				sampleLocation	= gl.getUniformLocation(m_textureSamplerProgram->getProgram(), "u_sampleNdx");
			const deUint32				textureTarget	= (m_numRequestedSamples == 0) ? (GL_TEXTURE_2D) : (GL_TEXTURE_2D_MULTISAMPLE);
			std::vector<tcu::Surface>	resultBuffers	(m_numTargetSamples);

			if (m_numRequestedSamples)
				m_testCtx.getLog() << tcu::TestLog::Message << "Reading multisample texture sample buffers." << tcu::TestLog::EndMessage;
			else
				m_testCtx.getLog() << tcu::TestLog::Message << "Reading texture." << tcu::TestLog::EndMessage;

			if (samplerLocation == -1)
				throw tcu::TestError("Location u_sampler was -1.");
			if (sampleLocation == -1)
				throw tcu::TestError("Location u_sampleNdx was -1.");

			for (int sampleNdx = 0; sampleNdx < m_numTargetSamples; ++sampleNdx)
				resultBuffers[sampleNdx].setSize(m_renderSize, m_renderSize);

			// read sample buffers to different surfaces
			gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
			gl.clear(GL_COLOR_BUFFER_BIT);
			gl.viewport(0, 0, m_renderSize, m_renderSize);
			GLU_EXPECT_NO_ERROR(gl.getError(), "clear");

			gl.bindVertexArray(m_resolveVao);
			gl.bindBuffer(GL_ARRAY_BUFFER, m_resolveBuffer);
			gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
			gl.enableVertexAttribArray(posLocation);
			GLU_EXPECT_NO_ERROR(gl.getError(), "set attrib");

			gl.activeTexture(GL_TEXTURE0);
			gl.bindTexture(textureTarget, m_fboTexture);
			GLU_EXPECT_NO_ERROR(gl.getError(), "bind tex");

			gl.bindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo);
			gl.useProgram(m_textureSamplerProgram->getProgram());
			gl.uniform1i(samplerLocation, 0);

			m_testCtx.getLog() << tcu::TestLog::Message << "Reading sample buffers" << tcu::TestLog::EndMessage;

			for (int sampleNdx = 0; sampleNdx < m_numTargetSamples; ++sampleNdx)
			{
				gl.uniform1i(sampleLocation, sampleNdx);
				gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
				GLU_EXPECT_NO_ERROR(gl.getError(), "draw");

				glu::readPixels(m_context.getRenderContext(), 0, 0, resultBuffers[sampleNdx].getAccess());
				GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
			}

			gl.useProgram(0);
			gl.bindVertexArray(0);
			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);

			// verify sample buffers
			verifyResultBuffersAndSetResult(resultBuffers);
		}
		else
			DE_ASSERT(false);
	}
}

std::string	MultisampleRenderCase::genVertexSource (int numTargetSamples) const
{
	const bool supportsES32orGL45 =
		glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
		glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));

	map<string, string>		args;

	args["GLSL_VERSION_DECL"] = supportsES32orGL45 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);

	DE_UNREF(numTargetSamples);
	return std::string(tcu::StringTemplate(s_vertexSource).specialize(args));
}

std::string MultisampleRenderCase::genMSSamplerSource (int numTargetSamples) const
{
	if (m_verifyTextureSampleBuffers)
		return genMSTextureLayerFetchSource(numTargetSamples);
	else
		return genMSTextureResolverSource(numTargetSamples);
}

std::string	MultisampleRenderCase::genMSTextureResolverSource (int numTargetSamples) const
{
	// default behavior: average

	const bool				supportsES32			= glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
	map<string, string>		args;
	const bool				isSingleSampleTarget	= (m_numRequestedSamples == 0);
	std::ostringstream		buf;

	args["GLSL_VERSION_DECL"] = supportsES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in mediump vec4 v_position;\n"
			"layout(location = 0) out mediump vec4 fragColor;\n"
			"uniform mediump " << ((isSingleSampleTarget) ? ("sampler2D") : ("sampler2DMS")) << " u_sampler;\n"
			"void main (void)\n"
			"{\n"
			"	mediump vec2 relPosition = (v_position.xy + vec2(1.0, 1.0)) / 2.0;\n"
			"	mediump ivec2 fetchPos = ivec2(floor(relPosition * " << m_renderSize << ".0));\n"
			"	mediump vec4 colorSum = vec4(0.0, 0.0, 0.0, 0.0);\n"
			"\n";

	if (isSingleSampleTarget)
		buf <<	"	colorSum = texelFetch(u_sampler, fetchPos, 0);\n"
				"\n";
	else
		buf <<	"	for (int sampleNdx = 0; sampleNdx < " << numTargetSamples << "; ++sampleNdx)\n"
				"		colorSum += texelFetch(u_sampler, fetchPos, sampleNdx);\n"
				"	colorSum /= " << numTargetSamples << ".0;\n"
				"\n";

	buf <<	"	fragColor = vec4(colorSum.xyz, 1.0);\n"
			"}\n";

	return tcu::StringTemplate(buf.str()).specialize(args);
}

std::string MultisampleRenderCase::genMSTextureLayerFetchSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	const bool				supportsES32			= glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
	map<string, string>		args;
	const bool				isSingleSampleTarget	= (m_numRequestedSamples == 0);
	std::ostringstream		buf;

	args["GLSL_VERSION_DECL"] = supportsES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in mediump vec4 v_position;\n"
			"layout(location = 0) out mediump vec4 fragColor;\n"
			"uniform mediump " << ((isSingleSampleTarget) ? ("sampler2D") : ("sampler2DMS")) << " u_sampler;\n"
			"uniform mediump int u_sampleNdx;\n"
			"void main (void)\n"
			"{\n"
			"	mediump vec2 relPosition = (v_position.xy + vec2(1.0, 1.0)) / 2.0;\n"
			"	mediump ivec2 fetchPos = ivec2(floor(relPosition * " << m_renderSize << ".0));\n"
			"\n"
			"	mediump vec4 color = texelFetch(u_sampler, fetchPos, u_sampleNdx);\n"
			"	fragColor = vec4(color.rgb, 1.0);\n"
			"}\n";

	return tcu::StringTemplate(buf.str()).specialize(args);
}

bool MultisampleRenderCase::verifySampleBuffers (const std::vector<tcu::Surface>& resultBuffers)
{
	DE_UNREF(resultBuffers);
	DE_ASSERT(false);
	return false;
}

void MultisampleRenderCase::setupRenderData (void)
{
	static const tcu::Vec4 fullscreenQuad[] =
	{
		tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
		tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
	};

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

	m_renderMode = GL_TRIANGLE_STRIP;
	m_renderCount = 4;
	m_renderSceneDescription = "quad";

	m_renderAttribs["a_position"].offset = 0;
	m_renderAttribs["a_position"].stride = sizeof(float[4]);

	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer);
	gl.bufferData(GL_ARRAY_BUFFER, (int)sizeof(fullscreenQuad), fullscreenQuad, GL_STATIC_DRAW);
}

glw::GLint MultisampleRenderCase::getMaxConformantSampleCount(glw::GLenum target, glw::GLenum internalFormat)
{
	deInt32					maxTextureSamples	= 0;
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();

	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 first 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] > maxTextureSamples)
				{
					maxTextureSamples = gl_supported_samples[i];
				}
			}
			delete[] gl_supported_samples;
		}
	}
	else
	{
		gl.getInternalformativ(target, internalFormat, GL_SAMPLES, 1, &maxTextureSamples);
	}

	return maxTextureSamples;
}

} // MultisampleShaderRenderUtil
} // Functional
} // gles31
} // deqp
