Home | History | Annotate | Download | only in glshared
      1 #ifndef _GLSLONGSTRESSCASE_HPP
      2 #define _GLSLONGSTRESSCASE_HPP
      3 /*-------------------------------------------------------------------------
      4  * drawElements Quality Program OpenGL (ES) Module
      5  * -----------------------------------------------
      6  *
      7  * Copyright 2014 The Android Open Source Project
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief Parametrized, long-running stress case.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "tcuDefs.hpp"
     27 #include "tcuTestCase.hpp"
     28 #include "tcuTexture.hpp"
     29 #include "tcuMatrix.hpp"
     30 #include "gluRenderContext.hpp"
     31 #include "gluShaderUtil.hpp"
     32 #include "glsTextureTestUtil.hpp"
     33 #include "deRandom.hpp"
     34 #include "deSharedPtr.hpp"
     35 
     36 #include <string>
     37 #include <vector>
     38 #include <map>
     39 
     40 namespace deqp
     41 {
     42 namespace gls
     43 {
     44 
     45 namespace LongStressCaseInternal
     46 {
     47 
     48 template <typename T> class GLObjectManager;
     49 class Program;
     50 class Buffer;
     51 class Texture;
     52 class DebugInfoRenderer;
     53 
     54 }
     55 
     56 struct VarSpec
     57 {
     58 	union Value
     59 	{
     60 		float	f[4*4]; // \note Matrices are stored in column major order.
     61 		int		i[4];
     62 	};
     63 
     64 	std::string		name;
     65 	glu::DataType	type;
     66 	Value			minValue;
     67 	Value			maxValue;
     68 
     69 	template <typename T>
     70 	VarSpec (const std::string& name_, const T& minValue_, const T& maxValue_)	: name(name_) { set(minValue_, maxValue_); }
     71 
     72 	template <typename T>
     73 	VarSpec (const std::string& name_, const T& value)							: name(name_) { set(value, value); }
     74 
     75 	void set (float minValue_, float maxValue_)
     76 	{
     77 		type			= glu::TYPE_FLOAT;
     78 		minValue.f[0]	= minValue_;
     79 		maxValue.f[0]	= maxValue_;
     80 	}
     81 
     82 	template <int ValSize>
     83 	void set (const tcu::Vector<float, ValSize>& minValue_, const tcu::Vector<float, ValSize>& maxValue_)
     84 	{
     85 		type = glu::getDataTypeFloatVec(ValSize);
     86 		vecToArr(minValue_, minValue.f);
     87 		vecToArr(maxValue_, maxValue.f);
     88 	}
     89 
     90 	template <int ValRows, int ValCols>
     91 	void set (const tcu::Matrix<float, ValRows, ValCols>& minValue_, const tcu::Matrix<float, ValRows, ValCols>& maxValue_)
     92 	{
     93 		type = glu::getDataTypeMatrix(ValCols, ValRows);
     94 		matToArr(minValue_, minValue.f);
     95 		matToArr(maxValue_, maxValue.f);
     96 	}
     97 
     98 	void set (int minValue_, int maxValue_)
     99 	{
    100 		type			= glu::TYPE_INT;
    101 		minValue.i[0]	= minValue_;
    102 		maxValue.i[0]	= maxValue_;
    103 	}
    104 
    105 	template <int ValSize>
    106 	void set (const tcu::Vector<int, ValSize>& minValue_, const tcu::Vector<int, ValSize>& maxValue_)
    107 	{
    108 		type = glu::getDataTypeVector(glu::TYPE_INT, ValSize);
    109 		vecToArr(minValue_, minValue.i);
    110 		vecToArr(maxValue_, maxValue.i);
    111 	}
    112 
    113 private:
    114 	template <typename T, int SrcSize, int DstSize>
    115 	static inline void vecToArr (const tcu::Vector<T, SrcSize>& src, T (&dst)[DstSize])
    116 	{
    117 		DE_STATIC_ASSERT(DstSize >= SrcSize);
    118 		for (int i = 0; i < SrcSize; i++)
    119 			dst[i] = src[i];
    120 	}
    121 
    122 	template <int ValRows, int ValCols, int DstSize>
    123 	static inline void matToArr (const tcu::Matrix<float, ValRows, ValCols>& src, float (&dst)[DstSize])
    124 	{
    125 		DE_STATIC_ASSERT(DstSize >= ValRows*ValCols);
    126 		tcu::Array<float, ValRows*ValCols> data = src.getColumnMajorData();
    127 		for (int i = 0; i < ValRows*ValCols; i++)
    128 			dst[i] = data[i];
    129 	}
    130 };
    131 
    132 struct TextureSpec
    133 {
    134 	gls::TextureTestUtil::TextureType	textureType;
    135 	deUint32							textureUnit;
    136 	int									width;
    137 	int									height;
    138 	deUint32							format;
    139 	deUint32							dataType;
    140 	deUint32							internalFormat;
    141 	bool								useMipmap;
    142 	deUint32							minFilter;
    143 	deUint32							magFilter;
    144 	deUint32							sWrap;
    145 	deUint32							tWrap;
    146 	tcu::Vec4							minValue;
    147 	tcu::Vec4							maxValue;
    148 
    149 	TextureSpec (const gls::TextureTestUtil::TextureType	texType,
    150 				 const deUint32								unit,
    151 				 const int									width_,
    152 				 const int									height_,
    153 				 const deUint32								format_,
    154 				 const deUint32								dataType_,
    155 				 const deUint32								internalFormat_,
    156 				 const bool									useMipmap_,
    157 				 const deUint32								minFilter_,
    158 				 const deUint32								magFilter_,
    159 				 const deUint32								sWrap_,
    160 				 const deUint32								tWrap_,
    161 				 const tcu::Vec4&							minValue_,
    162 				 const tcu::Vec4&							maxValue_)
    163 		: textureType		(texType)
    164 		, textureUnit		(unit)
    165 		, width				(width_)
    166 		, height			(height_)
    167 		, format			(format_)
    168 		, dataType			(dataType_)
    169 		, internalFormat	(internalFormat_)
    170 		, useMipmap			(useMipmap_)
    171 		, minFilter			(minFilter_)
    172 		, magFilter			(magFilter_)
    173 		, sWrap				(sWrap_)
    174 		, tWrap				(tWrap_)
    175 		, minValue			(minValue_)
    176 		, maxValue			(maxValue_)
    177 	{
    178 	}
    179 };
    180 
    181 /*--------------------------------------------------------------------*//*!
    182  * \brief Struct for a shader program sources and related data
    183  *
    184  * A ProgramContext holds a program's vertex and fragment shader sources
    185  * as well as specifications of its attributes, uniforms, and textures.
    186  * When given to a StressCase, the string ${NS} is replaced by a magic
    187  * number that varies between different compilations of the same program;
    188  * the same replacement is done in attributes' and uniforms' names. This
    189  * can be used to avoid shader caching by the GL, by e.g. suffixing each
    190  * attribute, uniform and varying name with ${NS} in the shader source.
    191  *//*--------------------------------------------------------------------*/
    192 struct ProgramContext
    193 {
    194 	std::string							vertexSource;
    195 	std::string							fragmentSource;
    196 	std::vector<VarSpec>				attributes;
    197 	std::vector<VarSpec>				uniforms;
    198 
    199 	std::vector<TextureSpec>			textureSpecs;		//!< \note If multiple textures have same unit, one of them is picked randomly.
    200 
    201 	std::string							positionAttrName;	//!< \note Position attribute may get a bit more careful handling than just complete random.
    202 
    203 	ProgramContext (const char* const vtxShaderSource_,
    204 					const char* const fragShaderSource_,
    205 					const char* const positionAttrName_)
    206 		: vertexSource		(vtxShaderSource_)
    207 		, fragmentSource	(fragShaderSource_)
    208 		, positionAttrName	(positionAttrName_)
    209 	{
    210 	}
    211 };
    212 
    213 class LongStressCase : public tcu::TestCase
    214 {
    215 public:
    216 	//! Probabilities for actions that may be taken on each iteration. \note The texture and buffer specific actions are randomized per texture or buffer.
    217 	struct FeatureProbabilities
    218 	{
    219 		float rebuildProgram;				//!< Rebuild program, with variable name-mangling.
    220 		float reuploadTexture;				//!< Reupload texture, even if it already exists and has been uploaded.
    221 		float reuploadBuffer;				//!< Reupload buffer, even if it already exists and has been uploaded.
    222 		float reuploadWithTexImage;			//!< Use glTexImage*() when re-uploading texture, not glTexSubImage*().
    223 		float reuploadWithBufferData;		//!< Use glBufferData() when re-uploading buffer, not glBufferSubData().
    224 		float deleteTexture;				//!< Delete texture at end of iteration, even if we could re-use it.
    225 		float deleteBuffer;					//!< Delete buffer at end of iteration, even if we could re-use it.
    226 		float wastefulTextureMemoryUsage;	//!< Don't re-use a texture, and don't delete it until given memory limit is hit.
    227 		float wastefulBufferMemoryUsage;	//!< Don't re-use a buffer, and don't delete it until given memory limit is hit.
    228 		float clientMemoryAttributeData;	//!< Use client memory for vertex attribute data when drawing (instead of GL buffers).
    229 		float clientMemoryIndexData;		//!< Use client memory for vertex indices when drawing (instead of GL buffers).
    230 		float randomBufferUploadTarget;		//!< Use a random target when setting buffer data (i.e. not necessarily the one it'll be ultimately bound to).
    231 		float randomBufferUsage;			//!< Use a random buffer usage parameter with glBufferData(), instead of the ones specified as params for the case.
    232 		float useDrawArrays;				//!< Use glDrawArrays() instead of glDrawElements().
    233 		float separateAttributeBuffers;		//!< Give each vertex attribute its own buffer.
    234 
    235 		// Named parameter idiom: helpers that can be used when making temporaries, e.g. FeatureProbabilities().pReuploadTexture(1.0f).pReuploadWithTexImage(1.0f)
    236 		FeatureProbabilities& pRebuildProgram				(const float prob) { rebuildProgram					= prob; return *this; }
    237 		FeatureProbabilities& pReuploadTexture				(const float prob) { reuploadTexture				= prob; return *this; }
    238 		FeatureProbabilities& pReuploadBuffer				(const float prob) { reuploadBuffer					= prob; return *this; }
    239 		FeatureProbabilities& pReuploadWithTexImage			(const float prob) { reuploadWithTexImage			= prob; return *this; }
    240 		FeatureProbabilities& pReuploadWithBufferData		(const float prob) { reuploadWithBufferData			= prob; return *this; }
    241 		FeatureProbabilities& pDeleteTexture				(const float prob) { deleteTexture					= prob; return *this; }
    242 		FeatureProbabilities& pDeleteBuffer					(const float prob) { deleteBuffer					= prob; return *this; }
    243 		FeatureProbabilities& pWastefulTextureMemoryUsage	(const float prob) { wastefulTextureMemoryUsage		= prob; return *this; }
    244 		FeatureProbabilities& pWastefulBufferMemoryUsage	(const float prob) { wastefulBufferMemoryUsage		= prob; return *this; }
    245 		FeatureProbabilities& pClientMemoryAttributeData	(const float prob) { clientMemoryAttributeData		= prob; return *this; }
    246 		FeatureProbabilities& pClientMemoryIndexData		(const float prob) { clientMemoryIndexData			= prob; return *this; }
    247 		FeatureProbabilities& pRandomBufferUploadTarget		(const float prob) { randomBufferUploadTarget		= prob; return *this; }
    248 		FeatureProbabilities& pRandomBufferUsage			(const float prob) { randomBufferUsage				= prob; return *this; }
    249 		FeatureProbabilities& pUseDrawArrays				(const float prob) { useDrawArrays					= prob; return *this; }
    250 		FeatureProbabilities& pSeparateAttribBuffers		(const float prob) { separateAttributeBuffers		= prob; return *this; }
    251 
    252 		FeatureProbabilities (void)
    253 			: rebuildProgram				(0.0f)
    254 			, reuploadTexture				(0.0f)
    255 			, reuploadBuffer				(0.0f)
    256 			, reuploadWithTexImage			(0.0f)
    257 			, reuploadWithBufferData		(0.0f)
    258 			, deleteTexture					(0.0f)
    259 			, deleteBuffer					(0.0f)
    260 			, wastefulTextureMemoryUsage	(0.0f)
    261 			, wastefulBufferMemoryUsage		(0.0f)
    262 			, clientMemoryAttributeData		(0.0f)
    263 			, clientMemoryIndexData			(0.0f)
    264 			, randomBufferUploadTarget		(0.0f)
    265 			, randomBufferUsage				(0.0f)
    266 			, useDrawArrays					(0.0f)
    267 			, separateAttributeBuffers		(0.0f)
    268 		{
    269 		}
    270 	};
    271 
    272 															LongStressCase						(tcu::TestContext&						testCtx,
    273 																								 const glu::RenderContext&				renderCtx,
    274 																								 const char*							name,
    275 																								 const char*							desc,
    276 																								 int									maxTexMemoryUsageBytes, //!< Approximate upper bound on GL texture memory usage.
    277 																								 int									maxBufMemoryUsageBytes, //!< Approximate upper bound on GL buffer memory usage.
    278 																								 int									numDrawCallsPerIteration,
    279 																								 int									numTrianglesPerDrawCall,
    280 																								 const std::vector<ProgramContext>&		programContexts,
    281 																								 const FeatureProbabilities&			probabilities,
    282 																								 deUint32								indexBufferUsage,
    283 																								 deUint32								attrBufferUsage,
    284 																								 int									redundantBufferFactor = 1,
    285 																								 bool									showDebugInfo = false);
    286 
    287 															~LongStressCase						(void);
    288 
    289 	void													init								(void);
    290 	void													deinit								(void);
    291 
    292 	IterateResult											iterate								(void);
    293 
    294 private:
    295 															LongStressCase						(const LongStressCase&);
    296 	LongStressCase&											operator=							(const LongStressCase&);
    297 
    298 	const glu::RenderContext&								m_renderCtx;
    299 	const int												m_maxTexMemoryUsageBytes;
    300 	const int												m_maxBufMemoryUsageBytes;
    301 	const int												m_numDrawCallsPerIteration;
    302 	const int												m_numTrianglesPerDrawCall;
    303 	const int												m_numVerticesPerDrawCall;
    304 	const std::vector<ProgramContext>						m_programContexts;
    305 	const FeatureProbabilities								m_probabilities;
    306 	const deUint32											m_indexBufferUsage;
    307 	const deUint32											m_attrBufferUsage;
    308 	const int												m_redundantBufferFactor; //!< By what factor we allocate redundant buffers. Default is 1, i.e. no redundancy.
    309 	const bool												m_showDebugInfo;
    310 
    311 	const int												m_numIterations;
    312 	const bool												m_isGLES3;
    313 
    314 	int														m_currentIteration;
    315 	deUint64												m_startTimeSeconds; //!< Set at beginning of first iteration.
    316 	deUint64												m_lastLogTime;
    317 	int														m_lastLogIteration;
    318 	int														m_currentLogEntryNdx;
    319 
    320 	de::Random												m_rnd;
    321 	LongStressCaseInternal::GLObjectManager<
    322 		LongStressCaseInternal::Program>*					m_programs;
    323 	LongStressCaseInternal::GLObjectManager<
    324 		LongStressCaseInternal::Buffer>*					m_buffers;
    325 	LongStressCaseInternal::GLObjectManager<
    326 		LongStressCaseInternal::Texture>*					m_textures;
    327 	std::vector<deUint16>									m_vertexIndices;
    328 
    329 	struct ProgramResources
    330 	{
    331 		std::vector<deUint8>							attrDataBuf;
    332 		std::vector<int>								attrDataOffsets;
    333 		std::vector<int>								attrDataSizes;
    334 		std::vector<de::SharedPtr<tcu::TextureLevel> >	dummyTextures;
    335 		std::string										shaderNameManglingSuffix;
    336 	};
    337 
    338 	std::vector<ProgramResources>							m_programResources;
    339 
    340 	LongStressCaseInternal::DebugInfoRenderer*				m_debugInfoRenderer;
    341 };
    342 
    343 
    344 } // gls
    345 } // deqp
    346 
    347 #endif // _GLSLONGSTRESSCASE_HPP
    348