1 #ifndef _GLSSTATEQUERYUTIL_HPP 2 #define _GLSSTATEQUERYUTIL_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 State Query test utils. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "tcuDefs.hpp" 27 #include "tcuTestLog.hpp" 28 #include "tcuTestContext.hpp" 29 #include "tcuResultCollector.hpp" 30 #include "glwDefs.hpp" 31 #include "deMath.h" 32 33 namespace glu 34 { 35 class CallLogWrapper; 36 } // glu 37 38 namespace deqp 39 { 40 namespace gls 41 { 42 namespace StateQueryUtil 43 { 44 45 #define GLS_COLLECT_GL_ERROR(RES, ERR, MSG) \ 46 do \ 47 { \ 48 const deUint32 err = (ERR); \ 49 if (err != GL_NO_ERROR) \ 50 (RES).fail(std::string("Got Error ") + glu::getErrorStr(err).toString() + ": " + (MSG)); \ 51 } \ 52 while (deGetFalse()) 53 54 /*--------------------------------------------------------------------*//*! 55 * \brief Rounds given float to the nearest integer (half up). 56 * 57 * Returns the nearest integer for a float argument. In the case that there 58 * are two nearest integers at the equal distance (aka. the argument is of 59 * form x.5), the integer with the higher value is chosen. (x.5 rounds to x+1) 60 *//*--------------------------------------------------------------------*/ 61 template <typename T> 62 T roundGLfloatToNearestIntegerHalfUp (float val) 63 { 64 return (T)(deFloatFloor(val + 0.5f)); 65 } 66 67 /*--------------------------------------------------------------------*//*! 68 * \brief Rounds given float to the nearest integer (half down). 69 * 70 * Returns the nearest integer for a float argument. In the case that there 71 * are two nearest integers at the equal distance (aka. the argument is of 72 * form x.5), the integer with the higher value is chosen. (x.5 rounds to x) 73 *//*--------------------------------------------------------------------*/ 74 template <typename T> 75 T roundGLfloatToNearestIntegerHalfDown (float val) 76 { 77 return (T)(deFloatCeil(val - 0.5f)); 78 } 79 80 template <typename T> 81 class StateQueryMemoryWriteGuard 82 { 83 public: 84 StateQueryMemoryWriteGuard (void); 85 86 operator T& (void); 87 T* operator & (void); 88 89 bool isUndefined (void) const; 90 bool isMemoryContaminated (void) const; 91 bool isPreguardContaminated (void) const; 92 bool isPostguardContaminated (void) const; 93 bool verifyValidity (tcu::TestContext& testCtx) const; 94 bool verifyValidity (tcu::ResultCollector& result) const; 95 96 const T& get (void) const { return m_value; } 97 98 private: 99 enum 100 { 101 WRITE_GUARD_VALUE = 0xDE 102 }; 103 104 T m_preguard; 105 T m_value; 106 T m_postguard; // \note guards are not const qualified since the GL implementation might modify them 107 }; 108 109 template <typename T> 110 StateQueryMemoryWriteGuard<T>::StateQueryMemoryWriteGuard (void) 111 { 112 DE_STATIC_ASSERT(sizeof(T) * 3 == sizeof(StateQueryMemoryWriteGuard<T>)); // tightly packed 113 114 for (size_t i = 0; i < sizeof(T); ++i) 115 { 116 ((deUint8*)&m_preguard)[i] = (deUint8)WRITE_GUARD_VALUE; 117 ((deUint8*)&m_value)[i] = (deUint8)WRITE_GUARD_VALUE; 118 ((deUint8*)&m_postguard)[i] = (deUint8)WRITE_GUARD_VALUE; 119 } 120 } 121 122 template <typename T> 123 StateQueryMemoryWriteGuard<T>::operator T& (void) 124 { 125 return m_value; 126 } 127 128 template <typename T> 129 T* StateQueryMemoryWriteGuard<T>::operator & (void) 130 { 131 return &m_value; 132 } 133 134 template <typename T> 135 bool StateQueryMemoryWriteGuard<T>::isUndefined () const 136 { 137 for (size_t i = 0; i < sizeof(T); ++i) 138 if (((deUint8*)&m_value)[i] != (deUint8)WRITE_GUARD_VALUE) 139 return false; 140 return true; 141 } 142 143 template <typename T> 144 bool StateQueryMemoryWriteGuard<T>::isMemoryContaminated () const 145 { 146 return isPreguardContaminated() || isPostguardContaminated(); 147 } 148 149 template <typename T> 150 bool StateQueryMemoryWriteGuard<T>::isPreguardContaminated (void) const 151 { 152 for (size_t i = 0; i < sizeof(T); ++i) 153 if (((deUint8*)&m_preguard)[i] != (deUint8)WRITE_GUARD_VALUE) 154 return true; 155 return false; 156 } 157 158 template <typename T> 159 bool StateQueryMemoryWriteGuard<T>::isPostguardContaminated (void) const 160 { 161 for (size_t i = 0; i < sizeof(T); ++i) 162 if (((deUint8*)&m_postguard)[i] != (deUint8)WRITE_GUARD_VALUE) 163 return true; 164 return false; 165 } 166 167 template <typename T> 168 bool StateQueryMemoryWriteGuard<T>::verifyValidity (tcu::TestContext& testCtx) const 169 { 170 using tcu::TestLog; 171 172 if (isPreguardContaminated()) 173 { 174 testCtx.getLog() << TestLog::Message << "// ERROR: Pre-guard value was modified " << TestLog::EndMessage; 175 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 176 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 177 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write"); 178 179 return false; 180 } 181 else if (isPostguardContaminated()) 182 { 183 testCtx.getLog() << TestLog::Message << "// ERROR: Post-guard value was modified " << TestLog::EndMessage; 184 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 185 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 186 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write"); 187 188 return false; 189 } 190 else if (isUndefined()) 191 { 192 testCtx.getLog() << TestLog::Message << "// ERROR: Get* did not return a value" << TestLog::EndMessage; 193 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 194 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 195 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did not return a value"); 196 197 return false; 198 } 199 200 return true; 201 } 202 203 template <typename T> 204 bool StateQueryMemoryWriteGuard<T>::verifyValidity (tcu::ResultCollector& result) const 205 { 206 using tcu::TestLog; 207 208 if (isPreguardContaminated()) 209 { 210 result.fail("pre-guard value was modified"); 211 return false; 212 } 213 else if (isPostguardContaminated()) 214 { 215 result.fail("post-guard value was modified"); 216 return false; 217 } 218 else if (isUndefined()) 219 { 220 result.fail("Get* did not return a value"); 221 return false; 222 } 223 224 return true; 225 } 226 227 template<typename T> 228 std::ostream& operator<< (std::ostream& str, const StateQueryMemoryWriteGuard<T>& guard) 229 { 230 return str << guard.get(); 231 } 232 233 // Verifiers 234 235 enum QueryType 236 { 237 QUERY_BOOLEAN = 0, 238 QUERY_BOOLEAN_VEC4, 239 QUERY_ISENABLED, 240 QUERY_INTEGER, 241 QUERY_INTEGER64, 242 QUERY_FLOAT, 243 244 // indexed 245 QUERY_INDEXED_BOOLEAN, 246 QUERY_INDEXED_BOOLEAN_VEC4, 247 QUERY_INDEXED_ISENABLED, 248 QUERY_INDEXED_INTEGER, 249 QUERY_INDEXED_INTEGER_VEC4, 250 QUERY_INDEXED_INTEGER64, 251 QUERY_INDEXED_INTEGER64_VEC4, 252 253 // attributes 254 QUERY_ATTRIBUTE_INTEGER, 255 QUERY_ATTRIBUTE_FLOAT, 256 QUERY_ATTRIBUTE_PURE_INTEGER, 257 QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER, 258 259 // fb 260 QUERY_FRAMEBUFFER_INTEGER, 261 262 // program 263 QUERY_PROGRAM_INTEGER, 264 QUERY_PROGRAM_INTEGER_VEC3, 265 266 // program pipeline 267 QUERY_PIPELINE_INTEGER, 268 269 // texture param 270 QUERY_TEXTURE_PARAM_INTEGER, 271 QUERY_TEXTURE_PARAM_FLOAT, 272 QUERY_TEXTURE_PARAM_PURE_INTEGER, 273 QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER, 274 QUERY_TEXTURE_PARAM_INTEGER_VEC4, 275 QUERY_TEXTURE_PARAM_FLOAT_VEC4, 276 QUERY_TEXTURE_PARAM_PURE_INTEGER_VEC4, 277 QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER_VEC4, 278 279 // texture level 280 QUERY_TEXTURE_LEVEL_INTEGER, 281 QUERY_TEXTURE_LEVEL_FLOAT, 282 283 // pointer 284 QUERY_POINTER, 285 286 // object states 287 QUERY_ISTEXTURE, 288 289 // query queries 290 QUERY_QUERY, 291 292 // sampler state 293 QUERY_SAMPLER_PARAM_INTEGER, 294 QUERY_SAMPLER_PARAM_FLOAT, 295 QUERY_SAMPLER_PARAM_PURE_INTEGER, 296 QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER, 297 QUERY_SAMPLER_PARAM_INTEGER_VEC4, 298 QUERY_SAMPLER_PARAM_FLOAT_VEC4, 299 QUERY_SAMPLER_PARAM_PURE_INTEGER_VEC4, 300 QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER_VEC4, 301 302 QUERY_LAST 303 }; 304 305 enum DataType 306 { 307 DATATYPE_BOOLEAN = 0, 308 DATATYPE_INTEGER, 309 DATATYPE_INTEGER64, 310 DATATYPE_FLOAT, 311 DATATYPE_UNSIGNED_INTEGER, 312 DATATYPE_INTEGER_VEC3, 313 DATATYPE_FLOAT_VEC4, 314 DATATYPE_INTEGER_VEC4, 315 DATATYPE_INTEGER64_VEC4, 316 DATATYPE_UNSIGNED_INTEGER_VEC4, 317 DATATYPE_BOOLEAN_VEC4, 318 DATATYPE_POINTER, 319 320 DATATYPE_LAST 321 }; 322 323 class QueriedState 324 { 325 public: 326 typedef glw::GLint GLIntVec3[3]; 327 typedef glw::GLint GLIntVec4[4]; 328 typedef glw::GLuint GLUintVec4[4]; 329 typedef glw::GLfloat GLFloatVec4[4]; 330 typedef bool BooleanVec4[4]; 331 typedef glw::GLint64 GLInt64Vec4[4]; 332 333 QueriedState (void); 334 explicit QueriedState (glw::GLint); 335 explicit QueriedState (glw::GLint64); 336 explicit QueriedState (bool); 337 explicit QueriedState (glw::GLfloat); 338 explicit QueriedState (glw::GLuint); 339 explicit QueriedState (const GLIntVec3&); 340 explicit QueriedState (void*); 341 explicit QueriedState (const GLIntVec4&); 342 explicit QueriedState (const GLUintVec4&); 343 explicit QueriedState (const GLFloatVec4&); 344 explicit QueriedState (const BooleanVec4&); 345 explicit QueriedState (const GLInt64Vec4&); 346 347 bool isUndefined (void) const; 348 DataType getType (void) const; 349 350 glw::GLint& getIntAccess (void); 351 glw::GLint64& getInt64Access (void); 352 bool& getBoolAccess (void); 353 glw::GLfloat& getFloatAccess (void); 354 glw::GLuint& getUintAccess (void); 355 GLIntVec3& getIntVec3Access (void); 356 void*& getPtrAccess (void); 357 GLIntVec4& getIntVec4Access (void); 358 GLUintVec4& getUintVec4Access (void); 359 GLFloatVec4& getFloatVec4Access (void); 360 BooleanVec4& getBooleanVec4Access (void); 361 GLInt64Vec4& getInt64Vec4Access (void); 362 363 private: 364 DataType m_type; 365 union 366 { 367 glw::GLint vInt; 368 glw::GLint64 vInt64; 369 bool vBool; 370 glw::GLfloat vFloat; 371 glw::GLuint vUint; 372 GLIntVec3 vIntVec3; 373 void* vPtr; 374 GLIntVec4 vIntVec4; 375 GLUintVec4 vUintVec4; 376 GLFloatVec4 vFloatVec4; 377 BooleanVec4 vBooleanVec4; 378 GLInt64Vec4 vInt64Vec4; 379 } m_v; 380 }; 381 382 // query functions 383 384 void queryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state); 385 void queryIndexedState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state); 386 void queryAttributeState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state); 387 void queryFramebufferState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state); 388 void queryProgramState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint program, glw::GLenum pname, QueriedState& state); 389 void queryPipelineState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint pipeline, glw::GLenum pname, QueriedState& state); 390 void queryTextureParamState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state); 391 void queryTextureLevelState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int level, glw::GLenum pname, QueriedState& state); 392 void queryPointerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state); 393 void queryObjectState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint handle, QueriedState& state); 394 void queryQueryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state); 395 void querySamplerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint sampler, glw::GLenum pname, QueriedState& state); 396 397 // verification functions 398 399 void verifyBoolean (tcu::ResultCollector& result, QueriedState& state, bool expected); 400 void verifyInteger (tcu::ResultCollector& result, QueriedState& state, int expected); 401 void verifyIntegerMin (tcu::ResultCollector& result, QueriedState& state, int minValue); 402 void verifyIntegerMax (tcu::ResultCollector& result, QueriedState& state, int maxValue); 403 void verifyIntegersEqual (tcu::ResultCollector& result, QueriedState& stateA, QueriedState& stateB); 404 void verifyFloat (tcu::ResultCollector& result, QueriedState& state, float expected); 405 void verifyFloatMin (tcu::ResultCollector& result, QueriedState& state, float minValue); 406 void verifyFloatMax (tcu::ResultCollector& result, QueriedState& state, float maxValue); 407 void verifyIntegerVec3 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec3& expected); 408 void verifyIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected); 409 void verifyUnsignedIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::UVec4& expected); 410 void verifyFloatVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::Vec4& expected); 411 void verifyBooleanVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::BVec4& expected); 412 void verifyPointer (tcu::ResultCollector& result, QueriedState& state, const void* expected); 413 void verifyNormalizedI32Vec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected); 414 415 // Helper functions that both query and verify 416 417 void verifyStateBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, bool expected, QueryType type); 418 void verifyStateInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int expected, QueryType type); 419 void verifyStateIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int minValue, QueryType type); 420 void verifyStateIntegerMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int maxValue, QueryType type); 421 void verifyStateIntegerEqualToOther (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum other, QueryType type); 422 void verifyStateFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float reference, QueryType type); 423 void verifyStateFloatMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float minValue, QueryType type); 424 void verifyStateFloatMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float maxValue, QueryType type); 425 void verifyStatePointer (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, const void* expected, QueryType type); 426 void verifyStateIndexedBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, bool expected, QueryType type); 427 void verifyStateIndexedBooleanVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, const tcu::BVec4& expected, QueryType type); 428 void verifyStateIndexedInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type); 429 void verifyStateIndexedIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int minValue, QueryType type); 430 void verifyStateAttributeInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type); 431 void verifyStateFramebufferInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type); 432 void verifyStateFramebufferIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int minValue, QueryType type); 433 void verifyStateProgramInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, int expected, QueryType type); 434 void verifyStateProgramIntegerVec3 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, const tcu::IVec3& expected, QueryType type); 435 void verifyStatePipelineInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint pipeline, glw::GLenum pname, int expected, QueryType type); 436 void verifyStateTextureParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type); 437 void verifyStateTextureParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, float expected, QueryType type); 438 void verifyStateTextureParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::Vec4& expected, QueryType type); 439 void verifyStateTextureParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type); 440 void verifyStateTextureParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type); 441 void verifyStateTextureParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::UVec4& expected, QueryType type); 442 void verifyStateTextureLevelInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int expected, QueryType type); 443 void verifyStateObjectBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint handle, bool expected, QueryType type); 444 void verifyStateQueryInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type); 445 void verifyStateSamplerParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, int expected, QueryType type); 446 void verifyStateSamplerParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, float expected, QueryType type); 447 void verifyStateSamplerParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::Vec4& expected, QueryType type); 448 void verifyStateSamplerParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type); 449 void verifyStateSamplerParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type); 450 void verifyStateSamplerParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::UVec4& expected, QueryType type); 451 452 } // StateQueryUtil 453 } // gls 454 } // deqp 455 456 #endif // _GLSSTATEQUERYUTIL_HPP 457