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 "deMath.h" 27 #include "tcuDefs.hpp" 28 #include "tcuTestLog.hpp" 29 30 namespace deqp 31 { 32 namespace gls 33 { 34 namespace StateQueryUtil 35 { 36 37 /*--------------------------------------------------------------------*//*! 38 * \brief Rounds given float to the nearest integer (half up). 39 * 40 * Returns the nearest integer for a float argument. In the case that there 41 * are two nearest integers at the equal distance (aka. the argument is of 42 * form x.5), the integer with the higher value is chosen. (x.5 rounds to x+1) 43 *//*--------------------------------------------------------------------*/ 44 template <typename T> 45 T roundGLfloatToNearestIntegerHalfUp (float val) 46 { 47 return (T)(deFloatFloor(val + 0.5f)); 48 } 49 50 /*--------------------------------------------------------------------*//*! 51 * \brief Rounds given float to the nearest integer (half down). 52 * 53 * Returns the nearest integer for a float argument. In the case that there 54 * are two nearest integers at the equal distance (aka. the argument is of 55 * form x.5), the integer with the higher value is chosen. (x.5 rounds to x) 56 *//*--------------------------------------------------------------------*/ 57 template <typename T> 58 T roundGLfloatToNearestIntegerHalfDown (float val) 59 { 60 return (T)(deFloatCeil(val - 0.5f)); 61 } 62 63 template <typename T> 64 class StateQueryMemoryWriteGuard 65 { 66 public: 67 StateQueryMemoryWriteGuard (void); 68 69 operator T& (void); 70 T* operator & (void); 71 72 bool isUndefined (void) const; 73 bool isMemoryContaminated (void) const; 74 bool verifyValidity (tcu::TestContext& testCtx) const; 75 76 const T& get (void) const { return m_value; } 77 78 private: 79 enum 80 { 81 GUARD_VALUE = 0xDEDEADCD 82 }; 83 enum 84 { 85 WRITE_GUARD_VALUE = 0xDE 86 }; 87 88 deInt32 m_preguard; 89 union 90 { 91 T m_value; 92 deUint8 m_isWrittenToGuard[sizeof(T)]; 93 }; 94 deInt32 m_postguard; // \note guards are not const qualified since the GL implementation might modify them 95 }; 96 97 template <typename T> 98 StateQueryMemoryWriteGuard<T>::StateQueryMemoryWriteGuard (void) 99 : m_preguard ((deInt32)(GUARD_VALUE)) 100 , m_postguard ((deInt32)(GUARD_VALUE)) 101 { 102 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(m_isWrittenToGuard); ++i) 103 m_isWrittenToGuard[i] = (deUint8)WRITE_GUARD_VALUE; 104 } 105 106 template <typename T> 107 StateQueryMemoryWriteGuard<T>::operator T& (void) 108 { 109 return m_value; 110 } 111 112 template <typename T> 113 T* StateQueryMemoryWriteGuard<T>::operator & (void) 114 { 115 return &m_value; 116 } 117 118 template <typename T> 119 bool StateQueryMemoryWriteGuard<T>::isUndefined () const 120 { 121 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(m_isWrittenToGuard); ++i) 122 if (m_isWrittenToGuard[i] != (deUint8)WRITE_GUARD_VALUE) 123 return false; 124 return true; 125 } 126 127 template <typename T> 128 bool StateQueryMemoryWriteGuard<T>::isMemoryContaminated () const 129 { 130 return (m_preguard != (deInt32)(GUARD_VALUE)) || (m_postguard != (deInt32)(GUARD_VALUE)); 131 } 132 133 template <typename T> 134 bool StateQueryMemoryWriteGuard<T>::verifyValidity (tcu::TestContext& testCtx) const 135 { 136 using tcu::TestLog; 137 138 if (m_preguard != (deInt32)(GUARD_VALUE)) 139 { 140 testCtx.getLog() << TestLog::Message << "// ERROR: Pre-guard value was modified " << TestLog::EndMessage; 141 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 142 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 143 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write"); 144 145 return false; 146 } 147 else if (m_postguard != (deInt32)(GUARD_VALUE)) 148 { 149 testCtx.getLog() << TestLog::Message << "// ERROR: Post-guard value was modified " << TestLog::EndMessage; 150 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 151 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 152 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write"); 153 154 return false; 155 } 156 else if (isUndefined()) 157 { 158 testCtx.getLog() << TestLog::Message << "// ERROR: Get* did not return a value" << TestLog::EndMessage; 159 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || 160 testCtx.getTestResult() == QP_TEST_RESULT_LAST) 161 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did not return a value"); 162 163 return false; 164 } 165 166 return true; 167 } 168 169 template<typename T> 170 std::ostream& operator<< (std::ostream& str, const StateQueryMemoryWriteGuard<T>& guard) 171 { 172 return str << guard.get(); 173 } 174 175 } // StateQueryUtil 176 } // gls 177 } // deqp 178 179 #endif // _GLSSTATEQUERYUTIL_HPP 180