13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Multisample shader render case
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fMultisampleShaderRenderCase.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace MultisampleShaderRenderUtil
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_vertexSource =	"#version 310 es\n"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											"in highp vec4 a_position;\n"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											"out highp vec4 v_position;\n"
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											"void main (void)\n"
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											"{\n"
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											"	gl_Position = a_position;\n"
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											"	v_position = a_position;\n"
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											"}";
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryQualityWarning::QualityWarning (const std::string& message)
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: tcu::Exception(message)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleRenderCase::MultisampleRenderCase (Context& context, const char* name, const char* desc, int numSamples, RenderTarget target, int renderSize, int flags)
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase						(context, name, desc)
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numRequestedSamples			(numSamples)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderTarget				(target)
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderSize					(renderSize)
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_perIterationShader			((flags & FLAG_PER_ITERATION_SHADER) != 0)
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_verifyTextureSampleBuffers	((flags & FLAG_VERIFY_MSAA_TEXTURE_SAMPLE_BUFFERS) != 0 && target == TARGET_TEXTURE)
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numTargetSamples			(-1)
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_buffer						(0)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_resolveBuffer				(0)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program						(DE_NULL)
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fbo							(0)
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fboTexture					(0)
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureSamplerProgram		(DE_NULL)
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fboRbo						(0)
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_resolveFbo					(0)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_resolveFboTexture			(0)
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_iteration					(0)
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numIterations				(1)
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderMode					(0)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCount					(0)
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderVao					(0)
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_resolveVao					(0)
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(target < TARGET_LAST);
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
893c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleRenderCase::~MultisampleRenderCase (void)
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MultisampleRenderCase::deinit();
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::init (void)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32					queriedSampleCount	= -1;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// requirements
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_renderTarget)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TARGET_DEFAULT:
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_context.getRenderTarget().getWidth() < m_renderSize || m_context.getRenderTarget().getHeight() < m_renderSize)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("Test requires render target with size " + de::toString(m_renderSize) + "x" + de::toString(m_renderSize) + " or greater");
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TARGET_TEXTURE:
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deInt32 maxTextureSamples = 0;
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, 1, &maxTextureSamples);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_numRequestedSamples > maxTextureSamples)
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("Sample count not supported");
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TARGET_RENDERBUFFER:
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deInt32 maxRboSamples = 0;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.getInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &maxRboSamples);
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_numRequestedSamples > maxRboSamples)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("Sample count not supported");
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// resources
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &m_buffer);
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setupRenderData();
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "setup data");
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genVertexArrays(1, &m_renderVao);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen vao");
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// buffer for MSAA texture resolving
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const tcu::Vec4 fullscreenQuad[] =
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genBuffers(1, &m_resolveBuffer);
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, m_resolveBuffer);
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bufferData(GL_ARRAY_BUFFER, (int)sizeof(fullscreenQuad), fullscreenQuad, GL_STATIC_DRAW);
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "setup data");
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// msaa targets
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_renderTarget == TARGET_TEXTURE)
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32 textureTarget = (m_numRequestedSamples == 0) ? (GL_TEXTURE_2D) : (GL_TEXTURE_2D_MULTISAMPLE);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genVertexArrays(1, &m_resolveVao);
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen vao");
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genTextures(1, &m_fboTexture);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(textureTarget, m_fboTexture);
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_numRequestedSamples == 0)
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texStorage2D(textureTarget, 1, GL_RGBA8, m_renderSize, m_renderSize);
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texStorage2DMultisample(textureTarget, m_numRequestedSamples, GL_RGBA8, m_renderSize, m_renderSize, GL_FALSE);
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex");
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genFramebuffers(1, &m_fbo);
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureTarget, m_fboTexture, 0);
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo");
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("fbo not complete");
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_numRequestedSamples != 0)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// for shader
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &queriedSampleCount);
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// logging
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Asked for " << m_numRequestedSamples << " samples, got " << queriedSampleCount << " samples." << tcu::TestLog::EndMessage;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// sanity
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (queriedSampleCount < m_numRequestedSamples)
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::TestError("Got less texture samples than asked for");
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// texture sampler shader
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureSamplerProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_vertexSource) << glu::FragmentSource(genMSSamplerSource(queriedSampleCount)));
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_textureSamplerProgram->isOk())
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Section("SamplerShader", "Sampler shader") << *m_textureSamplerProgram << tcu::TestLog::EndSection;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("could not build program");
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_renderTarget == TARGET_RENDERBUFFER)
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genRenderbuffers(1, &m_fboRbo);
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, m_fboRbo);
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_numRequestedSamples, GL_RGBA8, m_renderSize, m_renderSize);
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen rbo");
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genFramebuffers(1, &m_fbo);
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_fboRbo);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo");
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("fbo not complete");
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// logging
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &queriedSampleCount);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Asked for " << m_numRequestedSamples << " samples, got " << queriedSampleCount << " samples." << tcu::TestLog::EndMessage;
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// sanity
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (queriedSampleCount < m_numRequestedSamples)
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Got less renderbuffer samples samples than asked for");
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// fbo for resolving the multisample fbo
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_renderTarget != TARGET_DEFAULT)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genTextures(1, &m_resolveFboTexture);
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(GL_TEXTURE_2D, m_resolveFboTexture);
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, m_renderSize, m_renderSize);
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex");
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genFramebuffers(1, &m_resolveFbo);
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo);
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_resolveFboTexture, 0);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo");
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("resolve fbo not complete");
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// create verifier shader and set targetSampleCount
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int realSampleCount = -1;
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_renderTarget == TARGET_TEXTURE)
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_numRequestedSamples == 0)
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				realSampleCount = 1; // non msaa texture
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				realSampleCount = de::max(1, queriedSampleCount); // msaa texture
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_renderTarget == TARGET_RENDERBUFFER)
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			realSampleCount = de::max(1, queriedSampleCount); // msaa rbo
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_renderTarget == TARGET_DEFAULT)
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			realSampleCount = de::max(1, m_context.getRenderTarget().getNumSamples());
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// is set and is valid
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(realSampleCount != -1);
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(realSampleCount != 0);
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_numTargetSamples = realSampleCount;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_perIterationShader)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource(m_numTargetSamples)) << glu::FragmentSource(genFragmentSource(m_numTargetSamples)));
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Section("RenderShader", "Render shader") << *m_program << tcu::TestLog::EndSection;
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_program->isOk())
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("could not build program");
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::deinit (void)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_buffer)
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffer);
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffer = 0;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_resolveBuffer)
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_resolveBuffer);
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_resolveBuffer = 0;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fbo)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_fbo);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fbo = 0;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fboTexture)
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_fboTexture);
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fboTexture = 0;
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_textureSamplerProgram;
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textureSamplerProgram = DE_NULL;
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fboRbo)
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_fboRbo);
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fboRbo = 0;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_resolveFbo)
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_resolveFbo);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_resolveFbo = 0;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_resolveFboTexture)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_resolveFboTexture);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_resolveFboTexture = 0;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_renderVao)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_renderVao);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderVao = 0;
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_resolveVao)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_resolveVao);
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_resolveVao = 0;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleRenderCase::IterateResult MultisampleRenderCase::iterate (void)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// default value
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_iteration == 0)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		preTest();
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawOneIteration();
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// next iteration
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	++m_iteration;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_iteration < m_numIterations)
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTINUE;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		postTest();
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::preDraw (void)
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::postDraw (void)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::preTest (void)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::postTest (void)
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::verifyResultImageAndSetResult (const tcu::Surface& resultImage)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify using case-specific verification
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!verifyImage(resultImage))
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const QualityWarning& ex)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Quality warning, error = " << ex.what() << tcu::TestLog::EndMessage;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Failures are more important than warnings
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, ex.what());
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::verifyResultBuffersAndSetResult (const std::vector<tcu::Surface>& resultBuffers)
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify using case-specific verification
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!verifySampleBuffers(resultBuffers))
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const QualityWarning& ex)
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Quality warning, error = " << ex.what() << tcu::TestLog::EndMessage;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Failures are more important than warnings
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, ex.what());
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string	MultisampleRenderCase::getIterationDescription (int iteration) const
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(iteration);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return "";
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::drawOneIteration (void)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string			sectionDescription	= (m_numIterations > 1) ? ("Iteration " + de::toString(m_iteration+1) + "/" + de::toString(m_numIterations) + ": " + getIterationDescription(m_iteration)) : ("Test");
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "Iteration" + de::toString(m_iteration), sectionDescription);
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Per iteration shader?
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_perIterationShader)
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_program;
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = DE_NULL;
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource(m_numTargetSamples)) << glu::FragmentSource(genFragmentSource(m_numTargetSamples)));
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Section("RenderShader", "Render shader") << *m_program << tcu::TestLog::EndSection;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_program->isOk())
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("could not build program");
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_renderTarget == TARGET_TEXTURE || m_renderTarget == TARGET_RENDERBUFFER)
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "bind fbo");
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << m_renderSceneDescription << " with render shader to fbo." << tcu::TestLog::EndMessage;
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << m_renderSceneDescription << " with render shader to default framebuffer." << tcu::TestLog::EndMessage;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(0, 0, m_renderSize, m_renderSize);
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindVertexArray(m_renderVao);
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer);
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// set attribs
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!m_renderAttribs.empty());
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (std::map<std::string, Attrib>::const_iterator it = m_renderAttribs.begin(); it != m_renderAttribs.end(); ++it)
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32 location = gl.getAttribLocation(m_program->getProgram(), it->first.c_str());
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (location != -1)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.vertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, it->second.stride, (deUint8*)DE_NULL + it->second.offset);
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.enableVertexAttribArray(location);
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "set attrib");
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_program->getProgram());
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		preDraw();
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawArrays(m_renderMode, 0, m_renderCount);
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		postDraw();
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(0);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindVertexArray(0);
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_renderTarget == TARGET_TEXTURE || m_renderTarget == TARGET_RENDERBUFFER)
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// read
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_renderTarget == TARGET_DEFAULT)
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Surface resultImage(m_renderSize, m_renderSize);
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Reading pixels from default framebuffer." << tcu::TestLog::EndMessage;
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// default directly
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// set test result
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verifyResultImageAndSetResult(resultImage);
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_renderTarget == TARGET_RENDERBUFFER)
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Surface resultImage(m_renderSize, m_renderSize);
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// rbo by blitting to non-multisample fbo
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Blitting result from fbo to single sample fbo. (Resolve multisample)" << tcu::TestLog::EndMessage;
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolveFbo);
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.blitFramebuffer(0, 0, m_renderSize, m_renderSize, 0, 0, m_renderSize, m_renderSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "blit resolve");
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Reading pixels from single sample framebuffer." << tcu::TestLog::EndMessage;
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_resolveFbo);
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// set test result
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verifyResultImageAndSetResult(resultImage);
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_renderTarget == TARGET_TEXTURE && !m_verifyTextureSampleBuffers)
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	posLocation		= gl.getAttribLocation(m_textureSamplerProgram->getProgram(), "a_position");
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	samplerLocation	= gl.getUniformLocation(m_textureSamplerProgram->getProgram(), "u_sampler");
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	textureTarget	= (m_numRequestedSamples == 0) ? (GL_TEXTURE_2D) : (GL_TEXTURE_2D_MULTISAMPLE);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Surface	resultImage		(m_renderSize, m_renderSize);
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_numRequestedSamples)
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << tcu::TestLog::Message << "Using sampler shader to sample the multisample texture to single sample framebuffer." << tcu::TestLog::EndMessage;
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << tcu::TestLog::Message << "Drawing texture to single sample framebuffer. Using sampler shader." << tcu::TestLog::EndMessage;
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (samplerLocation == -1)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::TestError("Location u_sampler was -1.");
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// resolve multisample texture by averaging
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clear(GL_COLOR_BUFFER_BIT);
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(0, 0, m_renderSize, m_renderSize);
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindVertexArray(m_resolveVao);
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, m_resolveBuffer);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.enableVertexAttribArray(posLocation);
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "set attrib");
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.activeTexture(GL_TEXTURE0);
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(textureTarget, m_fboTexture);
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "bind tex");
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.useProgram(m_textureSamplerProgram->getProgram());
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1i(samplerLocation, 0);
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo);
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.useProgram(0);
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindVertexArray(0);
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Reading pixels from single sample framebuffer." << tcu::TestLog::EndMessage;
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// set test result
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verifyResultImageAndSetResult(resultImage);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_renderTarget == TARGET_TEXTURE && m_verifyTextureSampleBuffers)
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32				posLocation		= gl.getAttribLocation(m_textureSamplerProgram->getProgram(), "a_position");
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32				samplerLocation	= gl.getUniformLocation(m_textureSamplerProgram->getProgram(), "u_sampler");
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32				sampleLocation	= gl.getUniformLocation(m_textureSamplerProgram->getProgram(), "u_sampleNdx");
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32				textureTarget	= (m_numRequestedSamples == 0) ? (GL_TEXTURE_2D) : (GL_TEXTURE_2D_MULTISAMPLE);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<tcu::Surface>	resultBuffers	(m_numTargetSamples);
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_numRequestedSamples)
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << tcu::TestLog::Message << "Reading multisample texture sample buffers." << tcu::TestLog::EndMessage;
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << tcu::TestLog::Message << "Reading texture." << tcu::TestLog::EndMessage;
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (samplerLocation == -1)
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::TestError("Location u_sampler was -1.");
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (sampleLocation == -1)
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::TestError("Location u_sampleNdx was -1.");
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int sampleNdx = 0; sampleNdx < m_numTargetSamples; ++sampleNdx)
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultBuffers[sampleNdx].setSize(m_renderSize, m_renderSize);
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// read sample buffers to different surfaces
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clear(GL_COLOR_BUFFER_BIT);
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(0, 0, m_renderSize, m_renderSize);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindVertexArray(m_resolveVao);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, m_resolveBuffer);
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.enableVertexAttribArray(posLocation);
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "set attrib");
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.activeTexture(GL_TEXTURE0);
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(textureTarget, m_fboTexture);
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "bind tex");
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo);
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.useProgram(m_textureSamplerProgram->getProgram());
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1i(samplerLocation, 0);
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Reading sample buffers" << tcu::TestLog::EndMessage;
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int sampleNdx = 0; sampleNdx < m_numTargetSamples; ++sampleNdx)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.uniform1i(sampleLocation, sampleNdx);
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glu::readPixels(m_context.getRenderContext(), 0, 0, resultBuffers[sampleNdx].getAccess());
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.useProgram(0);
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindVertexArray(0);
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// verify sample buffers
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verifyResultBuffersAndSetResult(resultBuffers);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string	MultisampleRenderCase::genVertexSource (int numTargetSamples) const
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(numTargetSamples);
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::string(s_vertexSource);
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string MultisampleRenderCase::genMSSamplerSource (int numTargetSamples) const
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_verifyTextureSampleBuffers)
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return genMSTextureLayerFetchSource(numTargetSamples);
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return genMSTextureResolverSource(numTargetSamples);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string	MultisampleRenderCase::genMSTextureResolverSource (int numTargetSamples) const
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// default behavior: average
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isSingleSampleTarget = (m_numRequestedSamples == 0);
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	buf;
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"#version 310 es\n"
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in mediump vec4 v_position;\n"
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 fragColor;\n"
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump " << ((isSingleSampleTarget) ? ("sampler2D") : ("sampler2DMS")) << " u_sampler;\n"
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec2 relPosition = (v_position.xy + vec2(1.0, 1.0)) / 2.0;\n"
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump ivec2 fetchPos = ivec2(floor(relPosition * " << m_renderSize << ".0));\n"
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec4 colorSum = vec4(0.0, 0.0, 0.0, 0.0);\n"
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n";
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isSingleSampleTarget)
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	colorSum = texelFetch(u_sampler, fetchPos, 0);\n"
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"\n";
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf <<	"	for (int sampleNdx = 0; sampleNdx < " << numTargetSamples << "; ++sampleNdx)\n"
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"		colorSum += texelFetch(u_sampler, fetchPos, sampleNdx);\n"
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	colorSum /= " << numTargetSamples << ".0;\n"
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"\n";
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"	fragColor = vec4(colorSum.xyz, 1.0);\n"
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string MultisampleRenderCase::genMSTextureLayerFetchSource (int numTargetSamples) const
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(numTargetSamples);
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isSingleSampleTarget = (m_numRequestedSamples == 0);
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	buf;
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"#version 310 es\n"
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in mediump vec4 v_position;\n"
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 fragColor;\n"
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump " << ((isSingleSampleTarget) ? ("sampler2D") : ("sampler2DMS")) << " u_sampler;\n"
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump int u_sampleNdx;\n"
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec2 relPosition = (v_position.xy + vec2(1.0, 1.0)) / 2.0;\n"
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump ivec2 fetchPos = ivec2(floor(relPosition * " << m_renderSize << ".0));\n"
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec4 color = texelFetch(u_sampler, fetchPos, u_sampleNdx);\n"
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	fragColor = vec4(color.rgb, 1.0);\n"
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool MultisampleRenderCase::verifySampleBuffers (const std::vector<tcu::Surface>& resultBuffers)
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(resultBuffers);
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleRenderCase::setupRenderData (void)
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const tcu::Vec4 fullscreenQuad[] =
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderMode = GL_TRIANGLE_STRIP;
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderCount = 4;
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderSceneDescription = "quad";
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderAttribs["a_position"].offset = 0;
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderAttribs["a_position"].stride = sizeof(float[4]);
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer);
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_ARRAY_BUFFER, (int)sizeof(fullscreenQuad), fullscreenQuad, GL_STATIC_DRAW);
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // MultisampleShaderRenderUtil
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
766