13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL (ES) 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 Common object lifetime tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsLifetimeTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSTLUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRGBA.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuStringTemplate.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDefs.hpp"
40c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos#include "gluTextureUtil.hpp"
41c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos#include "gluStrUtil.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gls
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace LifetimeTests
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace details
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::ostringstream;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::Random;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::RenderTarget;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::RGBA;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::StringTemplate;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestCase;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef TestCase::IterateResult IterateResult;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::ScopedLogSection;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::Program;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::Shader;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::Framebuffer;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::SHADERTYPE_VERTEX;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::SHADERTYPE_FRAGMENT;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw;
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum { VIEWPORT_SIZE = 128, FRAMEBUFFER_SIZE = 128 };
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLint getInteger (ContextWrapper& gl, GLenum queryParam)
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint ret = 0;
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.glGetIntegerv(queryParam, &ret),
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.glGetError());
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.log() << TestLog::Message << "// Single integer output: " << ret << TestLog::EndMessage;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define GLSL100_SRC(BODY) ("#version 100\n" #BODY "\n")
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_vertexShaderSrc = GLSL100_SRC(
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribute vec2 pos;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void main()
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl_Position = vec4(pos.xy, 0.0, 1.0);
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	);
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_fragmentShaderSrc = GLSL100_SRC(
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void main()
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl_FragColor = vec4(1.0);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CheckedShader : public Shader
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CheckedShader (const RenderContext& renderCtx, glu::ShaderType type, const string& src)
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Shader (renderCtx, type)
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const srcStr = src.c_str();
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setSources(1, &srcStr, DE_NULL);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compile();
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(getCompileStatus());
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CheckedProgram : public Program
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CheckedProgram	(const RenderContext& renderCtx, GLuint vtxShader, GLuint fragShader)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Program	(renderCtx)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attachShader(vtxShader);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attachShader(fragShader);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		link();
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(getLinkStatus());
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryContextWrapper::ContextWrapper (const Context& ctx)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: CallLogWrapper	(ctx.gl(), ctx.log())
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_ctx				(ctx)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SimpleBinder::bind (GLuint name)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	(this->*m_bindFunc)(m_bindTarget, name);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint SimpleBinder::getBinding (void)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getInteger(*this, m_bindingParam);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint SimpleType::gen (void)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint ret;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	(this->*m_genFunc)(1, &ret);
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VertexArrayBinder : public SimpleBinder
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						VertexArrayBinder	(Context& ctx)
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: SimpleBinder	(ctx, 0, GL_NONE, GL_VERTEX_ARRAY_BINDING, true) {}
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				bind				(GLuint name) { glBindVertexArray(name); }
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass QueryBinder : public Binder
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						QueryBinder		(Context& ctx) : Binder(ctx) {}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				bind			(GLuint name)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (name != 0)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glBeginQuery(GL_ANY_SAMPLES_PASSED, name);
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEndQuery(GL_ANY_SAMPLES_PASSED);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint				getBinding		(void) { return 0; }
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ProgramType::isDeleteFlagged (GLuint name)
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint deleteFlagged = 0;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetProgramiv(name, GL_DELETE_STATUS, &deleteFlagged);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deleteFlagged != 0;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderType::isDeleteFlagged (GLuint name)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint deleteFlagged = 0;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetShaderiv(name, GL_DELETE_STATUS, &deleteFlagged);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deleteFlagged != 0;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid setupFbo (const Context& ctx, GLuint seed, GLuint fbo)
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Functions& gl = ctx.getRenderContext().getFunctions();
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, fbo),
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 gl.getError());
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (seed == 0)
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0, 0.0, 0.0, 1.0);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Random			rnd		(seed);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLsizei	width	= rnd.getInt(0, FRAMEBUFFER_SIZE);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLsizei	height	= rnd.getInt(0, FRAMEBUFFER_SIZE);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint		x		= rnd.getInt(0, FRAMEBUFFER_SIZE - width);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint		y		= rnd.getInt(0, FRAMEBUFFER_SIZE - height);
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	r1		= rnd.getFloat();
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	g1		= rnd.getFloat();
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	b1		= rnd.getFloat();
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	a1		= rnd.getFloat();
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	r2		= rnd.getFloat();
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	g2		= rnd.getFloat();
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	b2		= rnd.getFloat();
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	a2		= rnd.getFloat();
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(gl.clearColor(r1, g1, b1, a1), gl.getError());
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.scissor(x, y, width, height);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable(GL_SCISSOR_TEST);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(r2, g2, b2, a2);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disable(GL_SCISSOR_TEST);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_ERROR(gl.getError());
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawFbo (const Context& ctx, GLuint fbo, Surface& dst)
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RenderContext& renderCtx = ctx.getRenderContext();
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Functions& gl = renderCtx.getFunctions();
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo),
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getError());
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst.setSize(FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE);
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(renderCtx, 0, 0, dst.getAccess());
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels from framebuffer");
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, 0),
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getError());
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint getFboAttachment (const Functions& gl, GLuint fbo, GLenum requiredType)
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint type = 0, name = 0;
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   &type),
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getError());
259f78b3df108f38d8c8f489d4139b34aafc4824576Mika Isojärvi
260f78b3df108f38d8c8f489d4139b34aafc4824576Mika Isojärvi	if (GLenum(type) != requiredType || GLenum(type) == GL_NONE)
261f78b3df108f38d8c8f489d4139b34aafc4824576Mika Isojärvi		return 0;
262f78b3df108f38d8c8f489d4139b34aafc4824576Mika Isojärvi
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   &name),
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getError());
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_ERROR(gl.getError());
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
271f78b3df108f38d8c8f489d4139b34aafc4824576Mika Isojärvi	return name;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboAttacher::initAttachment (GLuint seed, GLuint element)
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Binder& binder = *getElementType().binder();
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Framebuffer fbo(getRenderContext());
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(false);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder.enableLogging(false);
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder.bind(element);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	initStorage();
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder.bind(0);
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder.enableLogging(true);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attach(element, *fbo);
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupFbo(getContext(), seed, *fbo);
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	detach(element, *fbo);
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Drew to " << getElementType().getName() << " " << element
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << " with seed " << seed << "."
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboInputAttacher::drawContainer (GLuint fbo, Surface& dst)
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawFbo(getContext(), fbo, dst);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Read pixels from framebuffer " << fbo << " to output image."
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboOutputAttacher::setupContainer (GLuint seed, GLuint fbo)
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupFbo(getContext(), seed, fbo);
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Drew to framebuffer " << fbo << " with seed " << seed << "."
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboOutputAttacher::drawAttachment (GLuint element, Surface& dst)
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Framebuffer fbo(getRenderContext());
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.enableLogging(false);
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.attach(element, *fbo);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawFbo(getContext(), *fbo, dst);
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.detach(element, *fbo);
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.enableLogging(true);
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Read pixels from " << m_attacher.getElementType().getName() << " " << element
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << " to output image."
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_ERROR(gl().getError());
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFboAttacher::attach (GLuint texture, GLuint fbo)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  GL_TEXTURE_2D, texture, 0),
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, 0),
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFboAttacher::detach (GLuint texture, GLuint fbo)
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(texture);
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0),
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, 0),
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint TextureFboAttacher::getAttachment (GLuint fbo)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getFboAttachment(gl(), fbo, GL_TEXTURE);
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulosstatic bool isTextureFormatColorRenderable (const glu::RenderContext& renderCtx, const glu::TransferFormat& format)
364c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos{
365c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	const glw::Functions&	gl			= renderCtx.getFunctions();
366c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	deUint32				curFbo		= ~0u;
367c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	deUint32				curTex		= ~0u;
368c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	deUint32				testFbo		= 0u;
369c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	deUint32				testTex		= 0u;
370c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	GLenum					status		= GL_NONE;
371c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
372c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_FRAMEBUFFER_BINDING, (deInt32*)&curFbo));
373c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_TEXTURE_BINDING_2D, (deInt32*)&curTex));
374c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
375c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	try
376c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	{
377c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, genTextures(1, &testTex));
378c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, testTex));
379c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, texImage2D(GL_TEXTURE_2D, 0, format.format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
380c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos										  format.format, format.dataType, DE_NULL));
381c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
382c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, genFramebuffers(1, &testFbo));
383c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, testFbo));
384c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, testTex, 0));
385c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
386c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
387c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_MSG(gl, "glCheckFramebufferStatus(GL_FRAMEBUFFER)");
388c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
389c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, curTex));
390c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, curFbo));
391c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
392c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, deleteTextures(1, &testTex));
393c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, deleteFramebuffers(1, &testFbo));
394c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	}
395c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	catch (...)
396c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	{
397c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		if (testTex != 0)
398c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			gl.deleteTextures(1, &testTex);
399c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
400c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		if (testFbo != 0)
401c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			gl.deleteFramebuffers(1, &testFbo);
402c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
403c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		throw;
404c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	}
405c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
406c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	if (status == GL_FRAMEBUFFER_COMPLETE)
407c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		return true;
408c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
409c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		return false;
410c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	else
411c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		TCU_THROW(TestError, (std::string("glCheckFramebufferStatus() returned invalid result code ")
412c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos							  + de::toString(glu::getFramebufferStatusStr(status))).c_str());
413c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos}
414c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
415c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulosstatic glu::TransferFormat getRenderableColorTextureFormat (const glu::RenderContext& renderCtx)
416c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos{
417c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	if (glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3,0)))
418c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		return glu::TransferFormat(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
419c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
420c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	{
421c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		const glu::TransferFormat	candidates[]	=
422c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		{
423c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			glu::TransferFormat(GL_RGBA,	GL_UNSIGNED_SHORT_4_4_4_4),
424c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			glu::TransferFormat(GL_RGBA,	GL_UNSIGNED_SHORT_5_5_5_1),
425c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			glu::TransferFormat(GL_RGB,		GL_UNSIGNED_SHORT_5_6_5),
426c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			glu::TransferFormat(GL_RGBA,	GL_UNSIGNED_BYTE),
427c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		};
428c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
429c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(candidates); ++ndx)
430c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		{
431c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			if (isTextureFormatColorRenderable(renderCtx, candidates[ndx]))
432c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos				return candidates[ndx];
433c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		}
434c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	}
435c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
436c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	return glu::TransferFormat(GL_NONE, GL_NONE);
437c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos}
438c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFboAttacher::initStorage (void)
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
441c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	const glu::TransferFormat	format	= getRenderableColorTextureFormat(getRenderContext());
442c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
443c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	if (format.format == GL_NONE)
444c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		TCU_THROW(NotSupportedError, "No renderable texture format found");
445c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
447c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		glTexImage2D(GL_TEXTURE_2D, 0, format.format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
448c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos					 format.format, format.dataType, DE_NULL),
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
452c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulosstatic bool isRenderbufferFormatColorRenderable (const glu::RenderContext& renderCtx, const deUint32 format)
453c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos{
454c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	const glw::Functions&	gl			= renderCtx.getFunctions();
455c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	deUint32				curFbo		= ~0u;
456c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	deUint32				curRbo		= ~0u;
457c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	deUint32				testFbo		= 0u;
458c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	deUint32				testRbo		= 0u;
459c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	GLenum					status		= GL_NONE;
460c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
461c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_FRAMEBUFFER_BINDING, (deInt32*)&curFbo));
462c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_RENDERBUFFER_BINDING, (deInt32*)&curRbo));
463c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
464c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	try
465c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	{
466c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, genRenderbuffers(1, &testRbo));
467c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, testRbo));
468c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE));
469c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
470c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, genFramebuffers(1, &testFbo));
471c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, testFbo));
472c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, testRbo));
473c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
474c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
475c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_MSG(gl, "glCheckFramebufferStatus(GL_FRAMEBUFFER)");
476c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
477c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, curRbo));
478c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, curFbo));
479c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
480c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, deleteRenderbuffers(1, &testRbo));
481c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		GLU_CHECK_GLW_CALL(gl, deleteFramebuffers(1, &testFbo));
482c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	}
483c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	catch (...)
484c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	{
485c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		if (testRbo != 0)
486c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			gl.deleteRenderbuffers(1, &testRbo);
487c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
488c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		if (testFbo != 0)
489c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			gl.deleteFramebuffers(1, &testFbo);
490c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
491c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		throw;
492c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	}
493c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
494c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	if (status == GL_FRAMEBUFFER_COMPLETE)
495c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		return true;
496c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
497c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		return false;
498c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	else
499c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		TCU_THROW(TestError, (std::string("glCheckFramebufferStatus() returned invalid result code ")
500c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos							  + de::toString(glu::getFramebufferStatusStr(status))).c_str());
501c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos}
502c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
503c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulosstatic deUint32 getRenderableColorRenderbufferFormat (const glu::RenderContext& renderCtx)
504c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos{
505c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	if (glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3,0)))
506c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		return GL_RGBA4;
507c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
508c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	{
509c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		const deUint32	candidates[]	=
510c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		{
511c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			GL_RGBA4,
512c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			GL_RGB5_A1,
513c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			GL_RGB565,
514c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		};
515c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
516c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(candidates); ++ndx)
517c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		{
518c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos			if (isRenderbufferFormatColorRenderable(renderCtx, candidates[ndx]))
519c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos				return candidates[ndx];
520c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		}
521c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	}
522c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
523c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	return GL_NONE;
524c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos}
525c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RboFboAttacher::initStorage (void)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
528c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	const deUint32	format	= getRenderableColorRenderbufferFormat(getRenderContext());
529c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
530c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos	if (format == GL_NONE)
531c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		TCU_THROW(TestError, "No color-renderable renderbuffer format found");
532c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
534c0a5dc217f05aebc817b195419b488924862ed01Pyry Haulos		glRenderbufferStorage(GL_RENDERBUFFER, format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE),
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RboFboAttacher::attach (GLuint rbo, GLuint fbo)
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo),
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, 0),
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RboFboAttacher::detach (GLuint rbo, GLuint fbo)
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(rbo);
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0),
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, 0),
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint RboFboAttacher::getAttachment (GLuint fbo)
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getFboAttachment(gl(), fbo, GL_RENDERBUFFER);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_fragmentShaderTemplate = GLSL100_SRC(
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void main()
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl_FragColor = vec4(${RED}, ${GREEN}, ${BLUE}, 1.0);
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	);
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgramAttacher::initAttachment (GLuint seed, GLuint shader)
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using					de::insert;
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using					de::floatToString;
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random					rnd(seed);
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string>		params;
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const StringTemplate	sourceTmpl	(s_fragmentShaderTemplate);
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	insert(params, "RED",	floatToString(rnd.getFloat(), 4));
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	insert(params, "GREEN",	floatToString(rnd.getFloat(), 4));
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	insert(params, "BLUE",	floatToString(rnd.getFloat(), 4));
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			source		= sourceTmpl.specialize(params);
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const		sourceStr	= source.c_str();
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(glShaderSource(shader, 1, &sourceStr, DE_NULL), gl().getError());
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(glCompileShader(shader), gl().getError());
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLint compileStatus = 0;
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl().getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK_MSG(compileStatus != 0, sourceStr);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgramAttacher::attach (GLuint shader, GLuint program)
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glAttachShader(program, shader),
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgramAttacher::detach (GLuint shader, GLuint program)
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDetachShader(program, shader),
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint ShaderProgramAttacher::getAttachment (GLuint program)
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			shaders[2]	= { 0, 0 };
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLsizei	shadersLen	= DE_LENGTH_OF_ARRAY(shaders);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLsizei			numShaders	= 0;
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			ret			= 0;
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl().getAttachedShaders(program, shadersLen, &numShaders, shaders);
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// There should ever be at most one attached shader in normal use, but if
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// something is wrong, the temporary vertex shader might not have been
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// detached properly, so let's find the fragment shader explicitly.
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < de::min<GLsizei>(shadersLen, numShaders); ++ndx)
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint shaderType = GL_NONE;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getShaderiv(shaders[ndx], GL_SHADER_TYPE, &shaderType);
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (shaderType == GL_FRAGMENT_SHADER)
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ret = shaders[ndx];
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid setViewport (const RenderContext& renderCtx, const Rectangle& rect)
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderCtx.getFunctions().viewport(rect.x, rect.y, rect.width, rect.height);
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid readRectangle (const RenderContext& renderCtx, const Rectangle& rect, Surface& dst)
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst.setSize(rect.width, rect.height);
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(renderCtx, rect.x, rect.y, dst.getAccess());
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRectangle randomViewport (const RenderContext& ctx, GLint maxWidth, GLint maxHeight,
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						  Random& rnd)
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RenderTarget&	target	= ctx.getRenderTarget();
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLint			width	= de::min(target.getWidth(), maxWidth);
662c58a816cc5a5af03767e98d2a495e1c8ab8808eaMika Isojärvi	const GLint			xOff	= rnd.getInt(0, target.getWidth() - width);
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLint			height	= de::min(target.getHeight(), maxHeight);
664c58a816cc5a5af03767e98d2a495e1c8ab8808eaMika Isojärvi	const GLint			yOff	= rnd.getInt(0, target.getHeight() - height);
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Rectangle(xOff, yOff, width, height);
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgramInputAttacher::drawContainer (GLuint program, Surface& dst)
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float	s_vertices[6]	= { -1.0, 0.0, 1.0, 1.0, 0.0, -1.0 };
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random				rnd				(program);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CheckedShader		vtxShader		(getRenderContext(),
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 SHADERTYPE_VERTEX, s_vertexShaderSrc);
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Rectangle		viewport		= randomViewport(getRenderContext(),
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 VIEWPORT_SIZE, VIEWPORT_SIZE, rnd);
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl().attachShader(program, vtxShader.getShader());
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl().linkProgram(program);
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint linkStatus = 0;
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getProgramiv(program, GL_LINK_STATUS, &linkStatus);
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(linkStatus != 0);
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Attached a temporary vertex shader and linked program " << program
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setViewport(getRenderContext(), viewport);
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message << "// Positioned viewport randomly" << TestLog::EndMessage;
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(program);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint posLoc = gl().getAttribLocation(program, "pos");
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(posLoc >= 0);
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().enableVertexAttribArray(posLoc);
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().clearColor(0, 0, 0, 1);
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().vertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, s_vertices);
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().drawArrays(GL_TRIANGLES, 0, 3);
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().disableVertexAttribArray(posLoc);
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log () << TestLog::Message << "// Drew a fixed triangle" << TestLog::EndMessage;
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(0);
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readRectangle(getRenderContext(), viewport, dst);
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message << "// Copied viewport to output image" << TestLog::EndMessage;
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl().detachShader(program, vtxShader.getShader());
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message << "// Removed temporary vertex shader" << TestLog::EndMessage;
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryES2Types::ES2Types (const Context& ctx)
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Types			(ctx)
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_bufferBind	(ctx, &CallLogWrapper::glBindBuffer,
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING)
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_bufferType	(ctx, "buffer", &CallLogWrapper::glGenBuffers,
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glDeleteBuffers,
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glIsBuffer, &m_bufferBind)
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureBind	(ctx, &CallLogWrapper::glBindTexture, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D)
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureType	(ctx, "texture", &CallLogWrapper::glGenTextures,
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glDeleteTextures,
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glIsTexture, &m_textureBind)
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboBind		(ctx, &CallLogWrapper::glBindRenderbuffer,
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 GL_RENDERBUFFER, GL_RENDERBUFFER_BINDING)
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboType		(ctx, "renderbuffer",
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glGenRenderbuffers,
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glDeleteRenderbuffers,
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glIsRenderbuffer, &m_rboBind)
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fboBind		(ctx, &CallLogWrapper::glBindFramebuffer,
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING)
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fboType		(ctx, "framebuffer",
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glGenFramebuffers,
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glDeleteFramebuffers,
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glIsFramebuffer, &m_fboBind)
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderType	(ctx)
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_programType	(ctx)
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texFboAtt	(ctx, m_textureType, m_fboType)
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texFboInAtt	(m_texFboAtt)
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texFboOutAtt(m_texFboAtt)
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboFboAtt	(ctx, m_rboType, m_fboType)
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboFboInAtt	(m_rboFboAtt)
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboFboOutAtt(m_rboFboAtt)
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderAtt	(ctx, m_shaderType, m_programType)
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderInAtt	(m_shaderAtt)
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type* const types[] =
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		&m_bufferType, &m_textureType, &m_rboType, &m_fboType, &m_shaderType, &m_programType
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_types.insert(m_types.end(), DE_ARRAY_BEGIN(types), DE_ARRAY_END(types));
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attachers.push_back(&m_texFboAtt);
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attachers.push_back(&m_rboFboAtt);
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attachers.push_back(&m_shaderAtt);
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_inAttachers.push_back(&m_texFboInAtt);
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_inAttachers.push_back(&m_rboFboInAtt);
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_inAttachers.push_back(&m_shaderInAtt);
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_outAttachers.push_back(&m_texFboOutAtt);
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_outAttachers.push_back(&m_rboFboOutAtt);
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Name
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Name		(Type& type) : m_type(type), m_name(type.gen()) {}
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Name		(Type& type, GLuint name) : m_type(type), m_name(name) {}
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				~Name		(void) { m_type.release(m_name); }
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint		operator*	(void) const { return m_name; }
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			m_type;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	m_name;
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ResultCollector
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ResultCollector		(TestContext& testCtx);
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			check				(bool cond, const char* msg);
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			fail				(const char* msg);
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			warn				(const char* msg);
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~ResultCollector	(void);
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			addResult			(qpTestResult result, const char* msg);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestContext&	m_testCtx;
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		m_log;
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestResult	m_result;
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		m_message;
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryResultCollector::ResultCollector (TestContext& testCtx)
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_testCtx		(testCtx)
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_log			(testCtx.getLog())
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_result		(QP_TEST_RESULT_PASS)
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_message		("Pass")
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ResultCollector::check (bool cond, const char* msg)
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!cond)
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fail(msg);
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return cond;
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ResultCollector::addResult (qpTestResult result, const char* msg)
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_log << TestLog::Message << "// Fail: " << msg << TestLog::EndMessage;
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_result == QP_TEST_RESULT_PASS)
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_result = result;
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_message = msg;
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (result == QP_TEST_RESULT_FAIL)
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_result = result;
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_message = "Multiple problems, see log for details";
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ResultCollector::fail (const char* msg)
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addResult(QP_TEST_RESULT_FAIL, msg);
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ResultCollector::warn (const char* msg)
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addResult(QP_TEST_RESULT_QUALITY_WARNING, msg);
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryResultCollector::~ResultCollector (void)
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(m_result, m_message);
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TestBase : public TestCase, protected CallLogWrapper
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							TestBase			(const char*	name,
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*	description,
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const Context&	ctx);
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Copy ContextWrapper since MI (except for CallLogWrapper) is a no-no.
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Context&			getContext			(void) const { return m_ctx; }
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RenderContext&	getRenderContext	(void) const { return m_ctx.getRenderContext(); }
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Functions&		gl					(void) const { return m_ctx.gl(); }
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log					(void) const { return m_ctx.log(); }
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init				(void);
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Context					m_ctx;
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random					m_rnd;
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestBase::TestBase (const char* name, const char* description, const Context& ctx)
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(ctx.getTestContext(), name, description)
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper	(ctx.gl(), ctx.log())
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_ctx				(ctx)
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rnd				(deStringHash(name))
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestBase::init (void)
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_rnd = Random(deStringHash(getName()));
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LifeTest : public TestBase
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef void			(LifeTest::*TestFunction)	(void);
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							LifeTest					(const char*	name,
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 const char*	description,
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 Type&			type,
887653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos														 TestFunction	test)
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								: TestBase		(name, description, type.getContext())
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								, m_type		(type)
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								, m_test		(test) {}
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate						(void);
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testGen						(void);
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDelete					(void);
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testBind					(void);
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeleteBound				(void);
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testBindNoGen				(void);
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeleteUsed				(void);
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Binder&					binder						(void) { return *m_type.binder(); }
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&					m_type;
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestFunction			m_test;
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult LifeTest::iterate (void)
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	(this->*m_test)();
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testGen (void)
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			name	(m_type);
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type.genCreates())
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(m_type.exists(*name), "Gen* should have created an object, but didn't");
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(!m_type.exists(*name), "Gen* should not have created an object, but did");
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testDelete (void)
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			name	= m_type.gen();
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type.release(name);
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(!m_type.exists(name), "Object still exists after deletion");
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testBind (void)
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			name	(m_type);
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder().bind(*name);
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl().getError(), "Bind failed");
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(m_type.exists(*name), "Object does not exist after binding");
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder().bind(0);
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testDeleteBound (void)
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	id		= m_type.gen();
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder().bind(id);
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type.release(id);
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type.nameLingers())
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(binder().getBinding() == id,
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object did not retain binding");
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(m_type.exists(id),
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object made its name invalid");
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(m_type.isDeleteFlagged(id),
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object did not flag the object for deletion");
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		binder().bind(0);
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(binder().getBinding() == 0,
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object did not remove binding");
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(!m_type.exists(id),
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object did not make its name invalid");
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		binder().bind(0);
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(binder().getBinding() == 0, "Unbinding didn't remove binding");
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(!m_type.exists(id), "Name is still valid after deleting and unbinding");
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testBindNoGen (void)
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	id		= m_rnd.getUint32();
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!errors.check(!m_type.exists(id), "Randomly chosen identifier already exists"))
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			name	(m_type, id);
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder().bind(*name);
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (binder().genRequired())
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(glGetError() == GL_INVALID_OPERATION,
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Did not fail when binding a name not generated by Gen* call");
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(!m_type.exists(*name),
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Bind* created an object for a name not generated by a Gen* call");
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(glGetError() == GL_NO_ERROR,
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Failed when binding a name not generated by Gen* call");
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(m_type.exists(*name),
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Object was not created by the Bind* call");
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testDeleteUsed (void)
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors(getTestContext());
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			programId = 0;
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CheckedShader	vtxShader	(getRenderContext(),
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 SHADERTYPE_VERTEX, s_vertexShaderSrc);
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CheckedShader	fragShader	(getRenderContext(),
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 SHADERTYPE_FRAGMENT, s_fragmentShaderSrc);
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CheckedProgram	program		(getRenderContext(),
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 vtxShader.getShader(), fragShader.getShader());
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programId = program.getProgram();
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message << "// Created and linked program " << programId
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(glUseProgram(programId), gl().getError());
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message << "// Deleted program " << programId
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(glIsProgram(programId));
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint deleteFlagged = 0;
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetProgramiv(programId, GL_DELETE_STATUS, &deleteFlagged);
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(deleteFlagged != 0, "Program object was not flagged as deleted");
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(glUseProgram(0), gl().getError());
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(!gl().isProgram(programId),
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Deleted program name still valid after being made non-current");
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AttachmentTest : public TestBase
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef void			(AttachmentTest::*TestFunction)	(void);
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							AttachmentTest					(const char*	name,
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*	description,
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 Attacher&		attacher,
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 TestFunction	test)
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								: TestBase		(name, description, attacher.getContext())
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								, m_attacher	(attacher)
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								, m_test		(test) {}
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate							(void);
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeletedNames				(void);
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeletedBinding				(void);
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeletedReattach				(void);
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Attacher&				m_attacher;
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestFunction		m_test;
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult AttachmentTest::iterate (void)
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	(this->*m_test)();
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint getAttachment (Attacher& attacher, GLuint container)
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint queriedAttachment = attacher.getAttachment(container);
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attacher.log() << TestLog::Message
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   << "// Result of query for " << attacher.getElementType().getName()
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   << " attached to " << attacher.getContainerType().getName() << " "
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   << container << ": " << queriedAttachment << "."
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   << TestLog::EndMessage;
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return queriedAttachment;
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AttachmentTest::testDeletedNames (void)
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			elemType		= m_attacher.getElementType();
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			containerType	= m_attacher.getContainerType();
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			container		(containerType);
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors			(getTestContext());
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			elementId		= 0;
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Name element(elemType);
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		elementId = *element;
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_attacher.initAttachment(0, *element);
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_attacher.attach(*element, *container);
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(getAttachment(m_attacher, *container) == elementId,
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Attachment name not returned by query even before deletion.");
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// "Such a container or other context may continue using the object, and
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// may still contain state identifying its name as being currently bound"
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// We here interpret "may" to mean that whenever the container has a
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// deleted object attached to it, a query will return that object's former
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// name.
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(getAttachment(m_attacher, *container) == elementId,
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Attachment name not returned by query after attachment was deleted.");
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (elemType.nameLingers())
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(elemType.exists(elementId),
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Attached object name no longer valid after deletion.");
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(!elemType.exists(elementId),
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Attached object name still valid after deletion.");
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.detach(elementId, *container);
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(getAttachment(m_attacher, *container) == 0,
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Attachment name returned by query even after detachment.");
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(!elemType.exists(elementId),
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Deleted attached object name still usable after detachment.");
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InputAttachmentTest : public TestBase
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					InputAttachmentTest	(const char*	name,
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const char*	description,
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 InputAttacher&	inputAttacher)
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						: TestBase			(name, description, inputAttacher.getContext())
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						, m_inputAttacher	(inputAttacher) {}
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate				(void);
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InputAttacher&	m_inputAttacher;
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint replaceName (Type& type, GLuint oldName, TestLog& log)
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Binder* const	binder		= type.binder();
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			genRequired	= binder == DE_NULL || binder->genRequired();
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (genRequired)
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return type.gen();
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "// Type does not require Gen* for binding, reusing old id " << oldName << "."
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return oldName;
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult InputAttachmentTest::iterate (void)
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Attacher&		attacher		= m_inputAttacher.getAttacher();
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			containerType	= attacher.getContainerType();
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			elementType		= attacher.getElementType();
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			container		(containerType);
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			elementId		= 0;
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	refSeed			= m_rnd.getUint32();
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	newSeed			= m_rnd.getUint32();
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors			(getTestContext());
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			refSurface;		// Surface from drawing with refSeed-seeded attachment
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			delSurface;		// Surface from drawing with deleted refSeed attachment
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			newSurface;		// Surface from drawing with newSeed-seeded attachment
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "Testing if writing to a newly created object modifies a deleted attachment"
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ScopedLogSection	section	(log(),
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 "Write to original", "Writing to an original attachment");
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Name			element	(elementType);
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		elementId = *element;
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.initAttachment(refSeed, elementId);
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.attach(elementId, *container);
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_inputAttacher.drawContainer(*container, refSurface);
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// element gets deleted here
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message << "// Deleting attachment";
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ScopedLogSection section	(log(), "Write to new",
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 "Writing to a new attachment after deleting the original");
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint	newId		= replaceName(elementType, elementId, log());
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Name		newElement	(elementType, newId);
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.initAttachment(newSeed, newId);
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_inputAttacher.drawContainer(*container, delSurface);
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.detach(elementId, *container);
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.attach(newId, *container);
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_inputAttacher.drawContainer(*container, newSurface);
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.detach(newId, *container);
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool surfacesMatch = tcu::pixelThresholdCompare(
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log(), "Reading from deleted",
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Comparison result from reading from a container with a deleted attachment "
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"before and after writing to a fresh object.",
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			refSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			surfacesMatch,
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Writing to a fresh object modified the container with a deleted attachment.");
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!surfacesMatch)
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log() << TestLog::Image("New attachment",
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									"Container state after attached to the fresh object",
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									newSurface);
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass OutputAttachmentTest : public TestBase
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						OutputAttachmentTest			(const char*		name,
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 const char*		description,
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 OutputAttacher&	outputAttacher)
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: TestBase			(name, description,
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 outputAttacher.getContext())
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							, m_outputAttacher	(outputAttacher) {}
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate							(void);
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OutputAttacher&		m_outputAttacher;
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult OutputAttachmentTest::iterate (void)
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Attacher&		attacher		= m_outputAttacher.getAttacher();
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			containerType	= attacher.getContainerType();
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			elementType		= attacher.getElementType();
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			container		(containerType);
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			elementId		= 0;
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	refSeed			= m_rnd.getUint32();
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	newSeed			= m_rnd.getUint32();
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors			(getTestContext());
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			refSurface;		// Surface drawn from attachment to refSeed container
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			newSurface;		// Surface drawn from attachment to newSeed container
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			delSurface;		// Like newSurface, after writing to a deleted attachment
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "Testing if writing to a container with a deleted attachment "
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "modifies a newly created object"
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ScopedLogSection	section	(log(), "Write to existing",
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 "Writing to a container with an existing attachment");
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Name			element	(elementType);
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		elementId = *element;
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.initAttachment(0, elementId);
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.attach(elementId, *container);
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// For reference purposes, make note of what refSeed looks like.
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.setupContainer(refSeed, *container);
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.drawAttachment(elementId, refSurface);
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ScopedLogSection	section		(log(), "Write to deleted",
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 "Writing to a container after deletion of attachment");
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint		newId		= replaceName(elementType, elementId, log());
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Name			newElement	(elementType, newId);
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << "Creating a new object " << newId
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << "Recording state of new object before writing to container"
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.initAttachment(newSeed, newId);
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.drawAttachment(newId, newSurface);
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << "Writing to container"
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Now re-write refSeed to the container.
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.setupContainer(refSeed, *container);
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Does it affect the newly created attachment object?
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.drawAttachment(newId, delSurface);
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attacher.detach(elementId, *container);
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool surfacesMatch = tcu::pixelThresholdCompare(
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log(), "Writing to deleted",
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"Comparison result from reading from a fresh object before and after "
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"writing to a container with a deleted attachment",
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		newSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(surfacesMatch,
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Writing to container with deleted attachment modified a new object.");
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!surfacesMatch)
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Image(
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Original attachment",
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Result of container modification on original attachment before deletion.",
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			refSurface);
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct LifeTestSpec
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*				name;
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LifeTest::TestFunction	func;
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					needBind;
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMovePtr<TestCaseGroup> createLifeTestGroup (TestContext& testCtx,
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											const LifeTestSpec& spec,
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											const vector<Type*>& types)
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MovePtr<TestCaseGroup> group(new TestCaseGroup(testCtx, spec.name, spec.name));
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Type*>::const_iterator it = types.begin(); it != types.end(); ++it)
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Type& type = **it;
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* name = type.getName();
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!spec.needBind || type.binder() != DE_NULL)
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			group->addChild(new LifeTest(name, name, type, spec.func));
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return group;
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const LifeTestSpec s_lifeTests[] =
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "gen",			&LifeTest::testGen,			false	},
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "delete",			&LifeTest::testDelete,		false	},
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "bind",			&LifeTest::testBind,		true	},
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "delete_bound",	&LifeTest::testDeleteBound,	true	},
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "bind_no_gen",	&LifeTest::testBindNoGen,	true	},
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring attacherName (Attacher& attacher)
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ostringstream os;
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	os << attacher.getElementType().getName() << "_" <<  attacher.getContainerType().getName();
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return os.str();
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid addTestCases (TestCaseGroup& group, Types& types)
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestContext& testCtx = types.getTestContext();
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (const LifeTestSpec* it = DE_ARRAY_BEGIN(s_lifeTests);
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 it != DE_ARRAY_END(s_lifeTests); ++it)
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group.addChild(createLifeTestGroup(testCtx, *it, types.getTypes()).release());
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const delUsedGroup =
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			new TestCaseGroup(testCtx, "delete_used", "Delete current program");
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group.addChild(delUsedGroup);
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delUsedGroup->addChild(
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			new LifeTest("program", "program", types.getProgramType(),
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 &LifeTest::testDeleteUsed));
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const	attGroup	= new TestCaseGroup(
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testCtx, "attach", "Attachment tests");
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group.addChild(attGroup);
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const	nameGroup	= new TestCaseGroup(
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				testCtx, "deleted_name", "Name of deleted attachment");
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attGroup->addChild(nameGroup);
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<Attacher*>& atts = types.getAttachers();
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<Attacher*>::const_iterator it = atts.begin(); it != atts.end(); ++it)
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string name = attacherName(**it);
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				nameGroup->addChild(new AttachmentTest(name.c_str(), name.c_str(), **it,
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   &AttachmentTest::testDeletedNames));
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* inputGroup = new TestCaseGroup(
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				testCtx, "deleted_input", "Input from deleted attachment");
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attGroup->addChild(inputGroup);
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<InputAttacher*>& inAtts = types.getInputAttachers();
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<InputAttacher*>::const_iterator it = inAtts.begin();
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 it != inAtts.end(); ++it)
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string name = attacherName((*it)->getAttacher());
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inputGroup->addChild(new InputAttachmentTest(name.c_str(), name.c_str(), **it));
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* outputGroup = new TestCaseGroup(
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				testCtx, "deleted_output", "Output to deleted attachment");
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attGroup->addChild(outputGroup);
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<OutputAttacher*>& outAtts = types.getOutputAttachers();
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<OutputAttacher*>::const_iterator it = outAtts.begin();
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 it != outAtts.end(); ++it)
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string name = attacherName((*it)->getAttacher());
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				outputGroup->addChild(new OutputAttachmentTest(name.c_str(), name.c_str(),
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   **it));
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // details
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // LifetimeTests
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gls
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1414