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