/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 3.0 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 tests. *//*--------------------------------------------------------------------*/ #include "es3fIntegerStateQueryTests.hpp" #include "es3fApiCase.hpp" #include "glsStateQueryUtil.hpp" #include "gluRenderContext.hpp" #include "gluContextInfo.hpp" #include "gluStrUtil.hpp" #include "tcuRenderTarget.hpp" #include "deRandom.hpp" #include "glwEnums.hpp" using namespace glw; // GLint and other GL types using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard; #ifndef GL_SLUMINANCE_NV #define GL_SLUMINANCE_NV 0x8C46 #endif #ifndef GL_SLUMINANCE_ALPHA_NV #define GL_SLUMINANCE_ALPHA_NV 0x8C44 #endif #ifndef GL_BGR_NV #define GL_BGR_NV 0x80E0 #endif namespace deqp { namespace gles3 { namespace Functional { namespace IntegerStateQueryVerifiers { // StateVerifier class StateVerifier : protected glu::CallLogWrapper { public: StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix); virtual ~StateVerifier (); // make GCC happy const char* getTestNamePostfix (void) const; virtual void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference) = DE_NULL; virtual void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3) = DE_NULL; virtual void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3) = DE_NULL; virtual void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) = DE_NULL; virtual void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference) = DE_NULL; virtual void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) = DE_NULL; virtual void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1) = DE_NULL; virtual void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength) = DE_NULL; virtual void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits) = DE_NULL; private: const char* const m_testNamePostfix; }; StateVerifier::StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix) : glu::CallLogWrapper (gl, log) , m_testNamePostfix (testNamePostfix) { enableLogging(true); } StateVerifier::~StateVerifier () { } const char* StateVerifier::getTestNamePostfix (void) const { return m_testNamePostfix; } // GetBooleanVerifier class GetBooleanVerifier : public StateVerifier { public: GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log); void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3); void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3); void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference); void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1); void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength); void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits); }; GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log) : StateVerifier(gl, log, "_getboolean") { } void GetBooleanVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLboolean> state; glGetBooleanv(name, &state); if (!state.verifyValidity(testCtx)) return; const GLboolean expectedGLState = reference ? GL_TRUE : GL_FALSE; if (state != expectedGLState) { testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (expectedGLState==GL_TRUE ? "GL_TRUE" : "GL_FALSE") << "; got " << (state == GL_TRUE ? "GL_TRUE" : (state == GL_FALSE ? "GL_FALSE" : "non-boolean")) << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } void GetBooleanVerifier::verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3) { verifyInteger4Mask(testCtx, name, reference0, true, reference1, true, reference2, true, reference3, true); } void GetBooleanVerifier::verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLboolean[4]> boolVector4; glGetBooleanv(name, boolVector4); if (!boolVector4.verifyValidity(testCtx)) return; const GLboolean referenceAsGLBoolean[] = { reference0 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE, reference1 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE, reference2 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE, reference3 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE, }; if ((enableRef0 && (boolVector4[0] != referenceAsGLBoolean[0])) || (enableRef1 && (boolVector4[1] != referenceAsGLBoolean[1])) || (enableRef2 && (boolVector4[2] != referenceAsGLBoolean[2])) || (enableRef3 && (boolVector4[3] != referenceAsGLBoolean[3]))) { testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (enableRef0 ? (referenceAsGLBoolean[0] ? "GL_TRUE" : "GL_FALSE") : " - ") << ", " << (enableRef1 ? (referenceAsGLBoolean[1] ? "GL_TRUE" : "GL_FALSE") : " - ") << ", " << (enableRef2 ? (referenceAsGLBoolean[2] ? "GL_TRUE" : "GL_FALSE") : " - ") << ", " << (enableRef3 ? (referenceAsGLBoolean[3] ? "GL_TRUE" : "GL_FALSE") : " - ") << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } void GetBooleanVerifier::verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLboolean> state; glGetBooleanv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state == GL_TRUE) // state is non-zero, could be greater than reference (correct) return; if (state == GL_FALSE) // state is zero { if (reference > 0) // and reference is greater than zero? { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } else { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } void GetBooleanVerifier::verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLboolean> state; glGetBooleanv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state == GL_TRUE) // state is non-zero, could be greater than reference (correct) return; if (state == GL_FALSE) // state is zero { if (reference > 0) // and reference is greater than zero? { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } else { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } void GetBooleanVerifier::verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLboolean> state; glGetBooleanv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state == GL_TRUE) // state is non-zero, could be less than reference (correct) return; if (state == GL_FALSE) // state is zero { if (reference < 0) // and reference is less than zero? { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } else { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } void GetBooleanVerifier::verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLboolean[2]> boolVector; glGetBooleanv(name, boolVector); if (!boolVector.verifyValidity(testCtx)) return; const GLboolean referenceAsGLBoolean[2] = { reference0 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE, reference1 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(referenceAsGLBoolean); ++ndx) { if (boolVector[ndx] == GL_TRUE) // state is non-zero, could be greater than any integer { continue; } else if (boolVector[ndx] == GL_FALSE) // state is zero { if (referenceAsGLBoolean[ndx] > 0) // and reference is greater than zero? { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } else { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } } void GetBooleanVerifier::verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLboolean> state; glGetBooleanv(name, &state); if (!state.verifyValidity(testCtx)) return; for (size_t ndx = 0; ndx < referencesLength; ++ndx) { const GLboolean expectedGLState = references[ndx] ? GL_TRUE : GL_FALSE; if (state == expectedGLState) return; } testCtx.getLog() << TestLog::Message << "// ERROR: got " << (state==GL_TRUE ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } void GetBooleanVerifier::verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits) { // if stencilBits == 0, the mask is allowed to be either GL_TRUE or GL_FALSE // otherwise it must be GL_TRUE using tcu::TestLog; StateQueryMemoryWriteGuard<GLboolean> state; glGetBooleanv(name, &state); if (!state.verifyValidity(testCtx)) return; if (stencilBits > 0 && state != GL_TRUE) { testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value"); } } //GetIntegerVerifier class GetIntegerVerifier : public StateVerifier { public: GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log); void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3); void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3); void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference); void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1); void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength); void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits); }; GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log) : StateVerifier(gl, log, "_getinteger") { } void GetIntegerVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint> state; glGetIntegerv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state != reference) { testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetIntegerVerifier::verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3) { verifyInteger4Mask(testCtx, name, reference0, true, reference1, true, reference2, true, reference3, true); } void GetIntegerVerifier::verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint[4]> intVector4; glGetIntegerv(name, intVector4); if (!intVector4.verifyValidity(testCtx)) return; if ((enableRef0 && (intVector4[0] != reference0)) || (enableRef1 && (intVector4[1] != reference1)) || (enableRef2 && (intVector4[2] != reference2)) || (enableRef3 && (intVector4[3] != reference3))) { testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (enableRef0?"":"(") << reference0 << (enableRef0?"":")") << ", " << (enableRef1?"":"(") << reference1 << (enableRef1?"":")") << ", " << (enableRef2?"":"(") << reference2 << (enableRef2?"":")") << ", " << (enableRef3?"":"(") << reference3 << (enableRef3?"":")") << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetIntegerVerifier::verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint> state; glGetIntegerv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state < reference) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetIntegerVerifier::verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint> state; glGetIntegerv(name, &state); if (!state.verifyValidity(testCtx)) return; if (GLuint(state) < reference) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference << "; got " << GLuint(state) << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetIntegerVerifier::verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint> state; glGetIntegerv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state > reference) { testCtx.getLog() << TestLog::Message << "// ERROR: expected less or equal to " << reference << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetIntegerVerifier::verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint[2]> intVector2; glGetIntegerv(name, intVector2); if (!intVector2.verifyValidity(testCtx)) return; if (intVector2[0] < reference0 || intVector2[1] < reference1) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference0 << ", " << reference1 << "; got " << intVector2[0] << ", " << intVector2[0] << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetIntegerVerifier::verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint> state; glGetIntegerv(name, &state); if (!state.verifyValidity(testCtx)) return; for (size_t ndx = 0; ndx < referencesLength; ++ndx) { const GLint expectedGLState = references[ndx]; if (state == expectedGLState) return; } testCtx.getLog() << TestLog::Message << "// ERROR: got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } void GetIntegerVerifier::verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint> state; glGetIntegerv(name, &state); if (!state.verifyValidity(testCtx)) return; const GLint reference = (1 << stencilBits) - 1; if ((state & reference) != reference) // the least significant stencilBits bits should be on { testCtx.getLog() << TestLog::Message << "// ERROR: expected minimum mask of " << reference << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid mask value"); } } //GetInteger64Verifier class GetInteger64Verifier : public StateVerifier { public: GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log); void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3); void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3); void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference); void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1); void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength); void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits); }; GetInteger64Verifier::GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log) : StateVerifier(gl, log, "_getinteger64") { } void GetInteger64Verifier::verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint64> state; glGetInteger64v(name, &state); if (!state.verifyValidity(testCtx)) return; if (state != GLint64(reference)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetInteger64Verifier::verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3) { verifyInteger4Mask(testCtx, name, reference0, true, reference1, true, reference2, true, reference3, true); } void GetInteger64Verifier::verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint64[4]> intVector4; glGetInteger64v(name, intVector4); if (!intVector4.verifyValidity(testCtx)) return; if ((enableRef0 && (intVector4[0] != GLint64(reference0))) || (enableRef1 && (intVector4[1] != GLint64(reference1))) || (enableRef2 && (intVector4[2] != GLint64(reference2))) || (enableRef3 && (intVector4[3] != GLint64(reference3)))) { testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (enableRef0?"":"(") << reference0 << (enableRef0?"":")") << ", " << (enableRef1?"":"(") << reference1 << (enableRef1?"":")") << ", " << (enableRef2?"":"(") << reference2 << (enableRef2?"":")") << ", " << (enableRef3?"":"(") << reference3 << (enableRef3?"":")") << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetInteger64Verifier::verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint64> state; glGetInteger64v(name, &state); if (!state.verifyValidity(testCtx)) return; if (state < GLint64(reference)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLint64(reference) << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetInteger64Verifier::verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint64> state; glGetInteger64v(name, &state); if (!state.verifyValidity(testCtx)) return; if (GLuint(state) < GLint64(reference)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLint64(reference) << "; got " << GLuint(state) << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetInteger64Verifier::verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint64> state; glGetInteger64v(name, &state); if (!state.verifyValidity(testCtx)) return; if (state > GLint64(reference)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected less or equal to " << GLint64(reference) << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetInteger64Verifier::verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint64[2]> intVector2; glGetInteger64v(name, intVector2); if (!intVector2.verifyValidity(testCtx)) return; if (intVector2[0] < GLint64(reference0) || intVector2[1] < GLint64(reference1)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLint64(reference0) << ", " << GLint64(reference1) << "; got " << intVector2[0] << ", " << intVector2[1] << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } } void GetInteger64Verifier::verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint64> state; glGetInteger64v(name, &state); if (!state.verifyValidity(testCtx)) return; for (size_t ndx = 0; ndx < referencesLength; ++ndx) { const GLint64 expectedGLState = GLint64(references[ndx]); if (state == expectedGLState) return; } testCtx.getLog() << TestLog::Message << "// ERROR: got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value"); } void GetInteger64Verifier::verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLint64> state; glGetInteger64v(name, &state); if (!state.verifyValidity(testCtx)) return; const GLint64 reference = (1ULL << stencilBits) - 1; if ((state & reference) != reference) // the least significant stencilBits bits should be on { testCtx.getLog() << TestLog::Message << "// ERROR: expected mimimum mask of " << reference << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid mask value"); } } //GetFloatVerifier class GetFloatVerifier : public StateVerifier { public: GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log); void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3); void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3); void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference); void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference); void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1); void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength); void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits); }; GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log) : StateVerifier(gl, log, "_getfloat") { } void GetFloatVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; const GLfloat referenceAsFloat = GLfloat(reference); DE_ASSERT(reference == GLint(referenceAsFloat)); // reference integer must have 1:1 mapping to float for this to work. Reference value is always such value in these tests StateQueryMemoryWriteGuard<GLfloat> state; glGetFloatv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state != referenceAsFloat) { testCtx.getLog() << TestLog::Message << "// ERROR: expected " << referenceAsFloat << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value"); } } void GetFloatVerifier::verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3) { verifyInteger4Mask(testCtx, name, reference0, true, reference1, true, reference2, true, reference3, true); } void GetFloatVerifier::verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLfloat[4]> floatVector4; glGetFloatv(name, floatVector4); if (!floatVector4.verifyValidity(testCtx)) return; if ((enableRef0 && (floatVector4[0] != GLfloat(reference0))) || (enableRef1 && (floatVector4[1] != GLfloat(reference1))) || (enableRef2 && (floatVector4[2] != GLfloat(reference2))) || (enableRef3 && (floatVector4[3] != GLfloat(reference3)))) { testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (enableRef0?"":"(") << GLfloat(reference0) << (enableRef0?"":")") << ", " << (enableRef1?"":"(") << GLfloat(reference1) << (enableRef1?"":")") << ", " << (enableRef2?"":"(") << GLfloat(reference2) << (enableRef2?"":")") << ", " << (enableRef3?"":"(") << GLfloat(reference3) << (enableRef3?"":")") << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value"); } } void GetFloatVerifier::verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLfloat> state; glGetFloatv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state < GLfloat(reference)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLfloat(reference) << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value"); } } void GetFloatVerifier::verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLfloat> state; glGetFloatv(name, &state); if (!state.verifyValidity(testCtx)) return; if (GLuint(state) < GLfloat(reference)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLfloat(reference) << "; got " << GLuint(state) << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value"); } } void GetFloatVerifier::verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLfloat> state; glGetFloatv(name, &state); if (!state.verifyValidity(testCtx)) return; if (state > GLfloat(reference)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected less or equal to " << GLfloat(reference) << "; got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value"); } } void GetFloatVerifier::verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLfloat[2]> floatVector2; glGetFloatv(name, floatVector2); if (!floatVector2.verifyValidity(testCtx)) return; if (floatVector2[0] < GLfloat(reference0) || floatVector2[1] < GLfloat(reference1)) { testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLfloat(reference0) << ", " << GLfloat(reference1) << "; got " << floatVector2[0] << ", " << floatVector2[1] << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value"); } } void GetFloatVerifier::verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength) { using tcu::TestLog; StateQueryMemoryWriteGuard<GLfloat> state; glGetFloatv(name, &state); if (!state.verifyValidity(testCtx)) return; for (size_t ndx = 0; ndx < referencesLength; ++ndx) { const GLfloat expectedGLState = GLfloat(references[ndx]); DE_ASSERT(references[ndx] == GLint(expectedGLState)); // reference integer must have 1:1 mapping to float for this to work. Reference value is always such value in these tests if (state == expectedGLState) return; } testCtx.getLog() << TestLog::Message << "// ERROR: got " << state << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value"); } void GetFloatVerifier::verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits) { // checking the mask bits with float doesn't make much sense because of conversion errors // just verify that the value is greater or equal to the minimum value const GLint reference = (1 << stencilBits) - 1; verifyIntegerGreaterOrEqual(testCtx, name, reference); } } // IntegerStateQueryVerifiers namespace { using namespace IntegerStateQueryVerifiers; using namespace deqp::gls::StateQueryUtil; class ConstantMinimumValueTestCase : public ApiCase { public: ConstantMinimumValueTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName, GLint minValue) : ApiCase (context, name, description) , m_targetName (targetName) , m_minValue (minValue) , m_verifier (verifier) { } void test (void) { m_verifier->verifyUnsignedIntegerGreaterOrEqual(m_testCtx, m_targetName, m_minValue); expectError(GL_NO_ERROR); } private: GLenum m_targetName; GLint m_minValue; StateVerifier* m_verifier; }; class ConstantMaximumValueTestCase : public ApiCase { public: ConstantMaximumValueTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName, GLint minValue) : ApiCase (context, name, description) , m_targetName (targetName) , m_minValue (minValue) , m_verifier (verifier) { } void test (void) { m_verifier->verifyIntegerLessOrEqual(m_testCtx, m_targetName, m_minValue); expectError(GL_NO_ERROR); } private: GLenum m_targetName; GLint m_minValue; StateVerifier* m_verifier; }; class SampleBuffersTestCase : public ApiCase { public: SampleBuffersTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { const int expectedSampleBuffers = (m_context.getRenderTarget().getNumSamples() > 1) ? 1 : 0; m_log << tcu::TestLog::Message << "Sample count is " << (m_context.getRenderTarget().getNumSamples()) << ", expecting GL_SAMPLE_BUFFERS to be " << expectedSampleBuffers << tcu::TestLog::EndMessage; m_verifier->verifyInteger(m_testCtx, GL_SAMPLE_BUFFERS, expectedSampleBuffers); expectError(GL_NO_ERROR); } private: StateVerifier* m_verifier; }; class SamplesTestCase : public ApiCase { public: SamplesTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { // MSAA? if (m_context.getRenderTarget().getNumSamples() > 1) { m_log << tcu::TestLog::Message << "Sample count is " << (m_context.getRenderTarget().getNumSamples()) << tcu::TestLog::EndMessage; m_verifier->verifyInteger(m_testCtx, GL_SAMPLES, m_context.getRenderTarget().getNumSamples()); expectError(GL_NO_ERROR); } else { const glw::GLint validSamples[] = {0, 1}; m_log << tcu::TestLog::Message << "Expecting GL_SAMPLES to be 0 or 1" << tcu::TestLog::EndMessage; m_verifier->verifyIntegerAnyOf(m_testCtx, GL_SAMPLES, validSamples, DE_LENGTH_OF_ARRAY(validSamples)); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class HintTestCase : public ApiCase { public: HintTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName) : ApiCase (context, name, description) , m_targetName (targetName) , m_verifier (verifier) { } void test (void) { m_verifier->verifyInteger(m_testCtx, m_targetName, GL_DONT_CARE); expectError(GL_NO_ERROR); glHint(m_targetName, GL_NICEST); m_verifier->verifyInteger(m_testCtx, m_targetName, GL_NICEST); expectError(GL_NO_ERROR); glHint(m_targetName, GL_FASTEST); m_verifier->verifyInteger(m_testCtx, m_targetName, GL_FASTEST); expectError(GL_NO_ERROR); glHint(m_targetName, GL_DONT_CARE); m_verifier->verifyInteger(m_testCtx, m_targetName, GL_DONT_CARE); expectError(GL_NO_ERROR); } private: GLenum m_targetName; StateVerifier* m_verifier; }; class DepthFuncTestCase : public ApiCase { public: DepthFuncTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { m_verifier->verifyInteger(m_testCtx, GL_DEPTH_FUNC, GL_LESS); expectError(GL_NO_ERROR); const GLenum depthFunctions[] = {GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GREATER, GL_GEQUAL, GL_NOTEQUAL}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthFunctions); ndx++) { glDepthFunc(depthFunctions[ndx]); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_DEPTH_FUNC, depthFunctions[ndx]); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class CullFaceTestCase : public ApiCase { public: CullFaceTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { m_verifier->verifyInteger(m_testCtx, GL_CULL_FACE_MODE, GL_BACK); expectError(GL_NO_ERROR); const GLenum cullFaces[] = {GL_FRONT, GL_BACK, GL_FRONT_AND_BACK}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cullFaces); ndx++) { glCullFace(cullFaces[ndx]); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_CULL_FACE_MODE, cullFaces[ndx]); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class FrontFaceTestCase : public ApiCase { public: FrontFaceTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { m_verifier->verifyInteger(m_testCtx, GL_FRONT_FACE, GL_CCW); expectError(GL_NO_ERROR); const GLenum frontFaces[] = {GL_CW, GL_CCW}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(frontFaces); ndx++) { glFrontFace(frontFaces[ndx]); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_FRONT_FACE, frontFaces[ndx]); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class ViewPortTestCase : public ApiCase { public: ViewPortTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { de::Random rnd(0xabcdef); GLint maxViewportDimensions[2] = {0}; glGetIntegerv(GL_MAX_VIEWPORT_DIMS, maxViewportDimensions); // verify initial value of first two values m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, 0, 0, m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight()); expectError(GL_NO_ERROR); const int numIterations = 120; for (int i = 0; i < numIterations; ++i) { GLint x = rnd.getInt(-64000, 64000); GLint y = rnd.getInt(-64000, 64000); GLsizei width = rnd.getInt(0, maxViewportDimensions[0]); GLsizei height = rnd.getInt(0, maxViewportDimensions[1]); glViewport(x, y, width, height); m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, x, y, width, height); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class ScissorBoxTestCase : public ApiCase { public: ScissorBoxTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { de::Random rnd(0xabcdef); // verify initial value of first two values m_verifier->verifyInteger4Mask(m_testCtx, GL_SCISSOR_BOX, 0, true, 0, true, 0, false, 0, false); expectError(GL_NO_ERROR); const int numIterations = 120; for (int i = 0; i < numIterations; ++i) { GLint left = rnd.getInt(-64000, 64000); GLint bottom = rnd.getInt(-64000, 64000); GLsizei width = rnd.getInt(0, 64000); GLsizei height = rnd.getInt(0, 64000); glScissor(left, bottom, width, height); m_verifier->verifyInteger4(m_testCtx, GL_SCISSOR_BOX, left, bottom, width, height); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class MaxViewportDimsTestCase : public ApiCase { public: MaxViewportDimsTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { m_verifier->verifyIntegerGreaterOrEqual2(m_testCtx, GL_MAX_VIEWPORT_DIMS, m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight()); expectError(GL_NO_ERROR); } private: StateVerifier* m_verifier; }; class StencilRefTestCase : public ApiCase { public: StencilRefTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) { } void test (void) { m_verifier->verifyInteger(m_testCtx, m_testTargetName, 0); expectError(GL_NO_ERROR); const int stencilBits = m_context.getRenderTarget().getStencilBits(); for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit) { const int ref = 1 << stencilBit; glStencilFunc(GL_ALWAYS, ref, 0); // mask should not affect the REF expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, ref); expectError(GL_NO_ERROR); glStencilFunc(GL_ALWAYS, ref, ref); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, ref); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; }; class StencilRefSeparateTestCase : public ApiCase { public: StencilRefSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, GLenum stencilFuncTargetFace) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) , m_stencilFuncTargetFace (stencilFuncTargetFace) { } void test (void) { m_verifier->verifyInteger(m_testCtx, m_testTargetName, 0); expectError(GL_NO_ERROR); const int stencilBits = m_context.getRenderTarget().getStencilBits(); for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit) { const int ref = 1 << stencilBit; glStencilFuncSeparate(m_stencilFuncTargetFace, GL_ALWAYS, ref, 0); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, ref); expectError(GL_NO_ERROR); glStencilFuncSeparate(m_stencilFuncTargetFace, GL_ALWAYS, ref, ref); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, ref); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; GLenum m_stencilFuncTargetFace; }; class StencilOpTestCase : public ApiCase { public: StencilOpTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum stencilOpName) : ApiCase (context, name, description) , m_verifier (verifier) , m_stencilOpName (stencilOpName) { } void test (void) { m_verifier->verifyInteger(m_testCtx, m_stencilOpName, GL_KEEP); expectError(GL_NO_ERROR); const GLenum stencilOpValues[] = {GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilOpValues); ++ndx) { SetStencilOp(stencilOpValues[ndx]); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_stencilOpName, stencilOpValues[ndx]); expectError(GL_NO_ERROR); } } protected: virtual void SetStencilOp (GLenum stencilOpValue) { switch (m_stencilOpName) { case GL_STENCIL_FAIL: case GL_STENCIL_BACK_FAIL: glStencilOp(stencilOpValue, GL_KEEP, GL_KEEP); break; case GL_STENCIL_PASS_DEPTH_FAIL: case GL_STENCIL_BACK_PASS_DEPTH_FAIL: glStencilOp(GL_KEEP, stencilOpValue, GL_KEEP); break; case GL_STENCIL_PASS_DEPTH_PASS: case GL_STENCIL_BACK_PASS_DEPTH_PASS: glStencilOp(GL_KEEP, GL_KEEP, stencilOpValue); break; default: DE_ASSERT(false && "should not happen"); break; } } StateVerifier* m_verifier; GLenum m_stencilOpName; }; class StencilOpSeparateTestCase : public StencilOpTestCase { public: StencilOpSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum stencilOpName, GLenum stencilOpFace) : StencilOpTestCase (context, verifier, name, description, stencilOpName) , m_stencilOpFace (stencilOpFace) { } private: void SetStencilOp (GLenum stencilOpValue) { switch (m_stencilOpName) { case GL_STENCIL_FAIL: case GL_STENCIL_BACK_FAIL: glStencilOpSeparate(m_stencilOpFace, stencilOpValue, GL_KEEP, GL_KEEP); break; case GL_STENCIL_PASS_DEPTH_FAIL: case GL_STENCIL_BACK_PASS_DEPTH_FAIL: glStencilOpSeparate(m_stencilOpFace, GL_KEEP, stencilOpValue, GL_KEEP); break; case GL_STENCIL_PASS_DEPTH_PASS: case GL_STENCIL_BACK_PASS_DEPTH_PASS: glStencilOpSeparate(m_stencilOpFace, GL_KEEP, GL_KEEP, stencilOpValue); break; default: DE_ASSERT(false && "should not happen"); break; } } GLenum m_stencilOpFace; }; class StencilFuncTestCase : public ApiCase { public: StencilFuncTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { m_verifier->verifyInteger(m_testCtx, GL_STENCIL_FUNC, GL_ALWAYS); expectError(GL_NO_ERROR); const GLenum stencilfuncValues[] = {GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilfuncValues); ++ndx) { glStencilFunc(stencilfuncValues[ndx], 0, 0); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_STENCIL_FUNC, stencilfuncValues[ndx]); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_STENCIL_BACK_FUNC, stencilfuncValues[ndx]); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class StencilFuncSeparateTestCase : public ApiCase { public: StencilFuncSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum stencilFuncName, GLenum stencilFuncFace) : ApiCase (context, name, description) , m_verifier (verifier) , m_stencilFuncName (stencilFuncName) , m_stencilFuncFace (stencilFuncFace) { } void test (void) { m_verifier->verifyInteger(m_testCtx, m_stencilFuncName, GL_ALWAYS); expectError(GL_NO_ERROR); const GLenum stencilfuncValues[] = {GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilfuncValues); ++ndx) { glStencilFuncSeparate(m_stencilFuncFace, stencilfuncValues[ndx], 0, 0); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_stencilFuncName, stencilfuncValues[ndx]); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_stencilFuncName; GLenum m_stencilFuncFace; }; class StencilMaskTestCase : public ApiCase { public: StencilMaskTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) { } void test (void) { const int stencilBits = m_context.getRenderTarget().getStencilBits(); m_verifier->verifyStencilMaskInitial(m_testCtx, m_testTargetName, stencilBits); expectError(GL_NO_ERROR); for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit) { const int mask = 1 << stencilBit; glStencilFunc(GL_ALWAYS, 0, mask); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, mask); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; }; class StencilMaskSeparateTestCase : public ApiCase { public: StencilMaskSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, GLenum stencilFuncTargetFace) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) , m_stencilFuncTargetFace (stencilFuncTargetFace) { } void test (void) { const int stencilBits = m_context.getRenderTarget().getStencilBits(); m_verifier->verifyStencilMaskInitial(m_testCtx, m_testTargetName, stencilBits); expectError(GL_NO_ERROR); for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit) { const int mask = 1 << stencilBit; glStencilFuncSeparate(m_stencilFuncTargetFace, GL_ALWAYS, 0, mask); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, mask); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; GLenum m_stencilFuncTargetFace; }; class StencilWriteMaskTestCase : public ApiCase { public: StencilWriteMaskTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) { } void test (void) { const int stencilBits = m_context.getRenderTarget().getStencilBits(); for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit) { const int mask = 1 << stencilBit; glStencilMask(mask); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, mask); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; }; class StencilWriteMaskSeparateTestCase : public ApiCase { public: StencilWriteMaskSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, GLenum stencilTargetFace) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) , m_stencilTargetFace (stencilTargetFace) { } void test (void) { const int stencilBits = m_context.getRenderTarget().getStencilBits(); for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit) { const int mask = 1 << stencilBit; glStencilMaskSeparate(m_stencilTargetFace, mask); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, mask); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; GLenum m_stencilTargetFace; }; class PixelStoreTestCase : public ApiCase { public: PixelStoreTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) , m_initialValue (initialValue) { } void test (void) { de::Random rnd(0xabcdef); m_verifier->verifyInteger(m_testCtx, m_testTargetName, m_initialValue); expectError(GL_NO_ERROR); const int numIterations = 120; for (int i = 0; i < numIterations; ++i) { const int referenceValue = rnd.getInt(0, 64000); glPixelStorei(m_testTargetName, referenceValue); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, referenceValue); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; int m_initialValue; }; class PixelStoreAlignTestCase : public ApiCase { public: PixelStoreAlignTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) { } void test (void) { m_verifier->verifyInteger(m_testCtx, m_testTargetName, 4); expectError(GL_NO_ERROR); const int alignments[] = {1, 2, 4, 8}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(alignments); ++ndx) { const int referenceValue = alignments[ndx]; glPixelStorei(m_testTargetName, referenceValue); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, referenceValue); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; }; class BlendFuncTestCase : public ApiCase { public: BlendFuncTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) , m_initialValue (initialValue) { } void test (void) { m_verifier->verifyInteger(m_testCtx, m_testTargetName, m_initialValue); expectError(GL_NO_ERROR); const GLenum blendFuncValues[] = { GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(blendFuncValues); ++ndx) { const GLenum referenceValue = blendFuncValues[ndx]; SetBlendFunc(referenceValue); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, referenceValue); expectError(GL_NO_ERROR); } } protected: virtual void SetBlendFunc (GLenum func) { switch (m_testTargetName) { case GL_BLEND_SRC_RGB: case GL_BLEND_SRC_ALPHA: glBlendFunc(func, GL_ZERO); break; case GL_BLEND_DST_RGB: case GL_BLEND_DST_ALPHA: glBlendFunc(GL_ZERO, func); break; default: DE_ASSERT(false && "should not happen"); break; } } StateVerifier* m_verifier; GLenum m_testTargetName; int m_initialValue; }; class BlendFuncSeparateTestCase : public BlendFuncTestCase { public: BlendFuncSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue) : BlendFuncTestCase (context, verifier, name, description, testTargetName, initialValue) { } void SetBlendFunc (GLenum func) { switch (m_testTargetName) { case GL_BLEND_SRC_RGB: glBlendFuncSeparate(func, GL_ZERO, GL_ZERO, GL_ZERO); break; case GL_BLEND_DST_RGB: glBlendFuncSeparate(GL_ZERO, func, GL_ZERO, GL_ZERO); break; case GL_BLEND_SRC_ALPHA: glBlendFuncSeparate(GL_ZERO, GL_ZERO, func, GL_ZERO); break; case GL_BLEND_DST_ALPHA: glBlendFuncSeparate(GL_ZERO, GL_ZERO, GL_ZERO, func); break; default: DE_ASSERT(false && "should not happen"); break; } } }; class BlendEquationTestCase : public ApiCase { public: BlendEquationTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) , m_initialValue (initialValue) { } void test (void) { m_verifier->verifyInteger(m_testCtx, m_testTargetName, m_initialValue); expectError(GL_NO_ERROR); const GLenum blendFuncValues[] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(blendFuncValues); ++ndx) { const GLenum referenceValue = blendFuncValues[ndx]; SetBlendEquation(referenceValue); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, m_testTargetName, referenceValue); expectError(GL_NO_ERROR); } } protected: virtual void SetBlendEquation (GLenum equation) { glBlendEquation(equation); } StateVerifier* m_verifier; GLenum m_testTargetName; int m_initialValue; }; class BlendEquationSeparateTestCase : public BlendEquationTestCase { public: BlendEquationSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue) : BlendEquationTestCase (context, verifier, name, description, testTargetName, initialValue) { } protected: void SetBlendEquation (GLenum equation) { switch (m_testTargetName) { case GL_BLEND_EQUATION_RGB: glBlendEquationSeparate(equation, GL_FUNC_ADD); break; case GL_BLEND_EQUATION_ALPHA: glBlendEquationSeparate(GL_FUNC_ADD, equation); break; default: DE_ASSERT(false && "should not happen"); break; } } }; class ImplementationArrayTestCase : public ApiCase { public: ImplementationArrayTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, GLenum testTargetLengthTargetName, int minValue) : ApiCase (context, name, description) , m_verifier (verifier) , m_testTargetName (testTargetName) , m_testTargetLengthTargetName (testTargetLengthTargetName) , m_minValue (minValue) { } void test (void) { m_verifier->verifyIntegerGreaterOrEqual(m_testCtx, m_testTargetLengthTargetName, m_minValue); expectError(GL_NO_ERROR); GLint targetArrayLength = 0; glGetIntegerv(m_testTargetLengthTargetName, &targetArrayLength); expectError(GL_NO_ERROR); if (targetArrayLength) { std::vector<GLint> queryResult; queryResult.resize(targetArrayLength, 0); glGetIntegerv(m_testTargetName, &queryResult[0]); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; GLenum m_testTargetName; GLenum m_testTargetLengthTargetName; int m_minValue; }; class BindingTest : public TestCase { public: BindingTest (Context& context, const char* name, const char* desc, QueryType type); IterateResult iterate (void); virtual void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const = 0; protected: const QueryType m_type; }; BindingTest::BindingTest (Context& context, const char* name, const char* desc, QueryType type) : TestCase (context, name, desc) , m_type (type) { } BindingTest::IterateResult BindingTest::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog()); tcu::ResultCollector result (m_context.getTestContext().getLog(), " // ERROR: "); gl.enableLogging(true); test(gl, result); result.setTestContextResult(m_testCtx); return STOP; } class TransformFeedbackBindingTestCase : public BindingTest { public: TransformFeedbackBindingTestCase (Context& context, QueryType type, const char* name) : BindingTest(context, name, "GL_TRANSFORM_FEEDBACK_BINDING", type) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { static const char* transformFeedbackTestVertSource = "#version 300 es\n" "void main (void)\n" "{\n" " gl_Position = vec4(0.0);\n" "}\n\0"; static const char* transformFeedbackTestFragSource = "#version 300 es\n" "layout(location = 0) out mediump vec4 fragColor;" "void main (void)\n" "{\n" " fragColor = vec4(0.0);\n" "}\n\0"; GLuint shaderVert; GLuint shaderFrag; GLuint shaderProg; GLuint transformfeedback = 0; GLuint feedbackBufferId = 0; { const tcu::ScopedLogSection section(gl.getLog(), "Initial", "Initial"); verifyStateInteger(result, gl, GL_TRANSFORM_FEEDBACK_BINDING, 0, m_type); } gl.glGenTransformFeedbacks(1, &transformfeedback); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenTransformFeedbacks"); { const tcu::ScopedLogSection section(gl.getLog(), "VertexShader", "Vertex Shader"); GLint compileStatus = -1; shaderVert = gl.glCreateShader(GL_VERTEX_SHADER); gl.glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL); gl.glCompileShader(shaderVert); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glCompileShader"); gl.glGetShaderiv(shaderVert, GL_COMPILE_STATUS, &compileStatus); if (compileStatus != GL_TRUE) result.fail("expected GL_TRUE"); } { const tcu::ScopedLogSection section(gl.getLog(), "FragmentShader", "Fragment Shader"); GLint compileStatus = -1; shaderFrag = gl.glCreateShader(GL_FRAGMENT_SHADER); gl.glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL); gl.glCompileShader(shaderFrag); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glCompileShader"); gl.glGetShaderiv(shaderFrag, GL_COMPILE_STATUS, &compileStatus); if (compileStatus != GL_TRUE) result.fail("expected GL_TRUE"); } { const tcu::ScopedLogSection section(gl.getLog(), "Program", "Create and bind program"); const char* transform_feedback_outputs = "gl_Position"; GLint linkStatus = -1; shaderProg = gl.glCreateProgram(); gl.glAttachShader(shaderProg, shaderVert); gl.glAttachShader(shaderProg, shaderFrag); gl.glTransformFeedbackVaryings(shaderProg, 1, &transform_feedback_outputs, GL_INTERLEAVED_ATTRIBS); gl.glLinkProgram(shaderProg); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glLinkProgram"); gl.glGetProgramiv(shaderProg, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) result.fail("expected GL_TRUE"); } gl.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformfeedback); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindTransformFeedback"); gl.glGenBuffers(1, &feedbackBufferId); gl.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBufferId); gl.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ); gl.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, feedbackBufferId); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind buffers"); gl.glUseProgram(shaderProg); verifyStateInteger(result, gl, GL_TRANSFORM_FEEDBACK_BINDING, transformfeedback, m_type); gl.glUseProgram(0); gl.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); gl.glDeleteTransformFeedbacks(1, &transformfeedback); verifyStateInteger(result, gl, GL_TRANSFORM_FEEDBACK_BINDING, 0, m_type); gl.glDeleteBuffers(1, &feedbackBufferId); gl.glDeleteShader(shaderVert); gl.glDeleteShader(shaderFrag); gl.glDeleteProgram(shaderProg); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteProgram"); } }; class CurrentProgramBindingTestCase : public BindingTest { public: CurrentProgramBindingTestCase (Context& context, QueryType type, const char* name, const char* description) : BindingTest(context, name, description, type) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { static const char* testVertSource = "#version 300 es\n" "void main (void)\n" "{\n" " gl_Position = vec4(0.0);\n" "}\n\0"; static const char* testFragSource = "#version 300 es\n" "layout(location = 0) out mediump vec4 fragColor;" "void main (void)\n" "{\n" " fragColor = vec4(0.0);\n" "}\n\0"; GLuint shaderVert; GLuint shaderFrag; GLuint shaderProg; { const tcu::ScopedLogSection section(gl.getLog(), "Initial", "Initial"); verifyStateInteger(result, gl, GL_CURRENT_PROGRAM, 0, m_type); } { const tcu::ScopedLogSection section(gl.getLog(), "VertexShader", "Vertex Shader"); GLint compileStatus = -1; shaderVert = gl.glCreateShader(GL_VERTEX_SHADER); gl.glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); gl.glCompileShader(shaderVert); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glCompileShader"); gl.glGetShaderiv(shaderVert, GL_COMPILE_STATUS, &compileStatus); if (compileStatus != GL_TRUE) result.fail("expected GL_TRUE"); } { const tcu::ScopedLogSection section(gl.getLog(), "FragmentShader", "Fragment Shader"); GLint compileStatus = -1; shaderFrag = gl.glCreateShader(GL_FRAGMENT_SHADER); gl.glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); gl.glCompileShader(shaderFrag); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glCompileShader"); gl.glGetShaderiv(shaderFrag, GL_COMPILE_STATUS, &compileStatus); if (compileStatus != GL_TRUE) result.fail("expected GL_TRUE"); } { const tcu::ScopedLogSection section(gl.getLog(), "Program", "Create and bind program"); GLint linkStatus = -1; shaderProg = gl.glCreateProgram(); gl.glAttachShader(shaderProg, shaderVert); gl.glAttachShader(shaderProg, shaderFrag); gl.glLinkProgram(shaderProg); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glLinkProgram"); gl.glGetProgramiv(shaderProg, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) result.fail("expected GL_TRUE"); gl.glUseProgram(shaderProg); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glUseProgram"); verifyStateInteger(result, gl, GL_CURRENT_PROGRAM, shaderProg, m_type); } { const tcu::ScopedLogSection section(gl.getLog(), "Delete", "Delete program while in use"); gl.glDeleteShader(shaderVert); gl.glDeleteShader(shaderFrag); gl.glDeleteProgram(shaderProg); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteProgram"); verifyStateInteger(result, gl, GL_CURRENT_PROGRAM, shaderProg, m_type); } { const tcu::ScopedLogSection section(gl.getLog(), "Unbind", "Unbind program"); gl.glUseProgram(0); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glUseProgram"); verifyStateInteger(result, gl, GL_CURRENT_PROGRAM, 0, m_type); } } }; class VertexArrayBindingTestCase : public BindingTest { public: VertexArrayBindingTestCase (Context& context, QueryType type, const char* name, const char* description) : BindingTest(context, name, description, type) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { verifyStateInteger(result, gl, GL_VERTEX_ARRAY_BINDING, 0, m_type); GLuint vertexArrayObject = 0; gl.glGenVertexArrays(1, &vertexArrayObject); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenVertexArrays"); gl.glBindVertexArray(vertexArrayObject); verifyStateInteger(result, gl, GL_VERTEX_ARRAY_BINDING, vertexArrayObject, m_type); gl.glDeleteVertexArrays(1, &vertexArrayObject); verifyStateInteger(result, gl, GL_VERTEX_ARRAY_BINDING, 0, m_type); } }; class BufferBindingTestCase : public BindingTest { public: BufferBindingTestCase (Context& context, QueryType type, const char* name, const char* description, GLenum bufferBindingName, GLenum bufferType) : BindingTest (context, name, description, type) , m_bufferBindingName (bufferBindingName) , m_bufferType (bufferType) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { verifyStateInteger(result, gl, m_bufferBindingName, 0, m_type); GLuint bufferObject = 0; gl.glGenBuffers(1, &bufferObject); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenBuffers"); gl.glBindBuffer(m_bufferType, bufferObject); verifyStateInteger(result, gl, m_bufferBindingName, bufferObject, m_type); gl.glDeleteBuffers(1, &bufferObject); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteBuffers"); verifyStateInteger(result, gl, m_bufferBindingName, 0, m_type); } private: const GLenum m_bufferBindingName; const GLenum m_bufferType; }; class ElementArrayBufferBindingTestCase : public BindingTest { public: ElementArrayBufferBindingTestCase (Context& context, QueryType type, const char* name) : BindingTest(context, name, "GL_ELEMENT_ARRAY_BUFFER_BINDING", type) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { // Test with default VAO { const tcu::ScopedLogSection section(gl.getLog(), "DefaultVAO", "Test with default VAO"); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type); GLuint bufferObject = 0; gl.glGenBuffers(1, &bufferObject); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenBuffers"); gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObject); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, bufferObject, m_type); gl.glDeleteBuffers(1, &bufferObject); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type); } // Test with multiple VAOs { const tcu::ScopedLogSection section(gl.getLog(), "WithVAO", "Test with VAO"); GLuint vaos[2] = {0}; GLuint buffers[2] = {0}; gl.glGenVertexArrays(2, vaos); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenVertexArrays"); gl.glGenBuffers(2, buffers); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenBuffers"); // initial gl.glBindVertexArray(vaos[0]); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type); // after setting gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[0]); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, buffers[0], m_type); // initial of vao 2 gl.glBindVertexArray(vaos[1]); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type); // after setting to 2 gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, buffers[1], m_type); // vao 1 still has buffer 1 bound? gl.glBindVertexArray(vaos[0]); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, buffers[0], m_type); // deleting clears from bound vaos ... gl.glDeleteBuffers(2, buffers); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type); // ... but does not from non-bound vaos? gl.glBindVertexArray(vaos[1]); verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, buffers[1], m_type); gl.glDeleteVertexArrays(2, vaos); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteVertexArrays"); } } }; class StencilClearValueTestCase : public ApiCase { public: StencilClearValueTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { m_verifier->verifyInteger(m_testCtx, GL_STENCIL_CLEAR_VALUE, 0); expectError(GL_NO_ERROR); const int stencilBits = m_context.getRenderTarget().getStencilBits(); for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit) { const int ref = 1 << stencilBit; glClearStencil(ref); // mask should not affect the REF expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_STENCIL_CLEAR_VALUE, ref); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class ActiveTextureTestCase : public ApiCase { public: ActiveTextureTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { m_verifier->verifyInteger(m_testCtx, GL_ACTIVE_TEXTURE, GL_TEXTURE0); expectError(GL_NO_ERROR); GLint textureUnits = 0; glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &textureUnits); expectError(GL_NO_ERROR); for (int ndx = 0; ndx < textureUnits; ++ndx) { glActiveTexture(GL_TEXTURE0 + ndx); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_ACTIVE_TEXTURE, GL_TEXTURE0 + ndx); expectError(GL_NO_ERROR); } } private: StateVerifier* m_verifier; }; class RenderbufferBindingTestCase : public BindingTest { public: RenderbufferBindingTestCase (Context& context, QueryType type, const char* name, const char* description) : BindingTest(context, name, description, type) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { verifyStateInteger(result, gl, GL_RENDERBUFFER_BINDING, 0, m_type); GLuint renderBuffer = 0; gl.glGenRenderbuffers(1, &renderBuffer); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenRenderbuffers"); gl.glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindRenderbuffer"); verifyStateInteger(result, gl, GL_RENDERBUFFER_BINDING, renderBuffer, m_type); gl.glDeleteRenderbuffers(1, &renderBuffer); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteRenderbuffers"); verifyStateInteger(result, gl, GL_RENDERBUFFER_BINDING, 0, m_type); } }; class SamplerObjectBindingTestCase : public BindingTest { public: SamplerObjectBindingTestCase (Context& context, QueryType type, const char* name, const char* description) : BindingTest(context, name, description, type) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { verifyStateInteger(result, gl, GL_SAMPLER_BINDING, 0, m_type); { const tcu::ScopedLogSection section(gl.getLog(), "SingleUnit", "Single unit"); GLuint sampler = 0; gl.glGenSamplers(1, &sampler); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenSamplers"); gl.glBindSampler(0, sampler); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindSampler"); verifyStateInteger(result, gl, GL_SAMPLER_BINDING, sampler, m_type); gl.glDeleteSamplers(1, &sampler); verifyStateInteger(result, gl, GL_SAMPLER_BINDING, 0, m_type); } { const tcu::ScopedLogSection section(gl.getLog(), "MultipleUnits", "Multiple units"); GLuint samplerA = 0; GLuint samplerB = 0; gl.glGenSamplers(1, &samplerA); gl.glGenSamplers(1, &samplerB); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenSamplers"); gl.glBindSampler(1, samplerA); gl.glBindSampler(2, samplerB); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindSampler"); verifyStateInteger(result, gl, GL_SAMPLER_BINDING, 0, m_type); gl.glActiveTexture(GL_TEXTURE1); verifyStateInteger(result, gl, GL_SAMPLER_BINDING, samplerA, m_type); gl.glActiveTexture(GL_TEXTURE2); verifyStateInteger(result, gl, GL_SAMPLER_BINDING, samplerB, m_type); gl.glDeleteSamplers(1, &samplerB); gl.glDeleteSamplers(1, &samplerA); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteSamplers"); } } }; class TextureBindingTestCase : public BindingTest { public: TextureBindingTestCase (Context& context, QueryType type, const char* name, const char* description, GLenum testBindingName, GLenum textureType) : BindingTest (context, name, description, type) , m_testBindingName (testBindingName) , m_textureType (textureType) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { verifyStateInteger(result, gl, m_testBindingName, 0, m_type); GLuint texture = 0; gl.glGenTextures(1, &texture); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenTextures"); gl.glBindTexture(m_textureType, texture); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindTexture"); verifyStateInteger(result, gl, m_testBindingName, texture, m_type); gl.glDeleteTextures(1, &texture); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteTextures"); verifyStateInteger(result, gl, m_testBindingName, 0, m_type); } private: const GLenum m_testBindingName; const GLenum m_textureType; }; class FrameBufferBindingTestCase : public BindingTest { public: FrameBufferBindingTestCase (Context& context, QueryType type, const char* name, const char* description) : BindingTest(context, name, description, type) { } void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const { verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, 0, m_type); verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, 0, m_type); verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, 0, m_type); GLuint framebufferId = 0; gl.glGenFramebuffers(1, &framebufferId); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenFramebuffers"); gl.glBindFramebuffer(GL_FRAMEBUFFER, framebufferId); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind GL_FRAMEBUFFER"); verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, framebufferId, m_type); verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, framebufferId, m_type); verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, framebufferId, m_type); gl.glBindFramebuffer(GL_FRAMEBUFFER, 0); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "unbind GL_FRAMEBUFFER"); verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, 0, m_type); verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, 0, m_type); verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, 0, m_type); gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferId); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind GL_READ_FRAMEBUFFER"); verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, 0, m_type); verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, 0, m_type); verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, framebufferId, m_type); gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferId); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind GL_DRAW_FRAMEBUFFER"); verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, framebufferId, m_type); verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, framebufferId, m_type); verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, framebufferId, m_type); gl.glDeleteFramebuffers(1, &framebufferId); GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteFramebuffers"); verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, 0, m_type); verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, 0, m_type); verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, 0, m_type); } }; class ImplementationColorReadTestCase : public ApiCase { public: ImplementationColorReadTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { const GLint defaultColorTypes[] = { GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV }; const GLint defaultColorFormats[] = { GL_RGBA, GL_RGBA_INTEGER, GL_RGB, GL_RGB_INTEGER, GL_RG, GL_RG_INTEGER, GL_RED, GL_RED_INTEGER }; std::vector<GLint> validColorTypes; std::vector<GLint> validColorFormats; // Defined by the spec for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(defaultColorTypes); ++ndx) validColorTypes.push_back(defaultColorTypes[ndx]); for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(defaultColorFormats); ++ndx) validColorFormats.push_back(defaultColorFormats[ndx]); // Extensions if (m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888") || m_context.getContextInfo().isExtensionSupported("GL_APPLE_texture_format_BGRA8888")) validColorFormats.push_back(GL_BGRA); if (m_context.getContextInfo().isExtensionSupported("GL_EXT_read_format_bgra")) { validColorFormats.push_back(GL_BGRA); validColorTypes.push_back(GL_UNSIGNED_SHORT_4_4_4_4_REV); validColorTypes.push_back(GL_UNSIGNED_SHORT_1_5_5_5_REV); } if (m_context.getContextInfo().isExtensionSupported("GL_IMG_read_format")) { validColorFormats.push_back(GL_BGRA); validColorTypes.push_back(GL_UNSIGNED_SHORT_4_4_4_4_REV); } if (m_context.getContextInfo().isExtensionSupported("GL_NV_sRGB_formats")) { validColorFormats.push_back(GL_SLUMINANCE_NV); validColorFormats.push_back(GL_SLUMINANCE_ALPHA_NV); } if (m_context.getContextInfo().isExtensionSupported("GL_NV_bgr")) { validColorFormats.push_back(GL_BGR_NV); } m_verifier->verifyIntegerAnyOf(m_testCtx, GL_IMPLEMENTATION_COLOR_READ_TYPE, &validColorTypes[0], validColorTypes.size()); m_verifier->verifyIntegerAnyOf(m_testCtx, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &validColorFormats[0], validColorFormats.size()); expectError(GL_NO_ERROR); } private: StateVerifier* m_verifier; }; class ReadBufferCase : public ApiCase { public: ReadBufferCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { const GLint validInitialValues[] = {GL_BACK, GL_NONE}; m_verifier->verifyIntegerAnyOf(m_testCtx, GL_READ_BUFFER, validInitialValues, DE_LENGTH_OF_ARRAY(validInitialValues)); expectError(GL_NO_ERROR); glReadBuffer(GL_NONE); m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, GL_NONE); expectError(GL_NO_ERROR); glReadBuffer(GL_BACK); m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, GL_BACK); expectError(GL_NO_ERROR); // test GL_READ_BUFFER with framebuffers GLuint framebufferId = 0; glGenFramebuffers(1, &framebufferId); expectError(GL_NO_ERROR); GLuint renderbuffer_id = 0; glGenRenderbuffers(1, &renderbuffer_id); expectError(GL_NO_ERROR); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_id); expectError(GL_NO_ERROR); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 128, 128); expectError(GL_NO_ERROR); glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferId); expectError(GL_NO_ERROR); glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_id); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, GL_COLOR_ATTACHMENT0); glDeleteFramebuffers(1, &framebufferId); glDeleteRenderbuffers(1, &renderbuffer_id); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, GL_BACK); expectError(GL_NO_ERROR); } private: StateVerifier* m_verifier; }; class DrawBufferCase : public ApiCase { public: DrawBufferCase (Context& context, StateVerifier* verifier, const char* name, const char* description) : ApiCase (context, name, description) , m_verifier (verifier) { } void test (void) { const GLint validInitialValues[] = {GL_BACK, GL_NONE}; m_verifier->verifyIntegerAnyOf(m_testCtx, GL_DRAW_BUFFER0, validInitialValues, DE_LENGTH_OF_ARRAY(validInitialValues)); expectError(GL_NO_ERROR); GLenum bufs = GL_NONE; glDrawBuffers(1, &bufs); m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_NONE); expectError(GL_NO_ERROR); bufs = GL_BACK; glDrawBuffers(1, &bufs); m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_BACK); expectError(GL_NO_ERROR); // test GL_DRAW_BUFFER with framebuffers GLuint framebufferId = 0; glGenFramebuffers(1, &framebufferId); expectError(GL_NO_ERROR); GLuint renderbuffer_ids[2] = {0}; glGenRenderbuffers(2, renderbuffer_ids); expectError(GL_NO_ERROR); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_ids[0]); expectError(GL_NO_ERROR); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 128, 128); expectError(GL_NO_ERROR); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_ids[1]); expectError(GL_NO_ERROR); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 128, 128); expectError(GL_NO_ERROR); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferId); expectError(GL_NO_ERROR); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_ids[0]); expectError(GL_NO_ERROR); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, renderbuffer_ids[1]); expectError(GL_NO_ERROR); // only the initial state the draw buffer for fragment color zero is defined m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_COLOR_ATTACHMENT0); GLenum bufTargets[2] = {GL_NONE, GL_COLOR_ATTACHMENT1}; glDrawBuffers(2, bufTargets); m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_NONE); m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER1, GL_COLOR_ATTACHMENT1); glDeleteFramebuffers(1, &framebufferId); glDeleteRenderbuffers(2, renderbuffer_ids); expectError(GL_NO_ERROR); m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_BACK); expectError(GL_NO_ERROR); } private: StateVerifier* m_verifier; }; static const char* getQueryTypeSuffix (QueryType type) { switch (type) { case QUERY_BOOLEAN: return "_getboolean"; case QUERY_INTEGER: return "_getinteger"; case QUERY_INTEGER64: return "_getinteger64"; case QUERY_FLOAT: return "_getfloat"; default: DE_ASSERT(DE_FALSE); return DE_NULL; } } #define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK) \ for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++) \ { \ StateVerifier* verifier = VERIFIERS[_verifierNdx]; \ CODE_BLOCK; \ } #define FOR_EACH_QUERYTYPE(QUERYTYPES, CODE_BLOCK) \ for (int _queryTypeNdx = 0; _queryTypeNdx < DE_LENGTH_OF_ARRAY(QUERYTYPES); _queryTypeNdx++) \ { \ const QueryType queryType = QUERYTYPES[_queryTypeNdx]; \ CODE_BLOCK; \ } } // anonymous IntegerStateQueryTests::IntegerStateQueryTests (Context& context) : TestCaseGroup (context, "integers", "Integer Values") , m_verifierBoolean (DE_NULL) , m_verifierInteger (DE_NULL) , m_verifierInteger64 (DE_NULL) , m_verifierFloat (DE_NULL) { } IntegerStateQueryTests::~IntegerStateQueryTests (void) { deinit(); } void IntegerStateQueryTests::init (void) { static const QueryType queryTypes[] = { QUERY_BOOLEAN, QUERY_INTEGER, QUERY_INTEGER64, QUERY_FLOAT, }; DE_ASSERT(m_verifierBoolean == DE_NULL); DE_ASSERT(m_verifierInteger == DE_NULL); DE_ASSERT(m_verifierInteger64 == DE_NULL); DE_ASSERT(m_verifierFloat == DE_NULL); m_verifierBoolean = new GetBooleanVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog()); m_verifierInteger = new GetIntegerVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog()); m_verifierInteger64 = new GetInteger64Verifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog()); m_verifierFloat = new GetFloatVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog()); const struct LimitedStateInteger { const char* name; const char* description; GLenum targetName; GLint value; } implementationMinLimits[] = { { "subpixel_bits", "SUBPIXEL_BITS has minimum value of 4", GL_SUBPIXEL_BITS, 4 }, { "max_3d_texture_size", "MAX_3D_TEXTURE_SIZE has minimum value of 256", GL_MAX_3D_TEXTURE_SIZE, 256 }, { "max_texture_size", "MAX_TEXTURE_SIZE has minimum value of 2048", GL_MAX_TEXTURE_SIZE, 2048}, { "max_array_texture_layers", "MAX_ARRAY_TEXTURE_LAYERS has minimum value of 256", GL_MAX_ARRAY_TEXTURE_LAYERS, 256 }, { "max_cube_map_texture_size", "MAX_CUBE_MAP_TEXTURE_SIZE has minimum value of 2048", GL_MAX_CUBE_MAP_TEXTURE_SIZE, 2048}, { "max_renderbuffer_size", "MAX_RENDERBUFFER_SIZE has minimum value of 2048", GL_MAX_RENDERBUFFER_SIZE, 2048}, { "max_draw_buffers", "MAX_DRAW_BUFFERS has minimum value of 4", GL_MAX_DRAW_BUFFERS, 4 }, { "max_color_attachments", "MAX_COLOR_ATTACHMENTS has minimum value of 4", GL_MAX_COLOR_ATTACHMENTS, 4 }, { "max_elements_indices", "MAX_ELEMENTS_INDICES has minimum value of 0", GL_MAX_ELEMENTS_INDICES, 0 }, { "max_elements_vertices", "MAX_ELEMENTS_VERTICES has minimum value of 0", GL_MAX_ELEMENTS_VERTICES, 0 }, { "num_extensions", "NUM_EXTENSIONS has minimum value of 0", GL_NUM_EXTENSIONS, 0 }, { "major_version", "MAJOR_VERSION has minimum value of 3", GL_MAJOR_VERSION, 3 }, { "minor_version", "MINOR_VERSION has minimum value of 0", GL_MINOR_VERSION, 0 }, { "max_vertex_attribs", "MAX_VERTEX_ATTRIBS has minimum value of 16", GL_MAX_VERTEX_ATTRIBS, 16 }, { "max_vertex_uniform_components", "MAX_VERTEX_UNIFORM_COMPONENTS has minimum value of 1024", GL_MAX_VERTEX_UNIFORM_COMPONENTS, 1024}, { "max_vertex_uniform_vectors", "MAX_VERTEX_UNIFORM_VECTORS has minimum value of 256", GL_MAX_VERTEX_UNIFORM_VECTORS, 256 }, { "max_vertex_uniform_blocks", "MAX_VERTEX_UNIFORM_BLOCKS has minimum value of 12", GL_MAX_VERTEX_UNIFORM_BLOCKS, 12 }, { "max_vertex_output_components", "MAX_VERTEX_OUTPUT_COMPONENTS has minimum value of 64", GL_MAX_VERTEX_OUTPUT_COMPONENTS, 64 }, { "max_vertex_texture_image_units", "MAX_VERTEX_TEXTURE_IMAGE_UNITS has minimum value of 16", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, 16 }, { "max_fragment_uniform_components", "MAX_FRAGMENT_UNIFORM_COMPONENTS has minimum value of 896", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, 896 }, { "max_fragment_uniform_vectors", "MAX_FRAGMENT_UNIFORM_VECTORS has minimum value of 224", GL_MAX_FRAGMENT_UNIFORM_VECTORS, 224 }, { "max_fragment_uniform_blocks", "MAX_FRAGMENT_UNIFORM_BLOCKS has minimum value of 12", GL_MAX_FRAGMENT_UNIFORM_BLOCKS, 12 }, { "max_fragment_input_components", "MAX_FRAGMENT_INPUT_COMPONENTS has minimum value of 60", GL_MAX_FRAGMENT_INPUT_COMPONENTS, 60 }, { "max_texture_image_units", "MAX_TEXTURE_IMAGE_UNITS has minimum value of 16", GL_MAX_TEXTURE_IMAGE_UNITS, 16 }, { "max_program_texel_offset", "MAX_PROGRAM_TEXEL_OFFSET has minimum value of 7", GL_MAX_PROGRAM_TEXEL_OFFSET, 7 }, { "max_uniform_buffer_bindings", "MAX_UNIFORM_BUFFER_BINDINGS has minimum value of 24", GL_MAX_UNIFORM_BUFFER_BINDINGS, 24 }, { "max_combined_uniform_blocks", "MAX_COMBINED_UNIFORM_BLOCKS has minimum value of 24", GL_MAX_COMBINED_UNIFORM_BLOCKS, 24 }, { "max_varying_components", "MAX_VARYING_COMPONENTS has minimum value of 60", GL_MAX_VARYING_COMPONENTS, 60 }, { "max_varying_vectors", "MAX_VARYING_VECTORS has minimum value of 15", GL_MAX_VARYING_VECTORS, 15 }, { "max_combined_texture_image_units", "MAX_COMBINED_TEXTURE_IMAGE_UNITS has minimum value of 32", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 32 }, { "max_transform_feedback_interleaved_components", "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS has minimum value of 64", GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, 64 }, { "max_transform_feedback_separate_attribs", "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS has minimum value of 4", GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, 4 }, { "max_transform_feedback_separate_components", "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS has minimum value of 4", GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, 4 }, { "max_samples", "MAX_SAMPLES has minimum value of 4", GL_MAX_SAMPLES, 4 }, { "red_bits", "RED_BITS has minimum value of 0", GL_RED_BITS, 0 }, { "green_bits", "GREEN_BITS has minimum value of 0", GL_GREEN_BITS, 0 }, { "blue_bits", "BLUE_BITS has minimum value of 0", GL_BLUE_BITS, 0 }, { "alpha_bits", "ALPHA_BITS has minimum value of 0", GL_ALPHA_BITS, 0 }, { "depth_bits", "DEPTH_BITS has minimum value of 0", GL_DEPTH_BITS, 0 }, { "stencil_bits", "STENCIL_BITS has minimum value of 0", GL_STENCIL_BITS, 0 }, }; const LimitedStateInteger implementationMaxLimits[] = { { "min_program_texel_offset", "MIN_PROGRAM_TEXEL_OFFSET has maximum value of -8", GL_MIN_PROGRAM_TEXEL_OFFSET, -8 }, { "uniform_buffer_offset_alignment", "UNIFORM_BUFFER_OFFSET_ALIGNMENT has minimum value of 1", GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, 256 }, }; // \note implementation defined limits have their own tests so just check the conversions to boolean, int64 and float StateVerifier* implementationLimitVerifiers[] = {m_verifierBoolean, m_verifierInteger64, m_verifierFloat}; for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationMinLimits); testNdx++) FOR_EACH_VERIFIER(implementationLimitVerifiers, addChild(new ConstantMinimumValueTestCase(m_context, verifier, (std::string(implementationMinLimits[testNdx].name) + verifier->getTestNamePostfix()).c_str(), implementationMinLimits[testNdx].description, implementationMinLimits[testNdx].targetName, implementationMinLimits[testNdx].value))); for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationMaxLimits); testNdx++) FOR_EACH_VERIFIER(implementationLimitVerifiers, addChild(new ConstantMaximumValueTestCase(m_context, verifier, (std::string(implementationMaxLimits[testNdx].name) + verifier->getTestNamePostfix()).c_str(), implementationMaxLimits[testNdx].description, implementationMaxLimits[testNdx].targetName, implementationMaxLimits[testNdx].value))); StateVerifier* normalVerifiers[] = {m_verifierBoolean, m_verifierInteger, m_verifierInteger64, m_verifierFloat}; FOR_EACH_VERIFIER(implementationLimitVerifiers, addChild(new SampleBuffersTestCase (m_context, verifier, (std::string("sample_buffers") + verifier->getTestNamePostfix()).c_str(), "SAMPLE_BUFFERS"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new SamplesTestCase (m_context, verifier, (std::string("samples") + verifier->getTestNamePostfix()).c_str(), "SAMPLES"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new HintTestCase (m_context, verifier, (std::string("generate_mipmap_hint") + verifier->getTestNamePostfix()).c_str(), "GENERATE_MIPMAP_HINT", GL_GENERATE_MIPMAP_HINT))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new HintTestCase (m_context, verifier, (std::string("fragment_shader_derivative_hint") + verifier->getTestNamePostfix()).c_str(), "FRAGMENT_SHADER_DERIVATIVE_HINT", GL_FRAGMENT_SHADER_DERIVATIVE_HINT))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new DepthFuncTestCase (m_context, verifier, (std::string("depth_func") + verifier->getTestNamePostfix()).c_str(), "DEPTH_FUNC"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new CullFaceTestCase (m_context, verifier, (std::string("cull_face_mode") + verifier->getTestNamePostfix()).c_str(), "CULL_FACE_MODE"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new FrontFaceTestCase (m_context, verifier, (std::string("front_face_mode") + verifier->getTestNamePostfix()).c_str(), "FRONT_FACE"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new ViewPortTestCase (m_context, verifier, (std::string("viewport") + verifier->getTestNamePostfix()).c_str(), "VIEWPORT"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new ScissorBoxTestCase (m_context, verifier, (std::string("scissor_box") + verifier->getTestNamePostfix()).c_str(), "SCISSOR_BOX"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new MaxViewportDimsTestCase (m_context, verifier, (std::string("max_viewport_dims") + verifier->getTestNamePostfix()).c_str(), "MAX_VIEWPORT_DIMS"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefTestCase (m_context, verifier, (std::string("stencil_ref") + verifier->getTestNamePostfix()).c_str(), "STENCIL_REF", GL_STENCIL_REF))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefTestCase (m_context, verifier, (std::string("stencil_back_ref") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_REF", GL_STENCIL_BACK_REF))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefSeparateTestCase (m_context, verifier, (std::string("stencil_ref_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_REF (separate)", GL_STENCIL_REF, GL_FRONT))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefSeparateTestCase (m_context, verifier, (std::string("stencil_ref_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_REF (separate)", GL_STENCIL_REF, GL_FRONT_AND_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefSeparateTestCase (m_context, verifier, (std::string("stencil_back_ref_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_REF (separate)", GL_STENCIL_BACK_REF, GL_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefSeparateTestCase (m_context, verifier, (std::string("stencil_back_ref_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_REF (separate)", GL_STENCIL_BACK_REF, GL_FRONT_AND_BACK))); const struct NamedStencilOp { const char* name; const char* frontDescription; GLenum frontTarget; const char* backDescription; GLenum backTarget; } stencilOps[] = { { "fail", "STENCIL_FAIL", GL_STENCIL_FAIL, "STENCIL_BACK_FAIL", GL_STENCIL_BACK_FAIL }, { "depth_fail", "STENCIL_PASS_DEPTH_FAIL", GL_STENCIL_PASS_DEPTH_FAIL, "STENCIL_BACK_PASS_DEPTH_FAIL", GL_STENCIL_BACK_PASS_DEPTH_FAIL }, { "depth_pass", "STENCIL_PASS_DEPTH_PASS", GL_STENCIL_PASS_DEPTH_PASS, "STENCIL_BACK_PASS_DEPTH_PASS", GL_STENCIL_BACK_PASS_DEPTH_PASS } }; for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(stencilOps); testNdx++) { FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpTestCase (m_context, verifier, (std::string("stencil_") + stencilOps[testNdx].name + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpTestCase (m_context, verifier, (std::string("stencil_back_") + stencilOps[testNdx].name + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpSeparateTestCase (m_context, verifier, (std::string("stencil_") + stencilOps[testNdx].name + "_separate_both" + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget, GL_FRONT_AND_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpSeparateTestCase (m_context, verifier, (std::string("stencil_back_") + stencilOps[testNdx].name + "_separate_both" + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget, GL_FRONT_AND_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpSeparateTestCase (m_context, verifier, (std::string("stencil_") + stencilOps[testNdx].name + "_separate" + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget, GL_FRONT))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpSeparateTestCase (m_context, verifier, (std::string("stencil_back_") + stencilOps[testNdx].name + "_separate" + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget, GL_BACK))); } FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncTestCase (m_context, verifier, (std::string("stencil_func") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncSeparateTestCase (m_context, verifier, (std::string("stencil_func_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC (separate)", GL_STENCIL_FUNC, GL_FRONT))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncSeparateTestCase (m_context, verifier, (std::string("stencil_func_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC (separate)", GL_STENCIL_FUNC, GL_FRONT_AND_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncSeparateTestCase (m_context, verifier, (std::string("stencil_back_func_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC (separate)", GL_STENCIL_BACK_FUNC, GL_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncSeparateTestCase (m_context, verifier, (std::string("stencil_back_func_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC (separate)", GL_STENCIL_BACK_FUNC, GL_FRONT_AND_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskTestCase (m_context, verifier, (std::string("stencil_value_mask") + verifier->getTestNamePostfix()).c_str(), "STENCIL_VALUE_MASK", GL_STENCIL_VALUE_MASK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskTestCase (m_context, verifier, (std::string("stencil_back_value_mask") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_VALUE_MASK", GL_STENCIL_BACK_VALUE_MASK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskSeparateTestCase (m_context, verifier, (std::string("stencil_value_mask_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_VALUE_MASK (separate)", GL_STENCIL_VALUE_MASK, GL_FRONT))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskSeparateTestCase (m_context, verifier, (std::string("stencil_value_mask_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_VALUE_MASK (separate)", GL_STENCIL_VALUE_MASK, GL_FRONT_AND_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskSeparateTestCase (m_context, verifier, (std::string("stencil_back_value_mask_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_VALUE_MASK (separate)", GL_STENCIL_BACK_VALUE_MASK, GL_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskSeparateTestCase (m_context, verifier, (std::string("stencil_back_value_mask_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_VALUE_MASK (separate)", GL_STENCIL_BACK_VALUE_MASK, GL_FRONT_AND_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskTestCase (m_context, verifier, (std::string("stencil_writemask") + verifier->getTestNamePostfix()).c_str(), "STENCIL_WRITEMASK", GL_STENCIL_WRITEMASK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskTestCase (m_context, verifier, (std::string("stencil_back_writemask") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_WRITEMASK", GL_STENCIL_BACK_WRITEMASK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskSeparateTestCase (m_context, verifier, (std::string("stencil_writemask_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_WRITEMASK (separate)", GL_STENCIL_WRITEMASK, GL_FRONT))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskSeparateTestCase (m_context, verifier, (std::string("stencil_writemask_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_WRITEMASK (separate)", GL_STENCIL_WRITEMASK, GL_FRONT_AND_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskSeparateTestCase (m_context, verifier, (std::string("stencil_back_writemask_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_WRITEMASK (separate)", GL_STENCIL_BACK_WRITEMASK, GL_BACK))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskSeparateTestCase (m_context, verifier, (std::string("stencil_back_writemask_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_WRITEMASK (separate)", GL_STENCIL_BACK_WRITEMASK, GL_FRONT_AND_BACK))); const struct PixelStoreState { const char* name; const char* description; GLenum target; int initialValue; } pixelStoreStates[] = { { "unpack_image_height","UNPACK_IMAGE_HEIGHT", GL_UNPACK_IMAGE_HEIGHT, 0 }, { "unpack_skip_images", "UNPACK_SKIP_IMAGES", GL_UNPACK_SKIP_IMAGES, 0 }, { "unpack_row_length", "UNPACK_ROW_LENGTH", GL_UNPACK_ROW_LENGTH, 0 }, { "unpack_skip_rows", "UNPACK_SKIP_ROWS", GL_UNPACK_SKIP_ROWS, 0 }, { "unpack_skip_pixels", "UNPACK_SKIP_PIXELS", GL_UNPACK_SKIP_PIXELS, 0 }, { "pack_row_length", "PACK_ROW_LENGTH", GL_PACK_ROW_LENGTH, 0 }, { "pack_skip_rows", "PACK_SKIP_ROWS", GL_PACK_SKIP_ROWS, 0 }, { "pack_skip_pixels", "PACK_SKIP_PIXELS", GL_PACK_SKIP_PIXELS, 0 } }; for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(pixelStoreStates); testNdx++) { FOR_EACH_VERIFIER(normalVerifiers, addChild(new PixelStoreTestCase(m_context, verifier, (std::string(pixelStoreStates[testNdx].name) + verifier->getTestNamePostfix()).c_str(), pixelStoreStates[testNdx].description, pixelStoreStates[testNdx].target, pixelStoreStates[testNdx].initialValue))); } FOR_EACH_VERIFIER(normalVerifiers, addChild(new PixelStoreAlignTestCase(m_context, verifier, (std::string("unpack_alignment") + verifier->getTestNamePostfix()).c_str(), "UNPACK_ALIGNMENT", GL_UNPACK_ALIGNMENT))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new PixelStoreAlignTestCase(m_context, verifier, (std::string("pack_alignment") + verifier->getTestNamePostfix()).c_str(), "PACK_ALIGNMENT", GL_PACK_ALIGNMENT))); const struct BlendColorState { const char* name; const char* description; GLenum target; int initialValue; } blendColorStates[] = { { "blend_src_rgb", "BLEND_SRC_RGB", GL_BLEND_SRC_RGB, GL_ONE }, { "blend_src_alpha", "BLEND_SRC_ALPHA", GL_BLEND_SRC_ALPHA, GL_ONE }, { "blend_dst_rgb", "BLEND_DST_RGB", GL_BLEND_DST_RGB, GL_ZERO }, { "blend_dst_alpha", "BLEND_DST_ALPHA", GL_BLEND_DST_ALPHA, GL_ZERO } }; for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(blendColorStates); testNdx++) { FOR_EACH_VERIFIER(normalVerifiers, addChild(new BlendFuncTestCase (m_context, verifier, (std::string(blendColorStates[testNdx].name) + verifier->getTestNamePostfix()).c_str(), blendColorStates[testNdx].description, blendColorStates[testNdx].target, blendColorStates[testNdx].initialValue))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new BlendFuncSeparateTestCase (m_context, verifier, (std::string(blendColorStates[testNdx].name) + "_separate" + verifier->getTestNamePostfix()).c_str(), blendColorStates[testNdx].description, blendColorStates[testNdx].target, blendColorStates[testNdx].initialValue))); } const struct BlendEquationState { const char* name; const char* description; GLenum target; int initialValue; } blendEquationStates[] = { { "blend_equation_rgb", "BLEND_EQUATION_RGB", GL_BLEND_EQUATION_RGB, GL_FUNC_ADD }, { "blend_equation_alpha", "BLEND_EQUATION_ALPHA", GL_BLEND_EQUATION_ALPHA, GL_FUNC_ADD } }; for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(blendEquationStates); testNdx++) { FOR_EACH_VERIFIER(normalVerifiers, addChild(new BlendEquationTestCase (m_context, verifier, (std::string(blendEquationStates[testNdx].name) + + verifier->getTestNamePostfix()).c_str(), blendEquationStates[testNdx].description, blendEquationStates[testNdx].target, blendEquationStates[testNdx].initialValue))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new BlendEquationSeparateTestCase (m_context, verifier, (std::string(blendEquationStates[testNdx].name) + "_separate" + verifier->getTestNamePostfix()).c_str(), blendEquationStates[testNdx].description, blendEquationStates[testNdx].target, blendEquationStates[testNdx].initialValue))); } const struct ImplementationArrayReturningState { const char* name; const char* description; GLenum target; GLenum targetLengthTarget; int minLength; } implementationArrayReturningStates[] = { { "compressed_texture_formats", "COMPRESSED_TEXTURE_FORMATS", GL_COMPRESSED_TEXTURE_FORMATS, GL_NUM_COMPRESSED_TEXTURE_FORMATS, 10 }, { "program_binary_formats", "PROGRAM_BINARY_FORMATS", GL_PROGRAM_BINARY_FORMATS, GL_NUM_PROGRAM_BINARY_FORMATS, 0 }, { "shader_binary_formats", "SHADER_BINARY_FORMATS", GL_SHADER_BINARY_FORMATS, GL_NUM_SHADER_BINARY_FORMATS, 0 } }; for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationArrayReturningStates); testNdx++) { FOR_EACH_VERIFIER(normalVerifiers, addChild(new ImplementationArrayTestCase(m_context, verifier, (std::string(implementationArrayReturningStates[testNdx].name) + verifier->getTestNamePostfix()).c_str(), implementationArrayReturningStates[testNdx].description, implementationArrayReturningStates[testNdx].target, implementationArrayReturningStates[testNdx].targetLengthTarget, implementationArrayReturningStates[testNdx].minLength))); } const struct BufferBindingState { const char* name; const char* description; GLenum target; GLenum type; } bufferBindingStates[] = { { "array_buffer_binding", "ARRAY_BUFFER_BINDING", GL_ARRAY_BUFFER_BINDING, GL_ARRAY_BUFFER }, { "uniform_buffer_binding", "UNIFORM_BUFFER_BINDING", GL_UNIFORM_BUFFER_BINDING, GL_UNIFORM_BUFFER }, { "pixel_pack_buffer_binding", "PIXEL_PACK_BUFFER_BINDING", GL_PIXEL_PACK_BUFFER_BINDING, GL_PIXEL_PACK_BUFFER }, { "pixel_unpack_buffer_binding", "PIXEL_UNPACK_BUFFER_BINDING", GL_PIXEL_UNPACK_BUFFER_BINDING, GL_PIXEL_UNPACK_BUFFER }, { "transform_feedback_buffer_binding", "TRANSFORM_FEEDBACK_BUFFER_BINDING", GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_TRANSFORM_FEEDBACK_BUFFER}, { "copy_read_buffer_binding", "COPY_READ_BUFFER_BINDING", GL_COPY_READ_BUFFER_BINDING, GL_COPY_READ_BUFFER }, { "copy_write_buffer_binding", "COPY_WRITE_BUFFER_BINDING", GL_COPY_WRITE_BUFFER_BINDING, GL_COPY_WRITE_BUFFER } }; for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(bufferBindingStates); testNdx++) { FOR_EACH_QUERYTYPE(queryTypes, addChild(new BufferBindingTestCase(m_context, queryType, (std::string(bufferBindingStates[testNdx].name) + getQueryTypeSuffix(queryType)).c_str(), bufferBindingStates[testNdx].description, bufferBindingStates[testNdx].target, bufferBindingStates[testNdx].type))); } FOR_EACH_QUERYTYPE(queryTypes, addChild(new ElementArrayBufferBindingTestCase (m_context, queryType, (std::string("element_array_buffer_binding") + getQueryTypeSuffix(queryType)).c_str()))); FOR_EACH_QUERYTYPE(queryTypes, addChild(new TransformFeedbackBindingTestCase (m_context, queryType, (std::string("transform_feedback_binding") + getQueryTypeSuffix(queryType)).c_str()))); FOR_EACH_QUERYTYPE(queryTypes, addChild(new CurrentProgramBindingTestCase (m_context, queryType, (std::string("current_program_binding") + getQueryTypeSuffix(queryType)).c_str(), "CURRENT_PROGRAM"))); FOR_EACH_QUERYTYPE(queryTypes, addChild(new VertexArrayBindingTestCase (m_context, queryType, (std::string("vertex_array_binding") + getQueryTypeSuffix(queryType)).c_str(), "VERTEX_ARRAY_BINDING"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilClearValueTestCase (m_context, verifier, (std::string("stencil_clear_value") + verifier->getTestNamePostfix()).c_str(), "STENCIL_CLEAR_VALUE"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new ActiveTextureTestCase (m_context, verifier, (std::string("active_texture") + verifier->getTestNamePostfix()).c_str(), "ACTIVE_TEXTURE"))); FOR_EACH_QUERYTYPE(queryTypes, addChild(new RenderbufferBindingTestCase (m_context, queryType, (std::string("renderbuffer_binding") + getQueryTypeSuffix(queryType)).c_str(), "RENDERBUFFER_BINDING"))); FOR_EACH_QUERYTYPE(queryTypes, addChild(new SamplerObjectBindingTestCase (m_context, queryType, (std::string("sampler_binding") + getQueryTypeSuffix(queryType)).c_str(), "SAMPLER_BINDING"))); const struct TextureBinding { const char* name; const char* description; GLenum target; GLenum type; } textureBindings[] = { { "texture_binding_2d", "TEXTURE_BINDING_2D", GL_TEXTURE_BINDING_2D, GL_TEXTURE_2D }, { "texture_binding_3d", "TEXTURE_BINDING_3D", GL_TEXTURE_BINDING_3D, GL_TEXTURE_3D }, { "texture_binding_2d_array", "TEXTURE_BINDING_2D_ARRAY", GL_TEXTURE_BINDING_2D_ARRAY, GL_TEXTURE_2D_ARRAY }, { "texture_binding_cube_map", "TEXTURE_BINDING_CUBE_MAP", GL_TEXTURE_BINDING_CUBE_MAP, GL_TEXTURE_CUBE_MAP } }; for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(textureBindings); testNdx++) { FOR_EACH_QUERYTYPE(queryTypes, addChild(new TextureBindingTestCase(m_context, queryType, (std::string(textureBindings[testNdx].name) + getQueryTypeSuffix(queryType)).c_str(), textureBindings[testNdx].description, textureBindings[testNdx].target, textureBindings[testNdx].type))); } FOR_EACH_QUERYTYPE(queryTypes, addChild(new FrameBufferBindingTestCase (m_context, queryType, (std::string("framebuffer_binding") + getQueryTypeSuffix(queryType)).c_str(), "DRAW_FRAMEBUFFER_BINDING and READ_FRAMEBUFFER_BINDING"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new ImplementationColorReadTestCase (m_context, verifier, (std::string("implementation_color_read") + verifier->getTestNamePostfix()).c_str(), "IMPLEMENTATION_COLOR_READ_TYPE and IMPLEMENTATION_COLOR_READ_FORMAT"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new ReadBufferCase (m_context, verifier, (std::string("read_buffer") + verifier->getTestNamePostfix()).c_str(), "READ_BUFFER"))); FOR_EACH_VERIFIER(normalVerifiers, addChild(new DrawBufferCase (m_context, verifier, (std::string("draw_buffer") + verifier->getTestNamePostfix()).c_str(), "DRAW_BUFFER"))); } void IntegerStateQueryTests::deinit (void) { if (m_verifierBoolean) { delete m_verifierBoolean; m_verifierBoolean = DE_NULL; } if (m_verifierInteger) { delete m_verifierInteger; m_verifierInteger = DE_NULL; } if (m_verifierInteger64) { delete m_verifierInteger64; m_verifierInteger64 = DE_NULL; } if (m_verifierFloat) { delete m_verifierFloat; m_verifierFloat = DE_NULL; } this->TestCaseGroup::deinit(); } } // Functional } // gles3 } // deqp