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> VarSpecdeqp::gls::VarSpec70 VarSpec (const std::string& name_, const T& minValue_, const T& maxValue_) : name(name_) { set(minValue_, maxValue_); } 71 72 template <typename T> VarSpecdeqp::gls::VarSpec73 VarSpec (const std::string& name_, const T& value) : name(name_) { set(value, value); } 74 setdeqp::gls::VarSpec75 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> setdeqp::gls::VarSpec83 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> setdeqp::gls::VarSpec91 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 setdeqp::gls::VarSpec98 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> setdeqp::gls::VarSpec106 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> vecToArrdeqp::gls::VarSpec115 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> matToArrdeqp::gls::VarSpec123 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 glu::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 TextureSpecdeqp::gls::TextureSpec149 TextureSpec (const glu::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 ProgramContextdeqp::gls::ProgramContext203 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) pRebuildProgramdeqp::gls::LongStressCase::FeatureProbabilities236 FeatureProbabilities& pRebuildProgram (const float prob) { rebuildProgram = prob; return *this; } pReuploadTexturedeqp::gls::LongStressCase::FeatureProbabilities237 FeatureProbabilities& pReuploadTexture (const float prob) { reuploadTexture = prob; return *this; } pReuploadBufferdeqp::gls::LongStressCase::FeatureProbabilities238 FeatureProbabilities& pReuploadBuffer (const float prob) { reuploadBuffer = prob; return *this; } pReuploadWithTexImagedeqp::gls::LongStressCase::FeatureProbabilities239 FeatureProbabilities& pReuploadWithTexImage (const float prob) { reuploadWithTexImage = prob; return *this; } pReuploadWithBufferDatadeqp::gls::LongStressCase::FeatureProbabilities240 FeatureProbabilities& pReuploadWithBufferData (const float prob) { reuploadWithBufferData = prob; return *this; } pDeleteTexturedeqp::gls::LongStressCase::FeatureProbabilities241 FeatureProbabilities& pDeleteTexture (const float prob) { deleteTexture = prob; return *this; } pDeleteBufferdeqp::gls::LongStressCase::FeatureProbabilities242 FeatureProbabilities& pDeleteBuffer (const float prob) { deleteBuffer = prob; return *this; } pWastefulTextureMemoryUsagedeqp::gls::LongStressCase::FeatureProbabilities243 FeatureProbabilities& pWastefulTextureMemoryUsage (const float prob) { wastefulTextureMemoryUsage = prob; return *this; } pWastefulBufferMemoryUsagedeqp::gls::LongStressCase::FeatureProbabilities244 FeatureProbabilities& pWastefulBufferMemoryUsage (const float prob) { wastefulBufferMemoryUsage = prob; return *this; } pClientMemoryAttributeDatadeqp::gls::LongStressCase::FeatureProbabilities245 FeatureProbabilities& pClientMemoryAttributeData (const float prob) { clientMemoryAttributeData = prob; return *this; } pClientMemoryIndexDatadeqp::gls::LongStressCase::FeatureProbabilities246 FeatureProbabilities& pClientMemoryIndexData (const float prob) { clientMemoryIndexData = prob; return *this; } pRandomBufferUploadTargetdeqp::gls::LongStressCase::FeatureProbabilities247 FeatureProbabilities& pRandomBufferUploadTarget (const float prob) { randomBufferUploadTarget = prob; return *this; } pRandomBufferUsagedeqp::gls::LongStressCase::FeatureProbabilities248 FeatureProbabilities& pRandomBufferUsage (const float prob) { randomBufferUsage = prob; return *this; } pUseDrawArraysdeqp::gls::LongStressCase::FeatureProbabilities249 FeatureProbabilities& pUseDrawArrays (const float prob) { useDrawArrays = prob; return *this; } pSeparateAttribBuffersdeqp::gls::LongStressCase::FeatureProbabilities250 FeatureProbabilities& pSeparateAttribBuffers (const float prob) { separateAttributeBuffers = prob; return *this; } 251 FeatureProbabilitiesdeqp::gls::LongStressCase::FeatureProbabilities252 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