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"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gls
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace LifetimeTests
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace details
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::ostringstream;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::Random;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::RenderTarget;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::RGBA;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::StringTemplate;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestCase;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef TestCase::IterateResult IterateResult;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::ScopedLogSection;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::Program;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::Shader;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::Framebuffer;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::SHADERTYPE_VERTEX;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::SHADERTYPE_FRAGMENT;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum { VIEWPORT_SIZE = 128, FRAMEBUFFER_SIZE = 128 };
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLint getInteger (ContextWrapper& gl, GLenum queryParam)
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint ret = 0;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.glGetIntegerv(queryParam, &ret),
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.glGetError());
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.log() << TestLog::Message << "// Single integer output: " << ret << TestLog::EndMessage;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define GLSL100_SRC(BODY) ("#version 100\n" #BODY "\n")
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_vertexShaderSrc = GLSL100_SRC(
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribute vec2 pos;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void main()
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl_Position = vec4(pos.xy, 0.0, 1.0);
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	);
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_fragmentShaderSrc = GLSL100_SRC(
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void main()
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl_FragColor = vec4(1.0);
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CheckedShader : public Shader
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CheckedShader (const RenderContext& renderCtx, glu::ShaderType type, const string& src)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Shader (renderCtx, type)
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const srcStr = src.c_str();
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setSources(1, &srcStr, DE_NULL);
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compile();
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(getCompileStatus());
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CheckedProgram : public Program
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CheckedProgram	(const RenderContext& renderCtx, GLuint vtxShader, GLuint fragShader)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Program	(renderCtx)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attachShader(vtxShader);
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attachShader(fragShader);
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		link();
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(getLinkStatus());
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryContextWrapper::ContextWrapper (const Context& ctx)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: CallLogWrapper	(ctx.gl(), ctx.log())
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_ctx				(ctx)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SimpleBinder::bind (GLuint name)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	(this->*m_bindFunc)(m_bindTarget, name);
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint SimpleBinder::getBinding (void)
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getInteger(*this, m_bindingParam);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint SimpleType::gen (void)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint ret;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	(this->*m_genFunc)(1, &ret);
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VertexArrayBinder : public SimpleBinder
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						VertexArrayBinder	(Context& ctx)
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: SimpleBinder	(ctx, 0, GL_NONE, GL_VERTEX_ARRAY_BINDING, true) {}
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				bind				(GLuint name) { glBindVertexArray(name); }
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass QueryBinder : public Binder
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						QueryBinder		(Context& ctx) : Binder(ctx) {}
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				bind			(GLuint name)
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (name != 0)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glBeginQuery(GL_ANY_SAMPLES_PASSED, name);
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEndQuery(GL_ANY_SAMPLES_PASSED);
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint				getBinding		(void) { return 0; }
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ProgramType::isDeleteFlagged (GLuint name)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint deleteFlagged = 0;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetProgramiv(name, GL_DELETE_STATUS, &deleteFlagged);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deleteFlagged != 0;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderType::isDeleteFlagged (GLuint name)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint deleteFlagged = 0;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetShaderiv(name, GL_DELETE_STATUS, &deleteFlagged);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deleteFlagged != 0;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid setupFbo (const Context& ctx, GLuint seed, GLuint fbo)
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Functions& gl = ctx.getRenderContext().getFunctions();
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, fbo),
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 gl.getError());
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (seed == 0)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.0, 0.0, 0.0, 1.0);
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Random			rnd		(seed);
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLsizei	width	= rnd.getInt(0, FRAMEBUFFER_SIZE);
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLsizei	height	= rnd.getInt(0, FRAMEBUFFER_SIZE);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint		x		= rnd.getInt(0, FRAMEBUFFER_SIZE - width);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint		y		= rnd.getInt(0, FRAMEBUFFER_SIZE - height);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	r1		= rnd.getFloat();
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	g1		= rnd.getFloat();
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	b1		= rnd.getFloat();
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	a1		= rnd.getFloat();
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	r2		= rnd.getFloat();
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	g2		= rnd.getFloat();
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	b2		= rnd.getFloat();
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLfloat	a2		= rnd.getFloat();
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(gl.clearColor(r1, g1, b1, a1), gl.getError());
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.scissor(x, y, width, height);
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enable(GL_SCISSOR_TEST);
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(r2, g2, b2, a2);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disable(GL_SCISSOR_TEST);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_ERROR(gl.getError());
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawFbo (const Context& ctx, GLuint fbo, Surface& dst)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RenderContext& renderCtx = ctx.getRenderContext();
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Functions& gl = renderCtx.getFunctions();
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo),
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getError());
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst.setSize(FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE);
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(renderCtx, 0, 0, dst.getAccess());
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels from framebuffer");
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, 0),
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getError());
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint getFboAttachment (const Functions& gl, GLuint fbo, GLenum requiredType)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint type = 0, name = 0;
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   &type),
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getError());
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   &name),
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getError());
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_ERROR(gl.getError());
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint ret = GLenum(type) == requiredType ? name : 0;
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboAttacher::initAttachment (GLuint seed, GLuint element)
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Binder& binder = *getElementType().binder();
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Framebuffer fbo(getRenderContext());
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(false);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder.enableLogging(false);
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder.bind(element);
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	initStorage();
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder.bind(0);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder.enableLogging(true);
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attach(element, *fbo);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupFbo(getContext(), seed, *fbo);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	detach(element, *fbo);
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Drew to " << getElementType().getName() << " " << element
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << " with seed " << seed << "."
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboInputAttacher::drawContainer (GLuint fbo, Surface& dst)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawFbo(getContext(), fbo, dst);
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Read pixels from framebuffer " << fbo << " to output image."
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboOutputAttacher::setupContainer (GLuint seed, GLuint fbo)
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupFbo(getContext(), seed, fbo);
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Drew to framebuffer " << fbo << " with seed " << seed << "."
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboOutputAttacher::drawAttachment (GLuint element, Surface& dst)
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Framebuffer fbo(getRenderContext());
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.enableLogging(false);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.attach(element, *fbo);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawFbo(getContext(), *fbo, dst);
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.detach(element, *fbo);
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.enableLogging(true);
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Read pixels from " << m_attacher.getElementType().getName() << " " << element
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << " to output image."
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_ERROR(gl().getError());
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFboAttacher::attach (GLuint texture, GLuint fbo)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  GL_TEXTURE_2D, texture, 0),
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, 0),
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFboAttacher::detach (GLuint texture, GLuint fbo)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(texture);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0),
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, 0),
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint TextureFboAttacher::getAttachment (GLuint fbo)
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getFboAttachment(gl(), fbo, GL_TEXTURE);
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFboAttacher::initStorage (void)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, DE_NULL),
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RboFboAttacher::initStorage (void)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE),
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RboFboAttacher::attach (GLuint rbo, GLuint fbo)
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo),
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, 0),
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RboFboAttacher::detach (GLuint rbo, GLuint fbo)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(rbo);
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, fbo),
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0),
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindFramebuffer(GL_FRAMEBUFFER, 0),
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint RboFboAttacher::getAttachment (GLuint fbo)
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getFboAttachment(gl(), fbo, GL_RENDERBUFFER);
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_fragmentShaderTemplate = GLSL100_SRC(
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void main()
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl_FragColor = vec4(${RED}, ${GREEN}, ${BLUE}, 1.0);
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	);
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgramAttacher::initAttachment (GLuint seed, GLuint shader)
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using					de::insert;
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using					de::floatToString;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random					rnd(seed);
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string>		params;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const StringTemplate	sourceTmpl	(s_fragmentShaderTemplate);
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	insert(params, "RED",	floatToString(rnd.getFloat(), 4));
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	insert(params, "GREEN",	floatToString(rnd.getFloat(), 4));
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	insert(params, "BLUE",	floatToString(rnd.getFloat(), 4));
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			source		= sourceTmpl.specialize(params);
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const		sourceStr	= source.c_str();
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(glShaderSource(shader, 1, &sourceStr, DE_NULL), gl().getError());
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(glCompileShader(shader), gl().getError());
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLint compileStatus = 0;
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl().getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK_MSG(compileStatus != 0, sourceStr);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgramAttacher::attach (GLuint shader, GLuint program)
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glAttachShader(program, shader),
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgramAttacher::detach (GLuint shader, GLuint program)
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDetachShader(program, shader),
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getError());
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint ShaderProgramAttacher::getAttachment (GLuint program)
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			shaders[2]	= { 0, 0 };
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLsizei	shadersLen	= DE_LENGTH_OF_ARRAY(shaders);
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLsizei			numShaders	= 0;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			ret			= 0;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl().getAttachedShaders(program, shadersLen, &numShaders, shaders);
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// There should ever be at most one attached shader in normal use, but if
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// something is wrong, the temporary vertex shader might not have been
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// detached properly, so let's find the fragment shader explicitly.
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < de::min<GLsizei>(shadersLen, numShaders); ++ndx)
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint shaderType = GL_NONE;
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getShaderiv(shaders[ndx], GL_SHADER_TYPE, &shaderType);
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (shaderType == GL_FRAGMENT_SHADER)
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ret = shaders[ndx];
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid setViewport (const RenderContext& renderCtx, const Rectangle& rect)
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderCtx.getFunctions().viewport(rect.x, rect.y, rect.width, rect.height);
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid readRectangle (const RenderContext& renderCtx, const Rectangle& rect, Surface& dst)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst.setSize(rect.width, rect.height);
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(renderCtx, rect.x, rect.y, dst.getAccess());
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRectangle randomViewport (const RenderContext& ctx, GLint maxWidth, GLint maxHeight,
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						  Random& rnd)
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RenderTarget&	target	= ctx.getRenderTarget();
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLint			width	= de::min(target.getWidth(), maxWidth);
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLint			xOff	= rnd.getInt(0, width - maxWidth);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLint			height	= de::min(target.getHeight(), maxHeight);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLint			yOff	= rnd.getInt(0, height - maxHeight);
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Rectangle(xOff, yOff, width, height);
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgramInputAttacher::drawContainer (GLuint program, Surface& dst)
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float	s_vertices[6]	= { -1.0, 0.0, 1.0, 1.0, 0.0, -1.0 };
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random				rnd				(program);
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CheckedShader		vtxShader		(getRenderContext(),
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 SHADERTYPE_VERTEX, s_vertexShaderSrc);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Rectangle		viewport		= randomViewport(getRenderContext(),
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 VIEWPORT_SIZE, VIEWPORT_SIZE, rnd);
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl().attachShader(program, vtxShader.getShader());
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl().linkProgram(program);
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint linkStatus = 0;
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().getProgramiv(program, GL_LINK_STATUS, &linkStatus);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(linkStatus != 0);
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "// Attached a temporary vertex shader and linked program " << program
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setViewport(getRenderContext(), viewport);
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message << "// Positioned viewport randomly" << TestLog::EndMessage;
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(program);
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint posLoc = gl().getAttribLocation(program, "pos");
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(posLoc >= 0);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().enableVertexAttribArray(posLoc);
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().clearColor(0, 0, 0, 1);
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().vertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, s_vertices);
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().drawArrays(GL_TRIANGLES, 0, 3);
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl().disableVertexAttribArray(posLoc);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log () << TestLog::Message << "// Drew a fixed triangle" << TestLog::EndMessage;
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(0);
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readRectangle(getRenderContext(), viewport, dst);
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message << "// Copied viewport to output image" << TestLog::EndMessage;
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl().detachShader(program, vtxShader.getShader());
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message << "// Removed temporary vertex shader" << TestLog::EndMessage;
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryES2Types::ES2Types (const Context& ctx)
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Types			(ctx)
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_bufferBind	(ctx, &CallLogWrapper::glBindBuffer,
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_bufferType	(ctx, "buffer", &CallLogWrapper::glGenBuffers,
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glDeleteBuffers,
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glIsBuffer, &m_bufferBind)
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureBind	(ctx, &CallLogWrapper::glBindTexture, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D)
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureType	(ctx, "texture", &CallLogWrapper::glGenTextures,
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glDeleteTextures,
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glIsTexture, &m_textureBind)
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboBind		(ctx, &CallLogWrapper::glBindRenderbuffer,
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 GL_RENDERBUFFER, GL_RENDERBUFFER_BINDING)
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboType		(ctx, "renderbuffer",
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glGenRenderbuffers,
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glDeleteRenderbuffers,
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glIsRenderbuffer, &m_rboBind)
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fboBind		(ctx, &CallLogWrapper::glBindFramebuffer,
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING)
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fboType		(ctx, "framebuffer",
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glGenFramebuffers,
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glDeleteFramebuffers,
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 &CallLogWrapper::glIsFramebuffer, &m_fboBind)
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderType	(ctx)
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_programType	(ctx)
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texFboAtt	(ctx, m_textureType, m_fboType)
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texFboInAtt	(m_texFboAtt)
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texFboOutAtt(m_texFboAtt)
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboFboAtt	(ctx, m_rboType, m_fboType)
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboFboInAtt	(m_rboFboAtt)
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rboFboOutAtt(m_rboFboAtt)
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderAtt	(ctx, m_shaderType, m_programType)
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderInAtt	(m_shaderAtt)
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type* const types[] =
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		&m_bufferType, &m_textureType, &m_rboType, &m_fboType, &m_shaderType, &m_programType
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_types.insert(m_types.end(), DE_ARRAY_BEGIN(types), DE_ARRAY_END(types));
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attachers.push_back(&m_texFboAtt);
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attachers.push_back(&m_rboFboAtt);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attachers.push_back(&m_shaderAtt);
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_inAttachers.push_back(&m_texFboInAtt);
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_inAttachers.push_back(&m_rboFboInAtt);
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_inAttachers.push_back(&m_shaderInAtt);
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_outAttachers.push_back(&m_texFboOutAtt);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_outAttachers.push_back(&m_rboFboOutAtt);
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Name
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Name		(Type& type) : m_type(type), m_name(type.gen()) {}
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Name		(Type& type, GLuint name) : m_type(type), m_name(name) {}
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				~Name		(void) { m_type.release(m_name); }
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint		operator*	(void) const { return m_name; }
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			m_type;
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	m_name;
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ResultCollector
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ResultCollector		(TestContext& testCtx);
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			check				(bool cond, const char* msg);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			fail				(const char* msg);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			warn				(const char* msg);
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~ResultCollector	(void);
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			addResult			(qpTestResult result, const char* msg);
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestContext&	m_testCtx;
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		m_log;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestResult	m_result;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		m_message;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryResultCollector::ResultCollector (TestContext& testCtx)
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_testCtx		(testCtx)
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_log			(testCtx.getLog())
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_result		(QP_TEST_RESULT_PASS)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_message		("Pass")
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ResultCollector::check (bool cond, const char* msg)
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!cond)
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fail(msg);
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return cond;
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ResultCollector::addResult (qpTestResult result, const char* msg)
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_log << TestLog::Message << "// Fail: " << msg << TestLog::EndMessage;
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_result == QP_TEST_RESULT_PASS)
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_result = result;
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_message = msg;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (result == QP_TEST_RESULT_FAIL)
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_result = result;
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_message = "Multiple problems, see log for details";
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ResultCollector::fail (const char* msg)
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addResult(QP_TEST_RESULT_FAIL, msg);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ResultCollector::warn (const char* msg)
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addResult(QP_TEST_RESULT_QUALITY_WARNING, msg);
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryResultCollector::~ResultCollector (void)
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(m_result, m_message);
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TestBase : public TestCase, protected CallLogWrapper
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							TestBase			(const char*	name,
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*	description,
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const Context&	ctx);
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Copy ContextWrapper since MI (except for CallLogWrapper) is a no-no.
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Context&			getContext			(void) const { return m_ctx; }
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RenderContext&	getRenderContext	(void) const { return m_ctx.getRenderContext(); }
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Functions&		gl					(void) const { return m_ctx.gl(); }
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log					(void) const { return m_ctx.log(); }
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init				(void);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Context					m_ctx;
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random					m_rnd;
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestBase::TestBase (const char* name, const char* description, const Context& ctx)
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(ctx.getTestContext(), name, description)
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper	(ctx.gl(), ctx.log())
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_ctx				(ctx)
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rnd				(deStringHash(name))
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestBase::init (void)
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_rnd = Random(deStringHash(getName()));
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LifeTest : public TestBase
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef void			(LifeTest::*TestFunction)	(void);
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							LifeTest					(const char*	name,
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 const char*	description,
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 Type&			type,
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 TestFunction 	test)
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								: TestBase		(name, description, type.getContext())
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								, m_type		(type)
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								, m_test		(test) {}
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate						(void);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testGen						(void);
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDelete					(void);
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testBind					(void);
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeleteBound				(void);
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testBindNoGen				(void);
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeleteUsed				(void);
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Binder&					binder						(void) { return *m_type.binder(); }
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&					m_type;
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestFunction			m_test;
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult LifeTest::iterate (void)
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	(this->*m_test)();
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testGen (void)
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			name	(m_type);
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type.genCreates())
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(m_type.exists(*name), "Gen* should have created an object, but didn't");
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(!m_type.exists(*name), "Gen* should not have created an object, but did");
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testDelete (void)
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			name	= m_type.gen();
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type.release(name);
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(!m_type.exists(name), "Object still exists after deletion");
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testBind (void)
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			name	(m_type);
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder().bind(*name);
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl().getError(), "Bind failed");
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(m_type.exists(*name), "Object does not exist after binding");
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder().bind(0);
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testDeleteBound (void)
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	id		= m_type.gen();
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder().bind(id);
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type.release(id);
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type.nameLingers())
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(binder().getBinding() == id,
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object did not retain binding");
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(m_type.exists(id),
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object made its name invalid");
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(m_type.isDeleteFlagged(id),
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object did not flag the object for deletion");
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		binder().bind(0);
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(binder().getBinding() == 0,
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object did not remove binding");
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(!m_type.exists(id),
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Deleting bound object did not make its name invalid");
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		binder().bind(0);
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(binder().getBinding() == 0, "Unbinding didn't remove binding");
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(!m_type.exists(id), "Name is still valid after deleting and unbinding");
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testBindNoGen (void)
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors	(getTestContext());
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	id		= m_rnd.getUint32();
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!errors.check(!m_type.exists(id), "Randomly chosen identifier already exists"))
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			name	(m_type, id);
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	binder().bind(*name);
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (binder().genRequired())
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(glGetError() == GL_INVALID_OPERATION,
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Did not fail when binding a name not generated by Gen* call");
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(!m_type.exists(*name),
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Bind* created an object for a name not generated by a Gen* call");
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(glGetError() == GL_NO_ERROR,
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Failed when binding a name not generated by Gen* call");
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(m_type.exists(*name),
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Object was not created by the Bind* call");
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LifeTest::testDeleteUsed (void)
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors(getTestContext());
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			programId = 0;
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CheckedShader	vtxShader	(getRenderContext(),
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 SHADERTYPE_VERTEX, s_vertexShaderSrc);
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CheckedShader	fragShader	(getRenderContext(),
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 SHADERTYPE_FRAGMENT, s_fragmentShaderSrc);
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CheckedProgram	program		(getRenderContext(),
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 vtxShader.getShader(), fragShader.getShader());
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programId = program.getProgram();
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message << "// Created and linked program " << programId
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL_ERROR(glUseProgram(programId), gl().getError());
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message << "// Deleted program " << programId
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(glIsProgram(programId));
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint deleteFlagged = 0;
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetProgramiv(programId, GL_DELETE_STATUS, &deleteFlagged);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(deleteFlagged != 0, "Program object was not flagged as deleted");
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL_ERROR(glUseProgram(0), gl().getError());
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(!gl().isProgram(programId),
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Deleted program name still valid after being made non-current");
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AttachmentTest : public TestBase
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef void			(AttachmentTest::*TestFunction)	(void);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							AttachmentTest					(const char*	name,
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*	description,
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 Attacher&		attacher,
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 TestFunction	test)
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								: TestBase		(name, description, attacher.getContext())
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								, m_attacher	(attacher)
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								, m_test		(test) {}
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate							(void);
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeletedNames				(void);
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeletedBinding				(void);
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					testDeletedReattach				(void);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Attacher&				m_attacher;
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestFunction		m_test;
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult AttachmentTest::iterate (void)
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	(this->*m_test)();
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint getAttachment (Attacher& attacher, GLuint container)
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint queriedAttachment = attacher.getAttachment(container);
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attacher.log() << TestLog::Message
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   << "// Result of query for " << attacher.getElementType().getName()
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   << " attached to " << attacher.getContainerType().getName() << " "
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   << container << ": " << queriedAttachment << "."
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   << TestLog::EndMessage;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return queriedAttachment;
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AttachmentTest::testDeletedNames (void)
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			elemType		= m_attacher.getElementType();
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			containerType	= m_attacher.getContainerType();
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			container		(containerType);
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors			(getTestContext());
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			elementId		= 0;
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Name element(elemType);
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		elementId = *element;
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_attacher.initAttachment(0, *element);
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_attacher.attach(*element, *container);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(getAttachment(m_attacher, *container) == elementId,
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Attachment name not returned by query even before deletion.");
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// "Such a container or other context may continue using the object, and
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// may still contain state identifying its name as being currently bound"
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// We here interpret "may" to mean that whenever the container has a
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// deleted object attached to it, a query will return that object's former
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// name.
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(getAttachment(m_attacher, *container) == elementId,
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Attachment name not returned by query after attachment was deleted.");
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (elemType.nameLingers())
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(elemType.exists(elementId),
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Attached object name no longer valid after deletion.");
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(!elemType.exists(elementId),
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 "Attached object name still valid after deletion.");
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attacher.detach(elementId, *container);
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(getAttachment(m_attacher, *container) == 0,
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Attachment name returned by query even after detachment.");
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(!elemType.exists(elementId),
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Deleted attached object name still usable after detachment.");
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InputAttachmentTest : public TestBase
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					InputAttachmentTest	(const char*	name,
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const char*	description,
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 InputAttacher&	inputAttacher)
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						: TestBase			(name, description, inputAttacher.getContext())
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						, m_inputAttacher	(inputAttacher) {}
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate				(void);
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InputAttacher&	m_inputAttacher;
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLuint replaceName (Type& type, GLuint oldName, TestLog& log)
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Binder* const	binder		= type.binder();
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			genRequired	= binder == DE_NULL || binder->genRequired();
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (genRequired)
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return type.gen();
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "// Type does not require Gen* for binding, reusing old id " << oldName << "."
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return oldName;
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult InputAttachmentTest::iterate (void)
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Attacher&		attacher		= m_inputAttacher.getAttacher();
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			containerType	= attacher.getContainerType();
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			elementType		= attacher.getElementType();
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			container		(containerType);
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			elementId		= 0;
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	refSeed			= m_rnd.getUint32();
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	newSeed			= m_rnd.getUint32();
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors			(getTestContext());
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			refSurface;		// Surface from drawing with refSeed-seeded attachment
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			delSurface;		// Surface from drawing with deleted refSeed attachment
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			newSurface;		// Surface from drawing with newSeed-seeded attachment
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "Testing if writing to a newly created object modifies a deleted attachment"
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ScopedLogSection	section	(log(),
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 "Write to original", "Writing to an original attachment");
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Name			element	(elementType);
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		elementId = *element;
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.initAttachment(refSeed, elementId);
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.attach(elementId, *container);
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_inputAttacher.drawContainer(*container, refSurface);
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// element gets deleted here
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message << "// Deleting attachment";
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ScopedLogSection section	(log(), "Write to new",
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 "Writing to a new attachment after deleting the original");
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint	newId		= replaceName(elementType, elementId, log());
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Name		newElement	(elementType, newId);
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.initAttachment(newSeed, newId);
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_inputAttacher.drawContainer(*container, delSurface);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.detach(elementId, *container);
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.attach(newId, *container);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_inputAttacher.drawContainer(*container, newSurface);
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.detach(newId, *container);
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool surfacesMatch = tcu::pixelThresholdCompare(
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log(), "Reading from deleted",
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Comparison result from reading from a container with a deleted attachment "
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"before and after writing to a fresh object.",
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			refSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		errors.check(
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			surfacesMatch,
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Writing to a fresh object modified the container with a deleted attachment.");
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!surfacesMatch)
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log() << TestLog::Image("New attachment",
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									"Container state after attached to the fresh object",
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									newSurface);
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass OutputAttachmentTest : public TestBase
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						OutputAttachmentTest			(const char*		name,
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 const char*		description,
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 OutputAttacher&	outputAttacher)
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: TestBase			(name, description,
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 outputAttacher.getContext())
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							, m_outputAttacher	(outputAttacher) {}
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate							(void);
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OutputAttacher&		m_outputAttacher;
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult OutputAttachmentTest::iterate (void)
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Attacher&		attacher		= m_outputAttacher.getAttacher();
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			containerType	= attacher.getContainerType();
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type&			elementType		= attacher.getElementType();
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Name			container		(containerType);
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint			elementId		= 0;
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	refSeed			= m_rnd.getUint32();
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLuint	newSeed			= m_rnd.getUint32();
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultCollector	errors			(getTestContext());
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			refSurface;		// Surface drawn from attachment to refSeed container
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			newSurface;		// Surface drawn from attachment to newSeed container
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			delSurface;		// Like newSurface, after writing to a deleted attachment
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log() << TestLog::Message
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "Testing if writing to a container with a deleted attachment "
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << "modifies a newly created object"
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		  << TestLog::EndMessage;
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ScopedLogSection	section	(log(), "Write to existing",
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 "Writing to a container with an existing attachment");
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Name			element	(elementType);
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		elementId = *element;
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.initAttachment(0, elementId);
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.attach(elementId, *container);
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// For reference purposes, make note of what refSeed looks like.
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.setupContainer(refSeed, *container);
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.drawAttachment(elementId, refSurface);
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ScopedLogSection	section		(log(), "Write to deleted",
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 "Writing to a container after deletion of attachment");
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint		newId		= replaceName(elementType, elementId, log());
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Name			newElement	(elementType, newId);
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << "Creating a new object " << newId
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << "Recording state of new object before writing to container"
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attacher.initAttachment(newSeed, newId);
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.drawAttachment(newId, newSurface);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Message
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << "Writing to container"
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  << TestLog::EndMessage;
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Now re-write refSeed to the container.
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.setupContainer(refSeed, *container);
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Does it affect the newly created attachment object?
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_outputAttacher.drawAttachment(newId, delSurface);
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attacher.detach(elementId, *container);
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool surfacesMatch = tcu::pixelThresholdCompare(
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log(), "Writing to deleted",
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"Comparison result from reading from a fresh object before and after "
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"writing to a container with a deleted attachment",
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		newSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errors.check(surfacesMatch,
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 "Writing to container with deleted attachment modified a new object.");
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!surfacesMatch)
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log() << TestLog::Image(
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Original attachment",
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Result of container modification on original attachment before deletion.",
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			refSurface);
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct LifeTestSpec
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*				name;
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LifeTest::TestFunction	func;
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					needBind;
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMovePtr<TestCaseGroup> createLifeTestGroup (TestContext& testCtx,
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											const LifeTestSpec& spec,
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											const vector<Type*>& types)
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MovePtr<TestCaseGroup> group(new TestCaseGroup(testCtx, spec.name, spec.name));
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Type*>::const_iterator it = types.begin(); it != types.end(); ++it)
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Type& type = **it;
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* name = type.getName();
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!spec.needBind || type.binder() != DE_NULL)
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			group->addChild(new LifeTest(name, name, type, spec.func));
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return group;
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const LifeTestSpec s_lifeTests[] =
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "gen",			&LifeTest::testGen,			false	},
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "delete",			&LifeTest::testDelete,		false	},
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "bind",			&LifeTest::testBind,		true	},
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "delete_bound",	&LifeTest::testDeleteBound,	true	},
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ "bind_no_gen",	&LifeTest::testBindNoGen,	true	},
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring attacherName (Attacher& attacher)
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ostringstream os;
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	os << attacher.getElementType().getName() << "_" <<  attacher.getContainerType().getName();
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return os.str();
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid addTestCases (TestCaseGroup& group, Types& types)
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestContext& testCtx = types.getTestContext();
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (const LifeTestSpec* it = DE_ARRAY_BEGIN(s_lifeTests);
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 it != DE_ARRAY_END(s_lifeTests); ++it)
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group.addChild(createLifeTestGroup(testCtx, *it, types.getTypes()).release());
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const delUsedGroup =
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			new TestCaseGroup(testCtx, "delete_used", "Delete current program");
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group.addChild(delUsedGroup);
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delUsedGroup->addChild(
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			new LifeTest("program", "program", types.getProgramType(),
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 &LifeTest::testDeleteUsed));
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const	attGroup	= new TestCaseGroup(
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testCtx, "attach", "Attachment tests");
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group.addChild(attGroup);
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const	nameGroup	= new TestCaseGroup(
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				testCtx, "deleted_name", "Name of deleted attachment");
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attGroup->addChild(nameGroup);
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<Attacher*>& atts = types.getAttachers();
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<Attacher*>::const_iterator it = atts.begin(); it != atts.end(); ++it)
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string name = attacherName(**it);
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				nameGroup->addChild(new AttachmentTest(name.c_str(), name.c_str(), **it,
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   &AttachmentTest::testDeletedNames));
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* inputGroup = new TestCaseGroup(
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				testCtx, "deleted_input", "Input from deleted attachment");
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attGroup->addChild(inputGroup);
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<InputAttacher*>& inAtts = types.getInputAttachers();
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<InputAttacher*>::const_iterator it = inAtts.begin();
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 it != inAtts.end(); ++it)
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string name = attacherName((*it)->getAttacher());
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inputGroup->addChild(new InputAttachmentTest(name.c_str(), name.c_str(), **it));
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* outputGroup = new TestCaseGroup(
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				testCtx, "deleted_output", "Output to deleted attachment");
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attGroup->addChild(outputGroup);
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<OutputAttacher*>& outAtts = types.getOutputAttachers();
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<OutputAttacher*>::const_iterator it = outAtts.begin();
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 it != outAtts.end(); ++it)
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string name = attacherName((*it)->getAttacher());
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				outputGroup->addChild(new OutputAttachmentTest(name.c_str(), name.c_str(),
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   **it));
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // details
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // LifetimeTests
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gls
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1249