glsStateQueryUtil.hpp revision cb82ed72dcbbfd8a6d07736c3259605227bc984f
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 "glwDefs.hpp" 30#include "deMath.h" 31 32namespace glu 33{ 34class CallLogWrapper; 35} // glu 36 37namespace deqp 38{ 39namespace gls 40{ 41namespace StateQueryUtil 42{ 43 44/*--------------------------------------------------------------------*//*! 45 * \brief Rounds given float to the nearest integer (half up). 46 * 47 * Returns the nearest integer for a float argument. In the case that there 48 * are two nearest integers at the equal distance (aka. the argument is of 49 * form x.5), the integer with the higher value is chosen. (x.5 rounds to x+1) 50 *//*--------------------------------------------------------------------*/ 51template <typename T> 52T roundGLfloatToNearestIntegerHalfUp (float val) 53{ 54 return (T)(deFloatFloor(val + 0.5f)); 55} 56 57/*--------------------------------------------------------------------*//*! 58 * \brief Rounds given float to the nearest integer (half down). 59 * 60 * Returns the nearest integer for a float argument. In the case that there 61 * are two nearest integers at the equal distance (aka. the argument is of 62 * form x.5), the integer with the higher value is chosen. (x.5 rounds to x) 63 *//*--------------------------------------------------------------------*/ 64template <typename T> 65T roundGLfloatToNearestIntegerHalfDown (float val) 66{ 67 return (T)(deFloatCeil(val - 0.5f)); 68} 69 70template <typename T> 71class StateQueryMemoryWriteGuard 72{ 73public: 74 StateQueryMemoryWriteGuard (void); 75 76 operator T& (void); 77 T* operator & (void); 78 79 bool isUndefined (void) const; 80 bool isMemoryContaminated (void) const; 81 bool isPreguardContaminated (void) const; 82 bool isPostguardContaminated (void) const; 83 bool verifyValidity (tcu::TestContext& testCtx) const; 84 bool verifyValidity (tcu::ResultCollector& result) const; 85 86 const T& get (void) const { return m_value; } 87 88private: 89 enum 90 { 91 WRITE_GUARD_VALUE = 0xDE 92 }; 93 94 T m_preguard; 95 T m_value; 96 T m_postguard; // \note guards are not const qualified since the GL implementation might modify them 97}; 98 99template <typename T> 100StateQueryMemoryWriteGuard<T>::StateQueryMemoryWriteGuard (void) 101{ 102 DE_STATIC_ASSERT(sizeof(T) * 3 == sizeof(StateQueryMemoryWriteGuard<T>)); // tightly packed 103 104 for (size_t i = 0; i < sizeof(T); ++i) 105 { 106 ((deUint8*)&m_preguard)[i] = (deUint8)WRITE_GUARD_VALUE; 107 ((deUint8*)&m_value)[i] = (deUint8)WRITE_GUARD_VALUE; 108 ((deUint8*)&m_postguard)[i] = (deUint8)WRITE_GUARD_VALUE; 109 } 110} 111 112template <typename T> 113StateQueryMemoryWriteGuard<T>::operator T& (void) 114{ 115 return m_value; 116} 117 118template <typename T> 119T* StateQueryMemoryWriteGuard<T>::operator & (void) 120{ 121 return &m_value; 122} 123 124template <typename T> 125bool StateQueryMemoryWriteGuard<T>::isUndefined () const 126{ 127 for (size_t i = 0; i < sizeof(T); ++i) 128 if (((deUint8*)&m_value)[i] != (deUint8)WRITE_GUARD_VALUE) 129 return false; 130 return true; 131} 132 133template <typename T> 134bool StateQueryMemoryWriteGuard<T>::isMemoryContaminated () const 135{ 136 return isPreguardContaminated() || isPostguardContaminated(); 137} 138 139template <typename T> 140bool StateQueryMemoryWriteGuard<T>::isPreguardContaminated (void) const 141{ 142 for (size_t i = 0; i < sizeof(T); ++i) 143 if (((deUint8*)&m_preguard)[i] != (deUint8)WRITE_GUARD_VALUE) 144 return true; 145 return false; 146} 147 148template <typename T> 149bool StateQueryMemoryWriteGuard<T>::isPostguardContaminated (void) const 150{ 151 for (size_t i = 0; i < sizeof(T); ++i) 152 if (((deUint8*)&m_postguard)[i] != (deUint8)WRITE_GUARD_VALUE) 153 return true; 154 return false; 155} 156 157template <typename T> 158bool StateQueryMemoryWriteGuard<T>::verifyValidity (tcu::TestContext& testCtx) const 159{ 160 using tcu::TestLog; 161 162 if (isPreguardContaminated()) 163 { 164 testCtx.getLog() << TestLog::Message << "// ERROR: Pre-guard value was modified " << TestLog::EndMessage; 165 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 166 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 167 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write"); 168 169 return false; 170 } 171 else if (isPostguardContaminated()) 172 { 173 testCtx.getLog() << TestLog::Message << "// ERROR: Post-guard value was modified " << TestLog::EndMessage; 174 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 175 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 176 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write"); 177 178 return false; 179 } 180 else if (isUndefined()) 181 { 182 testCtx.getLog() << TestLog::Message << "// ERROR: Get* did not return a value" << TestLog::EndMessage; 183 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 184 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 185 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did not return a value"); 186 187 return false; 188 } 189 190 return true; 191} 192 193template <typename T> 194bool StateQueryMemoryWriteGuard<T>::verifyValidity (tcu::ResultCollector& result) const 195{ 196 using tcu::TestLog; 197 198 if (isPreguardContaminated()) 199 { 200 result.fail("pre-guard value was modified"); 201 return false; 202 } 203 else if (isPostguardContaminated()) 204 { 205 result.fail("post-guard value was modified"); 206 return false; 207 } 208 else if (isUndefined()) 209 { 210 result.fail("Get* did not return a value"); 211 return false; 212 } 213 214 return true; 215} 216 217template<typename T> 218std::ostream& operator<< (std::ostream& str, const StateQueryMemoryWriteGuard<T>& guard) 219{ 220 return str << guard.get(); 221} 222 223// Verifiers 224 225enum QueryType 226{ 227 QUERY_BOOLEAN = 0, 228 QUERY_BOOLEAN_VEC4, 229 QUERY_ISENABLED, 230 QUERY_INTEGER, 231 QUERY_INTEGER64, 232 QUERY_FLOAT, 233 234 // indexed 235 QUERY_INDEXED_BOOLEAN, 236 QUERY_INDEXED_INTEGER, 237 QUERY_INDEXED_INTEGER64, 238 239 // attributes 240 QUERY_ATTRIBUTE_INTEGER, 241 QUERY_ATTRIBUTE_FLOAT, 242 QUERY_ATTRIBUTE_PURE_INTEGER, 243 QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER, 244 245 // fb 246 QUERY_FRAMEBUFFER_INTEGER, 247 248 // program 249 QUERY_PROGRAM_INTEGER, 250 QUERY_PROGRAM_INTEGER_VEC3, 251 252 // program pipeline 253 QUERY_PIPELINE_INTEGER, 254 255 // texture param 256 QUERY_TEXTURE_PARAM_INTEGER, 257 QUERY_TEXTURE_PARAM_FLOAT, 258 259 // texture level 260 QUERY_TEXTURE_LEVEL_INTEGER, 261 QUERY_TEXTURE_LEVEL_FLOAT, 262 263 QUERY_LAST 264}; 265 266enum DataType 267{ 268 DATATYPE_BOOLEAN = 0, 269 DATATYPE_INTEGER, 270 DATATYPE_INTEGER64, 271 DATATYPE_FLOAT, 272 DATATYPE_UNSIGNED_INTEGER, 273 DATATYPE_INTEGER_VEC3, 274 275 DATATYPE_LAST 276}; 277 278class QueriedState 279{ 280public: 281 typedef glw::GLint GLIntVec3[3]; 282 283 QueriedState (void); 284 explicit QueriedState (glw::GLint); 285 explicit QueriedState (glw::GLint64); 286 explicit QueriedState (glw::GLboolean); 287 explicit QueriedState (glw::GLfloat); 288 explicit QueriedState (glw::GLuint); 289 explicit QueriedState (const GLIntVec3&); 290 291 bool isUndefined (void) const; 292 DataType getType (void) const; 293 294 glw::GLint& getIntAccess (void); 295 glw::GLint64& getInt64Access (void); 296 glw::GLboolean& getBoolAccess (void); 297 glw::GLfloat& getFloatAccess (void); 298 glw::GLuint& getUintAccess (void); 299 GLIntVec3& getIntVec3Access (void); 300 301private: 302 DataType m_type; 303 union 304 { 305 glw::GLint vInt; 306 glw::GLint64 vInt64; 307 glw::GLboolean vBool; 308 glw::GLfloat vFloat; 309 glw::GLuint vUint; 310 GLIntVec3 vIntVec3; 311 } m_v; 312}; 313 314// query functions 315 316void queryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, QueriedState& state); 317void queryIndexedState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state); 318void queryAttributeState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state); 319void queryFramebufferState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state); 320void queryProgramState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint program, glw::GLenum pname, QueriedState& state); 321void queryPipelineState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint pipeline, glw::GLenum pname, QueriedState& state); 322void queryTextureParamState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state); 323void queryTextureLevelState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int level, glw::GLenum pname, QueriedState& state); 324 325// verification functions 326 327void verifyBoolean (tcu::ResultCollector& result, QueriedState& state, bool expected); 328void verifyInteger (tcu::ResultCollector& result, QueriedState& state, int expected); 329void verifyIntegerMin (tcu::ResultCollector& result, QueriedState& state, int minValue); 330void verifyIntegerMax (tcu::ResultCollector& result, QueriedState& state, int maxValue); 331void verifyIntegersEqual (tcu::ResultCollector& result, QueriedState& stateA, QueriedState& stateB); 332void verifyFloat (tcu::ResultCollector& result, QueriedState& state, float expected); 333void verifyFloatMin (tcu::ResultCollector& result, QueriedState& state, float minValue); 334void verifyFloatMax (tcu::ResultCollector& result, QueriedState& state, float maxValue); 335void verifyIntegerVec3 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec3& expected); 336 337// Helper functions that both query and verify 338 339void verifyStateBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, bool expected, QueryType type); 340void verifyStateInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int expected, QueryType type); 341void verifyStateIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int minValue, QueryType type); 342void verifyStateIntegerMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int maxValue, QueryType type); 343void verifyStateIntegerEqualToOther (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum other, QueryType type); 344void verifyStateFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float reference, QueryType type); 345void verifyStateFloatMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float minValue, QueryType type); 346void verifyStateFloatMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float maxValue, QueryType type); 347void verifyStateIndexedBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, bool expected, QueryType type); 348void verifyStateIndexedInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type); 349void verifyStateIndexedIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int minValue, QueryType type); 350void verifyStateAttributeInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type); 351void verifyStateFramebufferInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type); 352void verifyStateFramebufferIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int minValue, QueryType type); 353void verifyStateProgramInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, int expected, QueryType type); 354void verifyStateProgramIntegerVec3 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, const tcu::IVec3& expected, QueryType type); 355void verifyStatePipelineInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint pipeline, glw::GLenum pname, int expected, QueryType type); 356void verifyStateTextureParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type); 357 358} // StateQueryUtil 359} // gls 360} // deqp 361 362#endif // _GLSSTATEQUERYUTIL_HPP 363