glsStateQueryUtil.hpp revision 3c827367444ee418f129b2c238299f49d3264554
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 30namespace deqp 31{ 32namespace gls 33{ 34namespace 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 *//*--------------------------------------------------------------------*/ 44template <typename T> 45T 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 *//*--------------------------------------------------------------------*/ 57template <typename T> 58T roundGLfloatToNearestIntegerHalfDown (float val) 59{ 60 return (T)(deFloatCeil(val - 0.5f)); 61} 62 63template <typename T> 64class StateQueryMemoryWriteGuard 65{ 66public: 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 78private: 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 97template <typename T> 98StateQueryMemoryWriteGuard<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 106template <typename T> 107StateQueryMemoryWriteGuard<T>::operator T& (void) 108{ 109 return m_value; 110} 111 112template <typename T> 113T* StateQueryMemoryWriteGuard<T>::operator & (void) 114{ 115 return &m_value; 116} 117 118template <typename T> 119bool 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 127template <typename T> 128bool StateQueryMemoryWriteGuard<T>::isMemoryContaminated () const 129{ 130 return (m_preguard != (deInt32)(GUARD_VALUE)) || (m_postguard != (deInt32)(GUARD_VALUE)); 131} 132 133template <typename T> 134bool 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 169template<typename T> 170std::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