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 Parametrized, long-running stress case.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [2013-06-27 nuutti] Do certain things in a cleaner and less
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *							 confusing way, such as the "redundant buffer
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *							 factor" thing in LongStressCase.
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsLongStressCase.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuStringTemplate.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deClock.h"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glw.h"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iomanip>
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iomanip>
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec2;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec3;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec4;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TextureLevel;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TextureFormat;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::ConstPixelBufferAccess;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::CubeFace;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::SharedPtr;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::Random;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::toString;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gls
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
78c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketusing glu::TextureTestUtil::TextureType;
79c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketusing glu::TextureTestUtil::TEXTURETYPE_2D;
80c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketusing glu::TextureTestUtil::TEXTURETYPE_CUBE;
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float Mi = (float)(1<<20);
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const deUint32 bufferUsages[] =
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_STATIC_DRAW,
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_STREAM_DRAW,
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DYNAMIC_DRAW,
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_STATIC_READ,
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_STREAM_READ,
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DYNAMIC_READ,
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_STATIC_COPY,
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_STREAM_COPY,
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DYNAMIC_COPY
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const deUint32 bufferUsagesGLES2[] =
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_STATIC_DRAW,
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DYNAMIC_DRAW,
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_STREAM_DRAW
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const deUint32 bufferTargets[] =
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_ARRAY_BUFFER,
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_ELEMENT_ARRAY_BUFFER,
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_COPY_READ_BUFFER,
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_COPY_WRITE_BUFFER,
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_PIXEL_PACK_BUFFER,
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_PIXEL_UNPACK_BUFFER,
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_TRANSFORM_FEEDBACK_BUFFER,
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_UNIFORM_BUFFER
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const deUint32 bufferTargetsGLES2[] =
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_ARRAY_BUFFER,
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_ELEMENT_ARRAY_BUFFER
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int computePixelStore (const TextureFormat& format)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int pixelSize = format.getPixelSize();
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (deIsPowerOfTwo32(pixelSize))
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return de::min(pixelSize, 8);
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 1;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getNumIterations (const tcu::TestContext& testCtx, const int defaultNumIterations)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int cmdLineVal = testCtx.getCommandLine().getTestIterationCount();
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return cmdLineVal == 0 ? defaultNumIterations : cmdLineVal;
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float triangleArea (const Vec2& a, const Vec2& b, const Vec2& c)
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 ab = b-a;
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 ac = c-a;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 0.5f * tcu::length(ab.x()*ac.y() - ab.y()*ac.x());
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string mangleShaderNames (const string& source, const string& manglingSuffix)
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> m;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m["NS"] = manglingSuffix;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::StringTemplate(source.c_str()).specialize(m);
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int N>
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T randomChoose (Random& rnd, const T (&arr)[N])
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return rnd.choose<T>(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr));
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int nextDivisible (const int x, const int div)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(x >= 0);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(div >= 1);
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return x == 0 ? 0 : x-1 + div - (x-1) % div;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string getTimeStr (const deUint64 seconds)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint64		m = seconds / 60;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint64		h = m / 60;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint64		d = h / 24;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	res;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	res << d << "d " << h%24 << "h " << m%60 << "m " << seconds%60 << "s";
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res.str();
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string probabilityStr (const float prob)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return prob == 0.0f ? "never"	:
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   prob == 1.0f ? "ALWAYS"	:
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   de::floatToString(prob*100.0f, 0) + "%";
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline deUint32 randomBufferTarget (Random& rnd, const bool isGLES3)
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isGLES3 ? randomChoose(rnd, bufferTargets) : randomChoose(rnd, bufferTargetsGLES2);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline deUint32 randomBufferUsage (Random& rnd, const bool isGLES3)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isGLES3 ? randomChoose(rnd, bufferUsages) : randomChoose(rnd, bufferUsagesGLES2);
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline deUint32 cubeFaceToGLFace (tcu::CubeFace face)
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_X: return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_X: return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_Y: return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_Y: return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_Z: return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_Z: return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return GL_NONE;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_DEBUG)
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isMatchingGLInternalFormat (const deUint32 internalFormat, const TextureFormat& texFormat)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (internalFormat)
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Unsized formats.
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_RGBA:				return texFormat.order == TextureFormat::RGBA &&
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   (texFormat.type == TextureFormat::UNORM_INT8			||
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												texFormat.type == TextureFormat::UNORM_SHORT_4444	||
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												texFormat.type == TextureFormat::UNORM_SHORT_5551);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_RGB:				return texFormat.order == TextureFormat::RGB &&
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   (texFormat.type == TextureFormat::UNORM_INT8			||
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												texFormat.type == TextureFormat::UNORM_SHORT_565);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LUMINANCE_ALPHA:	return texFormat.order == TextureFormat::LA && texFormat.type == TextureFormat::UNORM_INT8;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LUMINANCE:			return texFormat.order == TextureFormat::L && texFormat.type == TextureFormat::UNORM_INT8;
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ALPHA:				return texFormat.order == TextureFormat::A && texFormat.type == TextureFormat::UNORM_INT8;
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Sized formats.
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return glu::mapGLInternalFormat(internalFormat) == texFormat;
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // DE_DEBUG
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool compileShader (const deUint32 shaderGL)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glCompileShader(shaderGL);
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int success = GL_FALSE;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetShaderiv(shaderGL, GL_COMPILE_STATUS, &success);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success == GL_TRUE;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool linkProgram (const deUint32 programGL)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glLinkProgram(programGL);
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int success = GL_FALSE;
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetProgramiv(programGL, GL_LINK_STATUS, &success);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success == GL_TRUE;
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string getShaderInfoLog (const deUint32 shaderGL)
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				infoLogLen = 0;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<char>	infoLog;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetShaderiv(shaderGL, GL_INFO_LOG_LENGTH, &infoLogLen);
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	infoLog.resize(infoLogLen+1);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetShaderInfoLog(shaderGL, (int)infoLog.size(), DE_NULL, &infoLog[0]);
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return &infoLog[0];
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string getProgramInfoLog (const deUint32 programGL)
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				infoLogLen = 0;
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<char>	infoLog;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetProgramiv(programGL, GL_INFO_LOG_LENGTH, &infoLogLen);
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	infoLog.resize(infoLogLen+1);
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetProgramInfoLog(programGL, (int)infoLog.size(), DE_NULL, &infoLog[0]);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return &infoLog[0];
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace LongStressCaseInternal
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// A hacky-ish class for drawing text on screen as GL quads.
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DebugInfoRenderer
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								DebugInfoRenderer		(const glu::RenderContext& ctx);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~DebugInfoRenderer		(void) { delete m_prog; }
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						drawInfo				(deUint64 secondsElapsed, int texMem, int maxTexMem, int bufMem, int maxBufMem, int iterNdx);
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								DebugInfoRenderer		(const DebugInfoRenderer&);
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DebugInfoRenderer&			operator=				(const DebugInfoRenderer&);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						render					(void);
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						addTextToBuffer			(const string& text, int yOffset);
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&	m_ctx;
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram*	m_prog;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>				m_posBuf;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint16>			m_ndxBuf;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DebugInfoRenderer::drawInfo (const deUint64 secondsElapsed, const int texMem, const int maxTexMem, const int bufMem, const int maxBufMem, const int iterNdx)
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint64 m = secondsElapsed / 60;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint64 h = m / 60;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint64 d = h / 24;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::ostringstream text;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		text << std::setw(2) << std::setfill('0') << d << ":"
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << std::setw(2) << std::setfill('0') << h % 24 << ":"
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << std::setw(2) << std::setfill('0') << m % 60 << ":"
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << std::setw(2) << std::setfill('0') << secondsElapsed % 60;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addTextToBuffer(text.str(), 0);
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		text.str("");
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		text << std::fixed << std::setprecision(2) << (float)texMem/Mi << "/" << (float)maxTexMem/Mi;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addTextToBuffer(text.str(), 1);
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		text.str("");
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		text << std::fixed << std::setprecision(2) << (float)bufMem/Mi << "/" << (float)maxBufMem/Mi;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addTextToBuffer(text.str(), 2);
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		text.str("");
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		text << std::setw(0) << iterNdx;
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addTextToBuffer(text.str(), 3);
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	render();
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDebugInfoRenderer::DebugInfoRenderer (const glu::RenderContext& ctx)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_ctx			(ctx)
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_prog		(DE_NULL)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_prog);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_prog = new glu::ShaderProgram(ctx, glu::makeVtxFragSources(
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec2 a_pos;\n"
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = vec4(a_pos, -1.0, 1.0);\n"
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n",
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main(void)\n"
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"));
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DebugInfoRenderer::addTextToBuffer (const string& text, const int yOffset)
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char		characters[]	= "0123456789.:/";
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numCharacters	= DE_LENGTH_OF_ARRAY(characters)-1; // \note -1 for null byte.
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				charWid			= 6;
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				charHei			= 6;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const string		charsStr		(characters);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char font[numCharacters*charWid*charHei + 1]=
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		" #### ""   #  "" #### ""##### ""   #  ""######"" #####""######"" #### "" #### ""      ""  ##  ""     #"
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#    #""  ##  ""#    #""     #""  #   ""#     ""#     ""    # ""#    #""#    #""      ""  ##  ""    # "
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#    #""   #  ""    # ""  ### "" #  # "" #### ""# ### ""   #  "" #### "" #####""      ""      ""   #  "
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#    #""   #  ""   #  ""     #""######""     #""##   #""  #   ""#    #""     #""      ""  ##  ""  #   "
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#    #""   #  ""  #   ""#    #""    # ""#    #""#    #"" #    ""#    #""   ## ""  ##  ""  ##  "" #    "
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		" #### ""  ### ""######"" #### ""    # "" #### "" #### ""#     "" #### ""###   ""  ##  ""      ""#     ";
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndxInText = 0; ndxInText < (int)text.size(); ndxInText++)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int ndxInCharset	= (int)charsStr.find(text[ndxInText]);
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(ndxInCharset < numCharacters);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int fontXStart	= ndxInCharset*charWid;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < charHei; y++)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float ay = -1.0f + (float)(y + 0 + yOffset*(charHei+2))*0.1f/(float)(charHei+2);
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float by = -1.0f + (float)(y + 1 + yOffset*(charHei+2))*0.1f/(float)(charHei+2);
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < charWid; x++)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note Text is mirrored in x direction since on most(?) mobile devices the image is mirrored(?).
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float ax = 1.0f - (float)(x + 0 + ndxInText*(charWid+2))*0.1f/(float)(charWid+2);
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float bx = 1.0f - (float)(x + 1 + ndxInText*(charWid+2))*0.1f/(float)(charWid+2);
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (font[y*numCharacters*charWid + fontXStart + x] != ' ')
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int vtxNdx = (int)m_posBuf.size()/2;
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
388c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry					m_ndxBuf.push_back(deUint16(vtxNdx+0));
389c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry					m_ndxBuf.push_back(deUint16(vtxNdx+1));
390c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry					m_ndxBuf.push_back(deUint16(vtxNdx+2));
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
392c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry					m_ndxBuf.push_back(deUint16(vtxNdx+2));
393c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry					m_ndxBuf.push_back(deUint16(vtxNdx+1));
394c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry					m_ndxBuf.push_back(deUint16(vtxNdx+3));
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_posBuf.push_back(ax);
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_posBuf.push_back(ay);
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_posBuf.push_back(bx);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_posBuf.push_back(ay);
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_posBuf.push_back(ax);
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_posBuf.push_back(by);
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_posBuf.push_back(bx);
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_posBuf.push_back(by);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DebugInfoRenderer::render (void)
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int prog		= m_prog->getProgram();
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int posloc	= glGetAttribLocation(prog, "a_pos");
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(prog);
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindBuffer(GL_ARRAY_BUFFER, 0);
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glEnableVertexAttribArray(posloc);
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glVertexAttribPointer(posloc, 2, GL_FLOAT, 0, 0, &m_posBuf[0]);
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDrawElements(GL_TRIANGLES, (int)m_ndxBuf.size(), GL_UNSIGNED_SHORT, &m_ndxBuf[0]);
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDisableVertexAttribArray(posloc);
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_posBuf.clear();
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_ndxBuf.clear();
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Texture object helper class
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Each Texture owns a GL texture object that is created when the Texture
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is constructed and deleted when it's destructed. The class provides some
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * convenience interface functions to e.g. upload texture data to the GL.
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * In addition, the class tracks the approximate amount of GL memory likely
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * used by the corresponding GL texture object; get this with
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * getApproxMemUsage(). Also, getApproxMemUsageDiff() returns N-M, where N
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is the value that getApproxMemUsage() would return after a call to
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * setData() with arguments corresponding to those given to
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * getApproxMemUsageDiff(), and M is the value currently returned by
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * getApproxMemUsage(). This can be used to check if we need to free some
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * other memory before performing the setData() call, in case we have an
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * upper limit on the amount of memory we want to use.
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						Texture					(TextureType type);
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~Texture				(void);
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Functions that may change the value returned by getApproxMemUsage().
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setData					(const ConstPixelBufferAccess& src, int width, int height, deUint32 internalFormat, bool useMipmap);
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Functions that don't change the value returned by getApproxMemUsage().
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setSubData				(const ConstPixelBufferAccess& src, int xOff, int yOff, int width, int height) const;
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				toUnit					(int unit) const;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setFilter				(deUint32 min, deUint32 mag) const;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setWrap					(deUint32 s, deUint32 t) const;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getApproxMemUsage		(void) const { return m_dataSizeApprox; }
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getApproxMemUsageDiff	(int width, int height, deUint32 internalFormat, bool useMipmap) const;
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						Texture					(const Texture&); // Not allowed.
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture&			operator=				(const Texture&); // Not allowed.
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static deUint32		genTexture				(void) { deUint32 tex = 0; glGenTextures(1, &tex); return tex; }
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			getGLBindTarget			(void) const { DE_ASSERT(m_type == TEXTURETYPE_2D || m_type == TEXTURETYPE_CUBE); return m_type == TEXTURETYPE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP; }
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureType	m_type;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32		m_textureGL;
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numMipLevels;
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			m_internalFormat;
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_dataSizeApprox;
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture::Texture (const TextureType type)
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type			(type)
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureGL		(genTexture())
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numMipLevels	(0)
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat	(0)
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataSizeApprox	(0)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture::~Texture (void)
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDeleteTextures(1, &m_textureGL);
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint Texture::getApproxMemUsageDiff (const int width, const int height, const deUint32 internalFormat, const bool useMipmap) const
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	numLevels				= useMipmap ? deLog2Floor32(de::max(width, height))+1 : 1;
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	pixelSize				= internalFormat == GL_RGBA		? 4
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: internalFormat == GL_RGB		? 3
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: internalFormat == GL_ALPHA	? 1
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: glu::mapGLInternalFormat(internalFormat).getPixelSize();
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			memUsageApproxAfter		= 0;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int level = 0; level < numLevels; level++)
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		memUsageApproxAfter += de::max(1, width>>level) * de::max(1, height>>level) * pixelSize * (m_type == TEXTURETYPE_CUBE ? 6 : 1);
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return memUsageApproxAfter - getApproxMemUsage();
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture::setData (const ConstPixelBufferAccess& src, const int width, const int height, const deUint32 internalFormat, const bool useMipmap)
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_type != TEXTURETYPE_CUBE || width == height);
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!useMipmap || (deIsPowerOfTwo32(width) && deIsPowerOfTwo32(height)));
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureFormat&		format		= src.getFormat();
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::TransferFormat	transfer	= glu::getTransferFormat(format);
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numMipLevels = useMipmap ? deLog2Floor32(de::max(width, height))+1 : 1;
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_internalFormat = internalFormat;
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_dataSizeApprox = width * height * format.getPixelSize() * (m_type == TEXTURETYPE_CUBE ? 6 : 1);
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getRowPitch() == format.getPixelSize()*src.getWidth());
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isMatchingGLInternalFormat(internalFormat, format));
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(width <= src.getWidth() && height <= src.getHeight());
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glPixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(format));
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TEXTURETYPE_2D)
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_dataSizeApprox = 0;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindTexture(GL_TEXTURE_2D, m_textureGL);
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < m_numMipLevels; level++)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int levelWid = de::max(1, width>>level);
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int levelHei = de::max(1, height>>level);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_dataSizeApprox += levelWid * levelHei * format.getPixelSize();
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glTexImage2D(GL_TEXTURE_2D, level, internalFormat, levelWid, levelHei, 0, transfer.format, transfer.dataType, src.getDataPtr());
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_type == TEXTURETYPE_CUBE)
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_dataSizeApprox = 0;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindTexture(GL_TEXTURE_CUBE_MAP, m_textureGL);
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < m_numMipLevels; level++)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int levelWid = de::max(1, width>>level);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int levelHei = de::max(1, height>>level);
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_dataSizeApprox += 6 * levelWid * levelHei * format.getPixelSize();
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glTexImage2D(cubeFaceToGLFace((CubeFace)face), level, internalFormat, levelWid, levelHei, 0, transfer.format, transfer.dataType, src.getDataPtr());
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture::setSubData (const ConstPixelBufferAccess& src, const int xOff, const int yOff, const int width, const int height) const
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureFormat&		format		= src.getFormat();
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::TransferFormat	transfer	= glu::getTransferFormat(format);
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getRowPitch() == format.getPixelSize()*src.getWidth());
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isMatchingGLInternalFormat(m_internalFormat, format));
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(width <= src.getWidth() && height <= src.getHeight());
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glPixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(format));
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type == TEXTURETYPE_2D)
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindTexture(GL_TEXTURE_2D, m_textureGL);
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < m_numMipLevels; level++)
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glTexSubImage2D(GL_TEXTURE_2D, level, xOff>>level, yOff>>level, de::max(1, width>>level), de::max(1, height>>level), transfer.format, transfer.dataType, src.getDataPtr());
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_type == TEXTURETYPE_CUBE)
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindTexture(GL_TEXTURE_CUBE_MAP, m_textureGL);
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < m_numMipLevels; level++)
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glTexSubImage2D(cubeFaceToGLFace((CubeFace)face), level, xOff>>level, yOff>>level, de::max(1, width>>level), de::max(1, height>>level), transfer.format, transfer.dataType, src.getDataPtr());
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture::setFilter (const deUint32 min, const deUint32 mag) const
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindTexture(getGLBindTarget(), m_textureGL);
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(getGLBindTarget(), GL_TEXTURE_MIN_FILTER, min);
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(getGLBindTarget(), GL_TEXTURE_MAG_FILTER, mag);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture::setWrap (const deUint32 s, const deUint32 t) const
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindTexture(getGLBindTarget(), m_textureGL);
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(getGLBindTarget(), GL_TEXTURE_WRAP_S, s);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(getGLBindTarget(), GL_TEXTURE_WRAP_T, t);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture::toUnit (const int unit) const
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glActiveTexture(GL_TEXTURE0 + unit);
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindTexture(getGLBindTarget(), m_textureGL);
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Buffer object helper class
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Each Buffer owns a GL buffer object that is created when the Buffer
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is constructed and deleted when it's destructed. The class provides some
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * convenience interface functions to e.g. upload buffer data to the GL.
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * In addition, the class tracks the approximate amount of GL memory,
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * similarly to the Texture class (see above). The getApproxMemUsageDiff()
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is also analoguous.
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Buffer
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						Buffer					(void);
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~Buffer					(void);
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Functions that may change the value returned by getApproxMemUsage().
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	template <typename T>
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setData					(const vector<T>& src, const deUint32 target, const deUint32 usage) { setData(&src[0], (int)(src.size()*sizeof(T)), target, usage); }
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setData					(const void* src, int size, deUint32 target, deUint32 usage);
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Functions that don't change the value returned by getApproxMemUsage().
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	template <typename T>
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setSubData				(const vector<T>& src, const int offsetElems, const int numElems, const deUint32 target) { setSubData(&src[offsetElems], offsetElems*(int)sizeof(T), numElems*(int)sizeof(T), target); }
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setSubData				(const void* src, int offsetBytes, int sizeBytes, deUint32 target) const;
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				bind					(const deUint32 target) const { glBindBuffer(target, m_bufferGL); }
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getApproxMemUsage		(void) const { return m_dataSizeApprox; }
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	template <typename T>
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getApproxMemUsageDiff	(const vector<T>& src) const { return getApproxMemUsageDiff((int)(src.size()*sizeof(T))); }
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getApproxMemUsageDiff	(const int sizeBytes) const { return sizeBytes - getApproxMemUsage(); }
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						Buffer					(const Buffer&); // Not allowed.
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Buffer&				operator=				(const Buffer&); // Not allowed.
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static deUint32		genBuffer				(void) { deUint32 buf = 0; glGenBuffers(1, &buf); return buf; }
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32		m_bufferGL;
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_dataSizeApprox;
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBuffer::Buffer (void)
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_bufferGL		(genBuffer())
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataSizeApprox	(0)
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBuffer::~Buffer (void)
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDeleteBuffers(1, &m_bufferGL);
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Buffer::setData (const void* const src, const int size, const deUint32 target, const deUint32 usage)
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bind(target);
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBufferData(target, size, src, usage);
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindBuffer(target, 0);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_dataSizeApprox = size;
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Buffer::setSubData (const void* const src, const int offsetBytes, const int sizeBytes, const deUint32 target) const
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bind(target);
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBufferSubData(target, offsetBytes, sizeBytes, src);
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindBuffer(target, 0);
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Program
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						Program					(void);
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~Program				(void);
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setSources				(const string& vertSource, const string& fragSource);
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				build					(TestLog& log);
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				use						(void) const { DE_ASSERT(m_isBuilt); glUseProgram(m_programGL); }
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setRandomUniforms		(const vector<VarSpec>& uniforms, const string& shaderNameManglingSuffix, Random& rnd) const;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setAttribute			(const Buffer& attrBuf, int attrBufOffset, const VarSpec& attrSpec, const string& shaderNameManglingSuffix) const;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setAttributeClientMem	(const void* attrData, const VarSpec& attrSpec, const string& shaderNameManglingSuffix) const;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				disableAttributeArray	(const VarSpec& attrSpec, const string& shaderNameManglingSuffix) const;
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						Program				(const Program&); // Not allowed.
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Program&			operator=			(const Program&); // Not allowed.
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				m_vertSource;
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				m_fragSource;
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32		m_vertShaderGL;
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32		m_fragShaderGL;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32		m_programGL;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				m_hasSources;
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				m_isBuilt;
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgram::Program (void)
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_vertShaderGL	(glCreateShader(GL_VERTEX_SHADER))
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fragShaderGL	(glCreateShader(GL_FRAGMENT_SHADER))
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_programGL		(glCreateProgram())
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_hasSources		(false)
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isBuilt			(false)
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glAttachShader(m_programGL, m_vertShaderGL);
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glAttachShader(m_programGL, m_fragShaderGL);
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgram::~Program (void)
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDeleteShader(m_vertShaderGL);
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDeleteShader(m_fragShaderGL);
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDeleteProgram(m_programGL);
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::setSources (const string& vertSource, const string& fragSource)
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const vertSourceCstr = vertSource.c_str();
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const fragSourceCstr = fragSource.c_str();
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertSource = vertSource;
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragSource = fragSource;
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note In GLES2 api the source parameter type lacks one const.
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glShaderSource(m_vertShaderGL, 1, (const char**)&vertSourceCstr, DE_NULL);
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glShaderSource(m_fragShaderGL, 1, (const char**)&fragSourceCstr, DE_NULL);
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_hasSources = true;
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::build (TestLog& log)
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_hasSources);
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool vertCompileOk	= compileShader(m_vertShaderGL);
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool fragCompileOk	= compileShader(m_fragShaderGL);
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool attemptLink		= vertCompileOk && fragCompileOk;
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool linkOk			= attemptLink && linkProgram(m_programGL);
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!(vertCompileOk && fragCompileOk && linkOk))
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::ShaderProgram(linkOk, attemptLink ? getProgramInfoLog(m_programGL) : string(""))
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Shader(QP_SHADER_TYPE_VERTEX, m_vertSource, vertCompileOk, getShaderInfoLog(m_vertShaderGL))
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Shader(QP_SHADER_TYPE_FRAGMENT, m_fragSource, fragCompileOk, getShaderInfoLog(m_fragShaderGL))
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::EndShaderProgram;
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Program build failed");
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_isBuilt = true;
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::setRandomUniforms (const vector<VarSpec>& uniforms, const string& shaderNameManglingSuffix, Random& rnd) const
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	use();
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)uniforms.size(); unifNdx++)
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarSpec&	spec			= uniforms[unifNdx];
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		typeScalarSize	= glu::getDataTypeScalarSize(spec.type);
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		location		= glGetUniformLocation(m_programGL, mangleShaderNames(spec.name, shaderNameManglingSuffix).c_str());
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location < 0)
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(spec.type))
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float val[4];
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < typeScalarSize; i++)
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				val[i] = rnd.getFloat(spec.minValue.f[i], spec.maxValue.f[i]);
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (spec.type)
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT:		glUniform1f(location, val[0]);							break;
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_VEC2:	glUniform2f(location, val[0], val[1]);					break;
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_VEC3:	glUniform3f(location, val[0], val[1], val[2]);			break;
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_VEC4:	glUniform4f(location, val[0], val[1], val[2], val[3]);	break;
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default: DE_ASSERT(false);
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeMatrix(spec.type))
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float val[4*4];
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < typeScalarSize; i++)
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				val[i] = rnd.getFloat(spec.minValue.f[i], spec.maxValue.f[i]);
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (spec.type)
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2:		glUniformMatrix2fv		(location, 1, GL_FALSE, &val[0]); break;
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3:		glUniformMatrix3fv		(location, 1, GL_FALSE, &val[0]); break;
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4:		glUniformMatrix4fv		(location, 1, GL_FALSE, &val[0]); break;
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2X3:	glUniformMatrix2x3fv	(location, 1, GL_FALSE, &val[0]); break;
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2X4:	glUniformMatrix2x4fv	(location, 1, GL_FALSE, &val[0]); break;
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3X2:	glUniformMatrix3x2fv	(location, 1, GL_FALSE, &val[0]); break;
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3X4:	glUniformMatrix3x4fv	(location, 1, GL_FALSE, &val[0]); break;
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4X2:	glUniformMatrix4x2fv	(location, 1, GL_FALSE, &val[0]); break;
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4X3:	glUniformMatrix4x3fv	(location, 1, GL_FALSE, &val[0]); break;
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default: DE_ASSERT(false);
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(spec.type))
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int val[4];
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < typeScalarSize; i++)
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				val[i] = rnd.getInt(spec.minValue.i[i], spec.maxValue.i[i]);
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (spec.type)
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_INT:			glUniform1i(location, val[0]);							break;
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_INT_VEC2:	glUniform2i(location, val[0], val[1]);					break;
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_INT_VEC3:	glUniform3i(location, val[0], val[1], val[2]);			break;
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_INT_VEC4:	glUniform4i(location, val[0], val[1], val[2], val[3]);	break;
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default: DE_ASSERT(false);
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec(spec.type))
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32 val[4];
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < typeScalarSize; i++)
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(spec.minValue.i[i] >= 0 && spec.maxValue.i[i] >= 0);
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				val[i] = (deUint32)rnd.getInt(spec.minValue.i[i], spec.maxValue.i[i]);
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (spec.type)
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_UINT:		glUniform1ui(location, val[0]);							break;
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_UINT_VEC2:	glUniform2ui(location, val[0], val[1]);					break;
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_UINT_VEC3:	glUniform3ui(location, val[0], val[1], val[2]);			break;
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_UINT_VEC4:	glUniform4ui(location, val[0], val[1], val[2], val[3]);	break;
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default: DE_ASSERT(false);
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::setAttribute (const Buffer& attrBuf, const int attrBufOffset, const VarSpec& attrSpec, const string& shaderNameManglingSuffix) const
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int attrLoc = glGetAttribLocation(m_programGL, mangleShaderNames(attrSpec.name, shaderNameManglingSuffix).c_str());
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glEnableVertexAttribArray(attrLoc);
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attrBuf.bind(GL_ARRAY_BUFFER);
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(attrSpec.type))
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glVertexAttribPointer(attrLoc, glu::getDataTypeScalarSize(attrSpec.type), GL_FLOAT, GL_FALSE, 0, (GLvoid*)(deIntptr)attrBufOffset);
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::setAttributeClientMem (const void* const attrData, const VarSpec& attrSpec, const string& shaderNameManglingSuffix) const
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int attrLoc = glGetAttribLocation(m_programGL, mangleShaderNames(attrSpec.name, shaderNameManglingSuffix).c_str());
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glEnableVertexAttribArray(attrLoc);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindBuffer(GL_ARRAY_BUFFER, 0);
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(attrSpec.type))
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glVertexAttribPointer(attrLoc, glu::getDataTypeScalarSize(attrSpec.type), GL_FLOAT, GL_FALSE, 0, attrData);
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::disableAttributeArray (const VarSpec& attrSpec, const string& shaderNameManglingSuffix) const
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int attrLoc = glGetAttribLocation(m_programGL, mangleShaderNames(attrSpec.name, shaderNameManglingSuffix).c_str());
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDisableVertexAttribArray(attrLoc);
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Container class for managing GL objects
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * GLObjectManager can be used for objects of class Program, Buffer or
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Texture. In the manager, each such object is associated with a name that
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is used to access it.
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * In addition to the making, getting and removing functions, the manager
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * supports marking objects as "garbage", meaning they're not yet
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * destroyed, but can be later destroyed with removeRandomGarbage(). The
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * idea is that if we want to stress test with high memory usage, we can
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * continuously move objects to garbage after using them, and when a memory
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limit is reached, we can call removeGarbageUntilUnder(limit, rnd). This
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * way we can approximately keep our memory usage at just under the wanted
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limit.
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The manager also supports querying the approximate amount of GL memory
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * used by its objects.
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \note The memory usage related functions are not currently supported
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *		 for Program objects.
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GLObjectManager
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						make						(const string& name)								{ DE_ASSERT(!has(name)); m_objects[name] = SharedPtr<T>(new T); }
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						make						(const string& name, gls::TextureType texType)		{ DE_ASSERT(!has(name)); m_objects[name] = SharedPtr<T>(new T(texType)); }
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						has							(const string& name) const	{ return m_objects.find(name) != m_objects.end(); }
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T&					get							(const string& name) const;
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	T&							get							(const string& name)		{ return const_cast<T&>(((const GLObjectManager<T>*)this)->get(name)); }
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						remove						(const string& name)		{ const int removed = (int)m_objects.erase(name); DE_ASSERT(removed); DE_UNREF(removed); }
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							computeApproxMemUsage		(void) const;
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						markAsGarbage				(const string& name);
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							removeRandomGarbage			(Random& rnd);
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						removeGarbageUntilUnder		(int limit, Random& rnd);
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*			objTypeName					(void);
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, SharedPtr<T> >	m_objects;
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<SharedPtr<T> >		m_garbageObjects;
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> const char* GLObjectManager<Buffer>::objTypeName	(void) { return "buffer"; }
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> const char* GLObjectManager<Texture>::objTypeName	(void) { return "texture"; }
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> const char* GLObjectManager<Program>::objTypeName	(void) { return "program"; }
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst T& GLObjectManager<T>::get (const string& name) const
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const typename map<string, SharedPtr<T> >::const_iterator it = m_objects.find(name);
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(it != m_objects.end());
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *it->second;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint GLObjectManager<T>::computeApproxMemUsage (void) const
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int result = 0;
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (typename map<string, SharedPtr<T> >::const_iterator it = m_objects.begin(); it != m_objects.end(); ++it)
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result += it->second->getApproxMemUsage();
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (typename vector<SharedPtr<T> >::const_iterator it = m_garbageObjects.begin(); it != m_garbageObjects.end(); ++it)
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result += (*it)->getApproxMemUsage();
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GLObjectManager<T>::markAsGarbage (const string& name)
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const typename map<string, SharedPtr<T> >::iterator it = m_objects.find(name);
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(it != m_objects.end());
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_garbageObjects.push_back(it->second);
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_objects.erase(it);
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint GLObjectManager<T>::removeRandomGarbage (Random& rnd)
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_garbageObjects.empty())
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return -1;
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int removeNdx		= rnd.getInt(0, (int)m_garbageObjects.size()-1);
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int memoryFreed	= m_garbageObjects[removeNdx]->getApproxMemUsage();
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_garbageObjects.erase(m_garbageObjects.begin() + removeNdx);
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return memoryFreed;
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GLObjectManager<T>::removeGarbageUntilUnder (const int limit, Random& rnd)
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int memUsage = computeApproxMemUsage();
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (memUsage > limit)
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int memReleased = removeRandomGarbage(rnd);
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (memReleased < 0)
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::InternalError(string("") + "Given " + objTypeName() + " memory usage limit exceeded, and no unneeded " + objTypeName() + " resources available to release");
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		memUsage -= memReleased;
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(memUsage == computeApproxMemUsage());
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // LongStressCaseInternal
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace LongStressCaseInternal;
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int generateRandomAttribData (vector<deUint8>& attrDataBuf, int& dataSizeBytesDst, const VarSpec& attrSpec, const int numVertices, Random& rnd)
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	isFloat			= glu::isDataTypeFloatOrVec(attrSpec.type);
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	numComponents	= glu::getDataTypeScalarSize(attrSpec.type);
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	componentSize	= (int)(isFloat ? sizeof(GLfloat) : sizeof(GLint));
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	offsetInBuf		= nextDivisible((int)attrDataBuf.size(), componentSize); // Round up for alignment.
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(sizeof(GLint) == sizeof(int));
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(float));
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dataSizeBytesDst = numComponents*componentSize*numVertices;
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attrDataBuf.resize(offsetInBuf + dataSizeBytesDst);
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFloat)
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float* const data = (float*)&attrDataBuf[offsetInBuf];
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx++)
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < numComponents; compNdx++)
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				data[vtxNdx*numComponents + compNdx] = rnd.getFloat(attrSpec.minValue.f[compNdx], attrSpec.maxValue.f[compNdx]);
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(glu::isDataTypeIntOrIVec(attrSpec.type));
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int* const data = (int*)&attrDataBuf[offsetInBuf];
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx++)
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < numComponents; compNdx++)
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				data[vtxNdx*numComponents + compNdx] = rnd.getInt(attrSpec.minValue.i[compNdx], attrSpec.maxValue.i[compNdx]);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return offsetInBuf;
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int generateRandomPositionAttribData (vector<deUint8>& attrDataBuf, int& dataSizeBytesDst, const VarSpec& attrSpec, const int numVertices, Random& rnd)
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeFloatOrVec(attrSpec.type));
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numComponents = glu::getDataTypeScalarSize(attrSpec.type);
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(numComponents >= 2);
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int offsetInBuf = generateRandomAttribData(attrDataBuf, dataSizeBytesDst, attrSpec, numVertices, rnd);
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numComponents > 2)
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float* const data = (float*)&attrDataBuf[offsetInBuf];
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx++)
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data[vtxNdx*numComponents + 2] = -1.0f;
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int triNdx = 0; triNdx < numVertices-2; triNdx++)
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float* const	vtxAComps	= &data[(triNdx+0)*numComponents];
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float* const	vtxBComps	= &data[(triNdx+1)*numComponents];
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float* const	vtxCComps	= &data[(triNdx+2)*numComponents];
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		triArea		= triangleArea(Vec2(vtxAComps[0], vtxAComps[1]),
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   Vec2(vtxBComps[0], vtxBComps[1]),
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   Vec2(vtxCComps[0], vtxCComps[1]));
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		t			= triArea / (triArea + 1.0f);
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		z			= (1.0f-t)*attrSpec.minValue.f[2] + t*attrSpec.maxValue.f[2];
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtxAComps[2] = de::max(vtxAComps[2], z);
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtxBComps[2] = de::max(vtxBComps[2], z);
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtxCComps[2] = de::max(vtxCComps[2], z);
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return offsetInBuf;
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void generateAttribs (vector<deUint8>& attrDataBuf, vector<int>& attrDataOffsets, vector<int>& attrDataSizes, const vector<VarSpec>& attrSpecs, const string& posAttrName, const int numVertices, Random& rnd)
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attrDataBuf.clear();
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attrDataOffsets.clear();
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attrDataSizes.resize(attrSpecs.size());
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)attrSpecs.size(); i++)
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (attrSpecs[i].name == posAttrName)
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attrDataOffsets.push_back(generateRandomPositionAttribData(attrDataBuf, attrDataSizes[i], attrSpecs[i], numVertices, rnd));
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attrDataOffsets.push_back(generateRandomAttribData(attrDataBuf, attrDataSizes[i], attrSpecs[i], numVertices, rnd));
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLongStressCase::LongStressCase (tcu::TestContext&				testCtx,
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const glu::RenderContext&		renderCtx,
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const char* const				name,
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const char* const				desc,
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int						maxTexMemoryUsageBytes,
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int						maxBufMemoryUsageBytes,
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int						numDrawCallsPerIteration,
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int						numTrianglesPerDrawCall,
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const vector<ProgramContext>&	programContexts,
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const FeatureProbabilities&		probabilities,
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const deUint32					indexBufferUsage,
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const deUint32					attrBufferUsage,
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int						redundantBufferFactor,
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool						showDebugInfo)
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: tcu::TestCase					(testCtx, name, desc)
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx					(renderCtx)
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxTexMemoryUsageBytes		(maxTexMemoryUsageBytes)
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxBufMemoryUsageBytes		(maxBufMemoryUsageBytes)
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numDrawCallsPerIteration	(numDrawCallsPerIteration)
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numTrianglesPerDrawCall		(numTrianglesPerDrawCall)
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numVerticesPerDrawCall		(numTrianglesPerDrawCall+2) // \note Triangle strips are used.
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_programContexts				(programContexts)
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_probabilities				(probabilities)
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_indexBufferUsage			(indexBufferUsage)
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_attrBufferUsage				(attrBufferUsage)
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_redundantBufferFactor		(redundantBufferFactor)
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_showDebugInfo				(showDebugInfo)
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numIterations				(getNumIterations(testCtx, 5))
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isGLES3						(contextSupports(renderCtx.getType(), glu::ApiType::es(3,0)))
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentIteration			(0)
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_startTimeSeconds			((deUint64)-1)
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_lastLogTime					((deUint64)-1)
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_lastLogIteration			(0)
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentLogEntryNdx			(0)
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rnd							(deStringHash(getName()) ^ testCtx.getCommandLine().getBaseSeed())
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_programs					(DE_NULL)
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_buffers						(DE_NULL)
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textures					(DE_NULL)
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_debugInfoRenderer			(DE_NULL)
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numVerticesPerDrawCall <= (int)std::numeric_limits<deUint16>::max()+1); // \note Vertices are referred to with 16-bit indices.
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_redundantBufferFactor > 0);
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLongStressCase::~LongStressCase (void)
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LongStressCase::deinit();
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LongStressCase::init (void)
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate dummy texture data for each texture spec in m_programContexts.
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_programContexts.empty());
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_programResources.empty());
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_programResources.resize(m_programContexts.size());
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int progCtxNdx = 0; progCtxNdx < (int)m_programContexts.size(); progCtxNdx++)
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ProgramContext&	progCtx = m_programContexts[progCtxNdx];
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ProgramResources&		progRes = m_programResources[progCtxNdx];
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int texSpecNdx = 0; texSpecNdx < (int)progCtx.textureSpecs.size(); texSpecNdx++)
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureSpec&		spec	= progCtx.textureSpecs[texSpecNdx];
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat		format	= glu::mapGLTransferFormat(spec.format, spec.dataType);
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// If texture data with the same format has already been generated, re-use that (don't care much about contents).
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			SharedPtr<TextureLevel> dummyTex;
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int prevProgCtxNdx = 0; prevProgCtxNdx < (int)m_programResources.size(); prevProgCtxNdx++)
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const vector<SharedPtr<TextureLevel> >& prevProgCtxTextures = m_programResources[prevProgCtxNdx].dummyTextures;
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int texNdx = 0; texNdx < (int)prevProgCtxTextures.size(); texNdx++)
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (prevProgCtxTextures[texNdx]->getFormat() == format)
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						dummyTex = prevProgCtxTextures[texNdx];
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!dummyTex)
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dummyTex = SharedPtr<TextureLevel>(new TextureLevel(format));
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (dummyTex->getWidth() < spec.width || dummyTex->getHeight() < spec.height)
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dummyTex->setSize(spec.width, spec.height);
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithComponentGradients(dummyTex->getAccess(), spec.minValue, spec.maxValue);
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			progRes.dummyTextures.push_back(dummyTex);
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexIndices.clear();
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < m_numVerticesPerDrawCall; i++)
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexIndices.push_back((deUint16)i);
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_rnd.shuffle(m_vertexIndices.begin(), m_vertexIndices.end());
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_programs && !m_buffers && !m_textures);
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_programs = new GLObjectManager<Program>;
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_buffers = new GLObjectManager<Buffer>;
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures = new GLObjectManager<Texture>;
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentIteration = 0;
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog& log = m_testCtx.getLog();
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Number of iterations: "										<< (m_numIterations > 0 ? toString(m_numIterations) : "infinite")				<< TestLog::EndMessage
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Number of draw calls per iteration: "						<< m_numDrawCallsPerIteration													<< TestLog::EndMessage
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Number of triangles per draw call: "						<< m_numTrianglesPerDrawCall													<< TestLog::EndMessage
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Using triangle strips"																														<< TestLog::EndMessage
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Approximate texture memory usage limit: "					<< de::floatToString((float)m_maxTexMemoryUsageBytes / Mi, 2) << " MiB"			<< TestLog::EndMessage
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Approximate buffer memory usage limit: "					<< de::floatToString((float)m_maxBufMemoryUsageBytes / Mi, 2) << " MiB"			<< TestLog::EndMessage
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Default vertex attribute data buffer usage parameter: "		<< glu::getUsageName(m_attrBufferUsage)											<< TestLog::EndMessage
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Default vertex index data buffer usage parameter: "			<< glu::getUsageName(m_indexBufferUsage)										<< TestLog::EndMessage
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Section("ProbabilityParams", "Per-iteration probability parameters")
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Program re-build: "															<< probabilityStr(m_probabilities.rebuildProgram)				<< TestLog::EndMessage
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Texture re-upload: "														<< probabilityStr(m_probabilities.reuploadTexture)				<< TestLog::EndMessage
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Buffer re-upload: "															<< probabilityStr(m_probabilities.reuploadBuffer)				<< TestLog::EndMessage
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Use glTexImage* instead of glTexSubImage* when uploading texture: "			<< probabilityStr(m_probabilities.reuploadWithTexImage)			<< TestLog::EndMessage
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Use glBufferData* instead of glBufferSubData* when uploading buffer: "		<< probabilityStr(m_probabilities.reuploadWithBufferData)		<< TestLog::EndMessage
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Delete texture after using it, even if could re-use it: "					<< probabilityStr(m_probabilities.deleteTexture)				<< TestLog::EndMessage
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Delete buffer after using it, even if could re-use it: "					<< probabilityStr(m_probabilities.deleteBuffer)					<< TestLog::EndMessage
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Don't re-use texture, and only delete if memory limit is hit: "				<< probabilityStr(m_probabilities.wastefulTextureMemoryUsage)	<< TestLog::EndMessage
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Don't re-use buffer, and only delete if memory limit is hit: "				<< probabilityStr(m_probabilities.wastefulBufferMemoryUsage)	<< TestLog::EndMessage
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Use client memory (instead of GL buffers) for vertex attribute data: "		<< probabilityStr(m_probabilities.clientMemoryAttributeData)	<< TestLog::EndMessage
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Use client memory (instead of GL buffers) for vertex index data: "			<< probabilityStr(m_probabilities.clientMemoryIndexData)		<< TestLog::EndMessage
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Use random target parameter when uploading buffer data: "					<< probabilityStr(m_probabilities.randomBufferUploadTarget)		<< TestLog::EndMessage
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Use random usage parameter when uploading buffer data: "					<< probabilityStr(m_probabilities.randomBufferUsage)			<< TestLog::EndMessage
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Use glDrawArrays instead of glDrawElements: "								<< probabilityStr(m_probabilities.useDrawArrays)				<< TestLog::EndMessage
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Use separate buffers for each attribute, instead of one array for all: "	<< probabilityStr(m_probabilities.separateAttributeBuffers)		<< TestLog::EndMessage
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::EndSection
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Using " << m_programContexts.size() << " program(s)" << TestLog::EndMessage;
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool anyProgramsFailed = false;
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int progCtxNdx = 0; progCtxNdx < (int)m_programContexts.size(); progCtxNdx++)
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ProgramContext& progCtx = m_programContexts[progCtxNdx];
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::ShaderProgram prog(m_renderCtx, glu::makeVtxFragSources(mangleShaderNames(progCtx.vertexSource, ""), mangleShaderNames(progCtx.fragmentSource, "")));
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Section("ShaderProgram" + toString(progCtxNdx), "Shader program " + toString(progCtxNdx)) << prog << TestLog::EndSection;
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!prog.isOk())
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				anyProgramsFailed = true;
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (anyProgramsFailed)
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("One or more shader programs failed to compile");
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_debugInfoRenderer);
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_showDebugInfo)
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_debugInfoRenderer = new DebugInfoRenderer(m_renderCtx);
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LongStressCase::deinit (void)
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_programResources.clear();
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_programs;
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_programs = DE_NULL;
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_buffers;
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_buffers = DE_NULL;
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_textures;
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures = DE_NULL;
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_debugInfoRenderer;
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_debugInfoRenderer = DE_NULL;
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLongStressCase::IterateResult LongStressCase::iterate (void)
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log							= m_testCtx.getLog();
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					renderWidth					= m_renderCtx.getRenderTarget().getWidth();
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					renderHeight				= m_renderCtx.getRenderTarget().getHeight();
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					useClientMemoryIndexData	= m_rnd.getFloat() < m_probabilities.clientMemoryIndexData;
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					useDrawArrays				= m_rnd.getFloat() < m_probabilities.useDrawArrays;
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					separateAttributeBuffers	= m_rnd.getFloat() < m_probabilities.separateAttributeBuffers;
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					progContextNdx				= m_rnd.getInt(0, (int)m_programContexts.size()-1);
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ProgramContext&		programContext				= m_programContexts[progContextNdx];
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramResources&			programResources			= m_programResources[progContextNdx];
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string				programName					= "prog" + toString(progContextNdx);
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string				textureNamePrefix			= "tex" + toString(progContextNdx) + "_";
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string				unitedAttrBufferNamePrefix	= "attrBuf" + toString(progContextNdx) + "_";
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string				indexBufferName				= "indexBuf" + toString(progContextNdx);
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string				separateAttrBufNamePrefix	= "attrBuf" + toString(progContextNdx) + "_";
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration == 0)
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_lastLogTime = m_startTimeSeconds = deGetTime();
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Make or re-compile programs.
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool hadProgram = m_programs->has(programName);
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hadProgram)
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_programs->make(programName);
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Program& prog = m_programs->get(programName);
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hadProgram || m_rnd.getFloat() < m_probabilities.rebuildProgram)
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			programResources.shaderNameManglingSuffix = toString((deUint16)deUint64Hash((deUint64)m_currentIteration ^ deGetTime()));
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			prog.setSources(mangleShaderNames(programContext.vertexSource, programResources.shaderNameManglingSuffix),
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							mangleShaderNames(programContext.fragmentSource, programResources.shaderNameManglingSuffix));
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			prog.build(log);
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		prog.use();
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Program& program = m_programs->get(programName);
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Make or re-upload textures.
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int texNdx = 0; texNdx < (int)programContext.textureSpecs.size(); texNdx++)
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string		texName		= textureNamePrefix + toString(texNdx);
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			hadTexture	= m_textures->has(texName);
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const TextureSpec&	spec		= programContext.textureSpecs[texNdx];
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hadTexture)
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures->make(texName, spec.textureType);
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hadTexture || m_rnd.getFloat() < m_probabilities.reuploadTexture)
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Texture& texture = m_textures->get(texName);
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures->removeGarbageUntilUnder(m_maxTexMemoryUsageBytes - texture.getApproxMemUsageDiff(spec.width, spec.height, spec.internalFormat, spec.useMipmap), m_rnd);
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!hadTexture || m_rnd.getFloat() < m_probabilities.reuploadWithTexImage)
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texture.setData(programResources.dummyTextures[texNdx]->getAccess(), spec.width, spec.height, spec.internalFormat, spec.useMipmap);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texture.setSubData(programResources.dummyTextures[texNdx]->getAccess(), 0, 0, spec.width, spec.height);
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.toUnit(0);
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.setWrap(spec.sWrap, spec.tWrap);
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.setFilter(spec.minFilter, spec.magFilter);
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind textures to units, in random order (because when multiple texture specs have same unit, we want to pick one randomly).
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<int> texSpecIndices(programContext.textureSpecs.size());
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)texSpecIndices.size(); i++)
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texSpecIndices[i] = i;
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_rnd.shuffle(texSpecIndices.begin(), texSpecIndices.end());
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)texSpecIndices.size(); i++)
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures->get(textureNamePrefix + toString(texSpecIndices[i])).toUnit(programContext.textureSpecs[i].textureUnit);
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Make or re-upload index buffer.
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!useDrawArrays)
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_rnd.shuffle(m_vertexIndices.begin(), m_vertexIndices.end());
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!useClientMemoryIndexData)
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool hadIndexBuffer = m_buffers->has(indexBufferName);
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!hadIndexBuffer)
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_buffers->make(indexBufferName);
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Buffer& indexBuf = m_buffers->get(indexBufferName);
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!hadIndexBuffer || m_rnd.getFloat() < m_probabilities.reuploadBuffer)
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_buffers->removeGarbageUntilUnder(m_maxBufMemoryUsageBytes - indexBuf.getApproxMemUsageDiff(m_vertexIndices), m_rnd);
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32 target = m_rnd.getFloat() < m_probabilities.randomBufferUploadTarget ? randomBufferTarget(m_rnd, m_isGLES3) : GL_ELEMENT_ARRAY_BUFFER;
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!hadIndexBuffer || m_rnd.getFloat() < m_probabilities.reuploadWithBufferData)
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					indexBuf.setData(m_vertexIndices, target, m_rnd.getFloat() < m_probabilities.randomBufferUsage ? randomBufferUsage(m_rnd, m_isGLES3) : m_indexBufferUsage);
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					indexBuf.setSubData(m_vertexIndices, 0, m_numVerticesPerDrawCall, target);
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set vertex attributes. If not using client-memory data, make or re-upload attribute buffers.
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	generateAttribs(programResources.attrDataBuf, programResources.attrDataOffsets, programResources.attrDataSizes,
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					programContext.attributes, programContext.positionAttrName, m_numVerticesPerDrawCall, m_rnd);
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!(m_rnd.getFloat() < m_probabilities.clientMemoryAttributeData))
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (separateAttributeBuffers)
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int attrNdx = 0; attrNdx < (int)programContext.attributes.size(); attrNdx++)
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int usedRedundantBufferNdx = m_rnd.getInt(0, m_redundantBufferFactor-1);
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int redundantBufferNdx = 0; redundantBufferNdx < m_redundantBufferFactor; redundantBufferNdx++)
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string	curAttrBufName		= separateAttrBufNamePrefix + toString(attrNdx) + "_" + toString(redundantBufferNdx);
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const bool		hadCurAttrBuffer	= m_buffers->has(curAttrBufName);
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (!hadCurAttrBuffer)
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_buffers->make(curAttrBufName);
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Buffer& curAttrBuf = m_buffers->get(curAttrBufName);
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (!hadCurAttrBuffer || m_rnd.getFloat() < m_probabilities.reuploadBuffer)
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_buffers->removeGarbageUntilUnder(m_maxBufMemoryUsageBytes - curAttrBuf.getApproxMemUsageDiff(programResources.attrDataSizes[attrNdx]), m_rnd);
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const deUint32 target = m_rnd.getFloat() < m_probabilities.randomBufferUploadTarget ? randomBufferTarget(m_rnd, m_isGLES3) : GL_ARRAY_BUFFER;
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (!hadCurAttrBuffer || m_rnd.getFloat() < m_probabilities.reuploadWithBufferData)
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							curAttrBuf.setData(&programResources.attrDataBuf[programResources.attrDataOffsets[attrNdx]], programResources.attrDataSizes[attrNdx], target,
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   m_rnd.getFloat() < m_probabilities.randomBufferUsage ? randomBufferUsage(m_rnd, m_isGLES3) : m_attrBufferUsage);
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						else
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							curAttrBuf.setSubData(&programResources.attrDataBuf[programResources.attrDataOffsets[attrNdx]], 0, programResources.attrDataSizes[attrNdx], target);
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (redundantBufferNdx == usedRedundantBufferNdx)
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						program.setAttribute(curAttrBuf, 0, programContext.attributes[attrNdx], programResources.shaderNameManglingSuffix);
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int usedRedundantBufferNdx = m_rnd.getInt(0, m_redundantBufferFactor-1);
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int redundantBufferNdx = 0; redundantBufferNdx < m_redundantBufferFactor; redundantBufferNdx++)
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string	attrBufName		= unitedAttrBufferNamePrefix + toString(redundantBufferNdx);
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const bool		hadAttrBuffer	= m_buffers->has(attrBufName);
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!hadAttrBuffer)
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_buffers->make(attrBufName);
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Buffer& attrBuf = m_buffers->get(attrBufName);
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!hadAttrBuffer || m_rnd.getFloat() < m_probabilities.reuploadBuffer)
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_buffers->removeGarbageUntilUnder(m_maxBufMemoryUsageBytes - attrBuf.getApproxMemUsageDiff(programResources.attrDataBuf), m_rnd);
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const deUint32 target = m_rnd.getFloat() < m_probabilities.randomBufferUploadTarget ? randomBufferTarget(m_rnd, m_isGLES3) : GL_ARRAY_BUFFER;
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (!hadAttrBuffer || m_rnd.getFloat() < m_probabilities.reuploadWithBufferData)
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						attrBuf.setData(programResources.attrDataBuf, target, m_rnd.getFloat() < m_probabilities.randomBufferUsage ? randomBufferUsage(m_rnd, m_isGLES3) : m_attrBufferUsage);
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					else
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						attrBuf.setSubData(programResources.attrDataBuf, 0, (int)programResources.attrDataBuf.size(), target);
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (redundantBufferNdx == usedRedundantBufferNdx)
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int i = 0; i < (int)programContext.attributes.size(); i++)
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						program.setAttribute(attrBuf, programResources.attrDataOffsets[i], programContext.attributes[i], programResources.shaderNameManglingSuffix);
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)programContext.attributes.size(); i++)
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			program.setAttributeClientMem(&programResources.attrDataBuf[programResources.attrDataOffsets[i]], programContext.attributes[i], programResources.shaderNameManglingSuffix);
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw.
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glViewport(0, 0, renderWidth, renderHeight);
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClearDepthf(1.0f);
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClear(GL_DEPTH_BUFFER_BIT);
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glEnable(GL_DEPTH_TEST);
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < m_numDrawCallsPerIteration; i++)
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.use();
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.setRandomUniforms(programContext.uniforms, programResources.shaderNameManglingSuffix, m_rnd);
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (useDrawArrays)
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glDrawArrays(GL_TRIANGLE_STRIP, 0, m_numVerticesPerDrawCall);
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (useClientMemoryIndexData)
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glDrawElements(GL_TRIANGLE_STRIP, m_numVerticesPerDrawCall, GL_UNSIGNED_SHORT, &m_vertexIndices[0]);
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_buffers->get(indexBufferName).bind(GL_ELEMENT_ARRAY_BUFFER);
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glDrawElements(GL_TRIANGLE_STRIP, m_numVerticesPerDrawCall, GL_UNSIGNED_SHORT, DE_NULL);
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for(int i = 0; i < (int)programContext.attributes.size(); i++)
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.disableAttributeArray(programContext.attributes[i], programResources.shaderNameManglingSuffix);
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_showDebugInfo)
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_debugInfoRenderer->drawInfo(deGetTime()-m_startTimeSeconds, m_textures->computeApproxMemUsage(), m_maxTexMemoryUsageBytes, m_buffers->computeApproxMemUsage(), m_maxBufMemoryUsageBytes, m_currentIteration);
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration > 0)
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Log if a certain amount of time has passed since last log entry (or if this is the last iteration).
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint64	loggingIntervalSeconds	= 10;
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint64	time					= deGetTime();
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint64	timeDiff				= time - m_lastLogTime;
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		iterDiff				= m_currentIteration - m_lastLogIteration;
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (timeDiff >= loggingIntervalSeconds || m_currentIteration == m_numIterations-1)
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Section("LogEntry" + toString(m_currentLogEntryNdx), "Log entry " + toString(m_currentLogEntryNdx))
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::Message << "Time elapsed: " << getTimeStr(time - m_startTimeSeconds) << TestLog::EndMessage
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::Message << "Frame number: " << m_currentIteration << TestLog::EndMessage
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::Message << "Time since last log entry: " << timeDiff << "s" << TestLog::EndMessage
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::Message << "Frames since last log entry: " << iterDiff << TestLog::EndMessage
1497c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry				<< TestLog::Message << "Average frame time since last log entry: " << de::floatToString((float)timeDiff / (float)iterDiff, 2) << "s" << TestLog::EndMessage
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::Message << "Approximate texture memory usage: "
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< de::floatToString((float)m_textures->computeApproxMemUsage() / Mi, 2) << " MiB / "
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< de::floatToString((float)m_maxTexMemoryUsageBytes / Mi, 2) << " MiB"
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< TestLog::EndMessage
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::Message << "Approximate buffer memory usage: "
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										<< de::floatToString((float)m_buffers->computeApproxMemUsage() / Mi, 2) << " MiB / "
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										<< de::floatToString((float)m_maxBufMemoryUsageBytes / Mi, 2) << " MiB"
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										<< TestLog::EndMessage
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::EndSection;
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_lastLogTime		= time;
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_lastLogIteration	= m_currentIteration;
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_currentLogEntryNdx++;
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Possibly remove or set-as-garbage some objects, depending on given probabilities.
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int texNdx = 0; texNdx < (int)programContext.textureSpecs.size(); texNdx++)
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string texName = textureNamePrefix + toString(texNdx);
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_rnd.getFloat() < m_probabilities.deleteTexture)
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures->remove(texName);
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_rnd.getFloat() < m_probabilities.wastefulTextureMemoryUsage)
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures->markAsGarbage(texName);
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_buffers->has(indexBufferName))
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_rnd.getFloat() < m_probabilities.deleteBuffer)
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_buffers->remove(indexBufferName);
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_rnd.getFloat() < m_probabilities.wastefulBufferMemoryUsage)
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_buffers->markAsGarbage(indexBufferName);
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (separateAttributeBuffers)
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int attrNdx = 0; attrNdx < (int)programContext.attributes.size(); attrNdx++)
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string curAttrBufNamePrefix = separateAttrBufNamePrefix + toString(attrNdx) + "_";
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_buffers->has(curAttrBufNamePrefix + "0"))
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (m_rnd.getFloat() < m_probabilities.deleteBuffer)
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int i = 0; i < m_redundantBufferFactor; i++)
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_buffers->remove(curAttrBufNamePrefix + toString(i));
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else if (m_rnd.getFloat() < m_probabilities.wastefulBufferMemoryUsage)
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int i = 0; i < m_redundantBufferFactor; i++)
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_buffers->markAsGarbage(curAttrBufNamePrefix + toString(i));
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_buffers->has(unitedAttrBufferNamePrefix + "0"))
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_rnd.getFloat() < m_probabilities.deleteBuffer)
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < m_redundantBufferFactor; i++)
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_buffers->remove(unitedAttrBufferNamePrefix + toString(i));
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_rnd.getFloat() < m_probabilities.wastefulBufferMemoryUsage)
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < m_redundantBufferFactor; i++)
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_buffers->markAsGarbage(unitedAttrBufferNamePrefix + toString(i));
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("End of LongStressCase::iterate()");
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentIteration++;
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration == m_numIterations)
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Passed");
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTINUE;
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gls
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1587