/*-------------------------------------------------------------------------
* 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