#ifndef _GLSSTATEQUERYUTIL_HPP #define _GLSSTATEQUERYUTIL_HPP /*------------------------------------------------------------------------- * drawElements Quality Program OpenGL (ES) Module * ----------------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief State Query test utils. *//*--------------------------------------------------------------------*/ #include "tcuDefs.hpp" #include "tcuTestLog.hpp" #include "tcuTestContext.hpp" #include "tcuResultCollector.hpp" #include "glwDefs.hpp" #include "deMath.h" namespace glu { class CallLogWrapper; } // glu namespace deqp { namespace gls { namespace StateQueryUtil { #define GLS_COLLECT_GL_ERROR(RES, ERR, MSG) \ do \ { \ const deUint32 err = (ERR); \ if (err != GL_NO_ERROR) \ (RES).fail(std::string("Got Error ") + glu::getErrorStr(err).toString() + ": " + (MSG)); \ } \ while (deGetFalse()) /*--------------------------------------------------------------------*//*! * \brief Rounds given float to the nearest integer (half up). * * Returns the nearest integer for a float argument. In the case that there * are two nearest integers at the equal distance (aka. the argument is of * form x.5), the integer with the higher value is chosen. (x.5 rounds to x+1) *//*--------------------------------------------------------------------*/ template T roundGLfloatToNearestIntegerHalfUp (float val) { return (T)(deFloatFloor(val + 0.5f)); } /*--------------------------------------------------------------------*//*! * \brief Rounds given float to the nearest integer (half down). * * Returns the nearest integer for a float argument. In the case that there * are two nearest integers at the equal distance (aka. the argument is of * form x.5), the integer with the higher value is chosen. (x.5 rounds to x) *//*--------------------------------------------------------------------*/ template T roundGLfloatToNearestIntegerHalfDown (float val) { return (T)(deFloatCeil(val - 0.5f)); } template class StateQueryMemoryWriteGuard { public: StateQueryMemoryWriteGuard (void); operator T& (void); T* operator & (void); bool isUndefined (void) const; bool isMemoryContaminated (void) const; bool isPreguardContaminated (void) const; bool isPostguardContaminated (void) const; bool verifyValidity (tcu::TestContext& testCtx) const; bool verifyValidity (tcu::ResultCollector& result) const; const T& get (void) const { return m_value; } private: enum { WRITE_GUARD_VALUE = 0xDE }; T m_preguard; T m_value; T m_postguard; // \note guards are not const qualified since the GL implementation might modify them }; template StateQueryMemoryWriteGuard::StateQueryMemoryWriteGuard (void) { DE_STATIC_ASSERT(sizeof(T) * 3 == sizeof(StateQueryMemoryWriteGuard)); // tightly packed deMemset(&m_preguard, WRITE_GUARD_VALUE, sizeof(m_preguard)); deMemset(&m_value, WRITE_GUARD_VALUE, sizeof(m_value)); deMemset(&m_postguard, WRITE_GUARD_VALUE, sizeof(m_postguard)); } template StateQueryMemoryWriteGuard::operator T& (void) { return m_value; } template T* StateQueryMemoryWriteGuard::operator & (void) { return &m_value; } template bool StateQueryMemoryWriteGuard::isUndefined () const { for (size_t i = 0; i < sizeof(T); ++i) if (((deUint8*)&m_value)[i] != (deUint8)WRITE_GUARD_VALUE) return false; return true; } template bool StateQueryMemoryWriteGuard::isMemoryContaminated () const { return isPreguardContaminated() || isPostguardContaminated(); } template bool StateQueryMemoryWriteGuard::isPreguardContaminated (void) const { for (size_t i = 0; i < sizeof(T); ++i) if (((deUint8*)&m_preguard)[i] != (deUint8)WRITE_GUARD_VALUE) return true; return false; } template bool StateQueryMemoryWriteGuard::isPostguardContaminated (void) const { for (size_t i = 0; i < sizeof(T); ++i) if (((deUint8*)&m_postguard)[i] != (deUint8)WRITE_GUARD_VALUE) return true; return false; } template bool StateQueryMemoryWriteGuard::verifyValidity (tcu::TestContext& testCtx) const { using tcu::TestLog; if (isPreguardContaminated()) { testCtx.getLog() << TestLog::Message << "// ERROR: Pre-guard value was modified " << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || testCtx.getTestResult() == QP_TEST_RESULT_LAST) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write"); return false; } else if (isPostguardContaminated()) { testCtx.getLog() << TestLog::Message << "// ERROR: Post-guard value was modified " << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || testCtx.getTestResult() == QP_TEST_RESULT_LAST) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write"); return false; } else if (isUndefined()) { testCtx.getLog() << TestLog::Message << "// ERROR: Get* did not return a value" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS || testCtx.getTestResult() == QP_TEST_RESULT_LAST) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did not return a value"); return false; } return true; } template bool StateQueryMemoryWriteGuard::verifyValidity (tcu::ResultCollector& result) const { using tcu::TestLog; if (isPreguardContaminated()) { result.fail("pre-guard value was modified"); return false; } else if (isPostguardContaminated()) { result.fail("post-guard value was modified"); return false; } else if (isUndefined()) { result.fail("Get* did not return a value"); return false; } return true; } template std::ostream& operator<< (std::ostream& str, const StateQueryMemoryWriteGuard& guard) { return str << guard.get(); } // Verifiers enum QueryType { QUERY_BOOLEAN = 0, QUERY_BOOLEAN_VEC4, QUERY_ISENABLED, QUERY_INTEGER, QUERY_INTEGER64, QUERY_FLOAT, // indexed QUERY_INDEXED_BOOLEAN, QUERY_INDEXED_BOOLEAN_VEC4, QUERY_INDEXED_ISENABLED, QUERY_INDEXED_INTEGER, QUERY_INDEXED_INTEGER_VEC4, QUERY_INDEXED_INTEGER64, QUERY_INDEXED_INTEGER64_VEC4, // attributes QUERY_ATTRIBUTE_INTEGER, QUERY_ATTRIBUTE_FLOAT, QUERY_ATTRIBUTE_PURE_INTEGER, QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER, // fb QUERY_FRAMEBUFFER_INTEGER, // program QUERY_PROGRAM_INTEGER, QUERY_PROGRAM_INTEGER_VEC3, // program pipeline QUERY_PIPELINE_INTEGER, // texture param QUERY_TEXTURE_PARAM_INTEGER, QUERY_TEXTURE_PARAM_FLOAT, QUERY_TEXTURE_PARAM_PURE_INTEGER, QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER, QUERY_TEXTURE_PARAM_INTEGER_VEC4, QUERY_TEXTURE_PARAM_FLOAT_VEC4, QUERY_TEXTURE_PARAM_PURE_INTEGER_VEC4, QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER_VEC4, // texture level QUERY_TEXTURE_LEVEL_INTEGER, QUERY_TEXTURE_LEVEL_FLOAT, // pointer QUERY_POINTER, // object states QUERY_ISTEXTURE, // query queries QUERY_QUERY, // sampler state QUERY_SAMPLER_PARAM_INTEGER, QUERY_SAMPLER_PARAM_FLOAT, QUERY_SAMPLER_PARAM_PURE_INTEGER, QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER, QUERY_SAMPLER_PARAM_INTEGER_VEC4, QUERY_SAMPLER_PARAM_FLOAT_VEC4, QUERY_SAMPLER_PARAM_PURE_INTEGER_VEC4, QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER_VEC4, QUERY_LAST }; enum DataType { DATATYPE_BOOLEAN = 0, DATATYPE_INTEGER, DATATYPE_INTEGER64, DATATYPE_FLOAT16, DATATYPE_FLOAT, DATATYPE_UNSIGNED_INTEGER, DATATYPE_INTEGER_VEC3, DATATYPE_FLOAT_VEC4, DATATYPE_INTEGER_VEC4, DATATYPE_INTEGER64_VEC4, DATATYPE_UNSIGNED_INTEGER_VEC4, DATATYPE_BOOLEAN_VEC4, DATATYPE_POINTER, DATATYPE_LAST }; class QueriedState { public: typedef glw::GLint GLIntVec3[3]; typedef glw::GLint GLIntVec4[4]; typedef glw::GLuint GLUintVec4[4]; typedef glw::GLfloat GLFloatVec4[4]; typedef bool BooleanVec4[4]; typedef glw::GLint64 GLInt64Vec4[4]; QueriedState (void); explicit QueriedState (glw::GLint); explicit QueriedState (glw::GLint64); explicit QueriedState (bool); explicit QueriedState (glw::GLfloat); explicit QueriedState (glw::GLuint); explicit QueriedState (const GLIntVec3&); explicit QueriedState (void*); explicit QueriedState (const GLIntVec4&); explicit QueriedState (const GLUintVec4&); explicit QueriedState (const GLFloatVec4&); explicit QueriedState (const BooleanVec4&); explicit QueriedState (const GLInt64Vec4&); bool isUndefined (void) const; DataType getType (void) const; glw::GLint& getIntAccess (void); glw::GLint64& getInt64Access (void); bool& getBoolAccess (void); glw::GLfloat& getFloatAccess (void); glw::GLuint& getUintAccess (void); GLIntVec3& getIntVec3Access (void); void*& getPtrAccess (void); GLIntVec4& getIntVec4Access (void); GLUintVec4& getUintVec4Access (void); GLFloatVec4& getFloatVec4Access (void); BooleanVec4& getBooleanVec4Access (void); GLInt64Vec4& getInt64Vec4Access (void); private: DataType m_type; union { glw::GLint vInt; glw::GLint64 vInt64; bool vBool; glw::GLfloat vFloat; glw::GLuint vUint; GLIntVec3 vIntVec3; void* vPtr; GLIntVec4 vIntVec4; GLUintVec4 vUintVec4; GLFloatVec4 vFloatVec4; BooleanVec4 vBooleanVec4; GLInt64Vec4 vInt64Vec4; } m_v; }; // query functions void queryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state); void queryIndexedState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state); void queryAttributeState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state); void queryFramebufferState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state); void queryProgramState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint program, glw::GLenum pname, QueriedState& state); void queryPipelineState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint pipeline, glw::GLenum pname, QueriedState& state); void queryTextureParamState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state); void queryTextureLevelState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int level, glw::GLenum pname, QueriedState& state); void queryPointerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state); void queryObjectState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint handle, QueriedState& state); void queryQueryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state); void querySamplerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint sampler, glw::GLenum pname, QueriedState& state); // verification functions void verifyBoolean (tcu::ResultCollector& result, QueriedState& state, bool expected); void verifyInteger (tcu::ResultCollector& result, QueriedState& state, int expected); void verifyIntegerMin (tcu::ResultCollector& result, QueriedState& state, int minValue); void verifyIntegerMax (tcu::ResultCollector& result, QueriedState& state, int maxValue); void verifyIntegersEqual (tcu::ResultCollector& result, QueriedState& stateA, QueriedState& stateB); void verifyFloat (tcu::ResultCollector& result, QueriedState& state, float expected); void verifyFloatMin (tcu::ResultCollector& result, QueriedState& state, float minValue); void verifyFloatMax (tcu::ResultCollector& result, QueriedState& state, float maxValue); void verifyIntegerVec3 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec3& expected); void verifyIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected); void verifyUnsignedIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::UVec4& expected); void verifyFloatVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::Vec4& expected); void verifyBooleanVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::BVec4& expected); void verifyPointer (tcu::ResultCollector& result, QueriedState& state, const void* expected); void verifyNormalizedI32Vec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected); // Helper functions that both query and verify void verifyStateBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, bool expected, QueryType type); void verifyStateInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int expected, QueryType type); void verifyStateIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int minValue, QueryType type); void verifyStateIntegerMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int maxValue, QueryType type); void verifyStateIntegerEqualToOther (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum other, QueryType type); void verifyStateFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float reference, QueryType type); void verifyStateFloatMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float minValue, QueryType type); void verifyStateFloatMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float maxValue, QueryType type); void verifyStatePointer (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, const void* expected, QueryType type); void verifyStateIndexedBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, bool expected, QueryType type); void verifyStateIndexedBooleanVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, const tcu::BVec4& expected, QueryType type); void verifyStateIndexedInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type); void verifyStateIndexedIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int minValue, QueryType type); void verifyStateAttributeInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type); void verifyStateFramebufferInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type); void verifyStateFramebufferIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int minValue, QueryType type); void verifyStateProgramInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, int expected, QueryType type); void verifyStateProgramIntegerVec3 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, const tcu::IVec3& expected, QueryType type); void verifyStatePipelineInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint pipeline, glw::GLenum pname, int expected, QueryType type); void verifyStateTextureParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type); void verifyStateTextureParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, float expected, QueryType type); void verifyStateTextureParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::Vec4& expected, QueryType type); void verifyStateTextureParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type); void verifyStateTextureParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type); void verifyStateTextureParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::UVec4& expected, QueryType type); void verifyStateTextureLevelInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int expected, QueryType type); void verifyStateObjectBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint handle, bool expected, QueryType type); void verifyStateQueryInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type); void verifyStateSamplerParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, int expected, QueryType type); void verifyStateSamplerParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, float expected, QueryType type); void verifyStateSamplerParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::Vec4& expected, QueryType type); void verifyStateSamplerParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type); void verifyStateSamplerParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type); void verifyStateSamplerParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::UVec4& expected, QueryType type); } // StateQueryUtil } // gls } // deqp #endif // _GLSSTATEQUERYUTIL_HPP