blob: 18dd53850381d103937cd6b23bbb52f1ed57f09c [file] [log] [blame] [edit]
/*-------------------------------------------------------------------------
* 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 (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::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);
}
} // namespace 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};
GLfloat viewportBoundsRange[2] = {0.0f};
GLboolean hasViewportArray = false;
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, maxViewportDimensions);
hasViewportArray = m_context.getContextInfo().isExtensionSupported("GL_OES_viewport_array") ||
m_context.getContextInfo().isExtensionSupported("GL_NV_viewport_array") ||
m_context.getContextInfo().isExtensionSupported("GL_ARB_viewport_array");
if (hasViewportArray)
{
glGetFloatv(GL_VIEWPORT_BOUNDS_RANGE, viewportBoundsRange);
}
// 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);
if (hasViewportArray)
{
m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT,
de::clamp(x, deFloorFloatToInt32(viewportBoundsRange[0]),
deFloorFloatToInt32(viewportBoundsRange[1])),
de::clamp(y, deFloorFloatToInt32(viewportBoundsRange[0]),
deFloorFloatToInt32(viewportBoundsRange[1])),
width, height);
}
else
{
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 bool isGlCore45 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
GLenum colorAttachment = isGlCore45 ? GL_FRONT : GL_BACK;
if (isGlCore45)
{
// Make sure GL_FRONT is available. If not, use GL_BACK instead.
GLint objectType = GL_NONE;
glGetFramebufferAttachmentParameteriv(GL_READ_FRAMEBUFFER, colorAttachment,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &objectType);
if (objectType == GL_NONE)
{
colorAttachment = GL_BACK;
}
}
const GLint validInitialValues[] = {(GLint)colorAttachment, 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(colorAttachment);
m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, colorAttachment);
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, colorAttachment);
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_FRONT, 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);
const GLint validDraw0Values[] = {GL_FRONT_LEFT, GL_BACK};
m_verifier->verifyIntegerAnyOf(m_testCtx, GL_DRAW_BUFFER0, validDraw0Values,
DE_LENGTH_OF_ARRAY(validDraw0Values));
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->verifyIntegerAnyOf(m_testCtx, GL_DRAW_BUFFER0, validDraw0Values,
DE_LENGTH_OF_ARRAY(validDraw0Values));
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(false);
return DE_NULL;
}
}
#define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK) \
do \
{ \
for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++) \
{ \
StateVerifier *verifier = (VERIFIERS)[_verifierNdx]; \
CODE_BLOCK; \
} \
} while (0)
#define FOR_EACH_QUERYTYPE(QUERYTYPES, CODE_BLOCK) \
do \
{ \
for (int _queryTypeNdx = 0; _queryTypeNdx < DE_LENGTH_OF_ARRAY(QUERYTYPES); _queryTypeNdx++) \
{ \
const QueryType queryType = (QUERYTYPES)[_queryTypeNdx]; \
CODE_BLOCK; \
} \
} while (0)
} // namespace
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;
bool skipForGl;
} implementationMinLimits[] = {
{"subpixel_bits", "SUBPIXEL_BITS has minimum value of 4", GL_SUBPIXEL_BITS, 4, false},
{"max_3d_texture_size", "MAX_3D_TEXTURE_SIZE has minimum value of 256", GL_MAX_3D_TEXTURE_SIZE, 256, false},
{"max_texture_size", "MAX_TEXTURE_SIZE has minimum value of 2048", GL_MAX_TEXTURE_SIZE, 2048, false},
{"max_array_texture_layers", "MAX_ARRAY_TEXTURE_LAYERS has minimum value of 256", GL_MAX_ARRAY_TEXTURE_LAYERS,
256, false},
{"max_cube_map_texture_size", "MAX_CUBE_MAP_TEXTURE_SIZE has minimum value of 2048",
GL_MAX_CUBE_MAP_TEXTURE_SIZE, 2048, false},
{"max_renderbuffer_size", "MAX_RENDERBUFFER_SIZE has minimum value of 2048", GL_MAX_RENDERBUFFER_SIZE, 2048,
false},
{"max_draw_buffers", "MAX_DRAW_BUFFERS has minimum value of 4", GL_MAX_DRAW_BUFFERS, 4, false},
{"max_color_attachments", "MAX_COLOR_ATTACHMENTS has minimum value of 4", GL_MAX_COLOR_ATTACHMENTS, 4, false},
{"max_elements_indices", "MAX_ELEMENTS_INDICES has minimum value of 0", GL_MAX_ELEMENTS_INDICES, 0, false},
{"max_elements_vertices", "MAX_ELEMENTS_VERTICES has minimum value of 0", GL_MAX_ELEMENTS_VERTICES, 0, false},
{"num_extensions", "NUM_EXTENSIONS has minimum value of 0", GL_NUM_EXTENSIONS, 0, false},
{"major_version", "MAJOR_VERSION has minimum value of 3", GL_MAJOR_VERSION, 3, false},
{"minor_version", "MINOR_VERSION has minimum value of 0", GL_MINOR_VERSION, 0, false},
{"max_vertex_attribs", "MAX_VERTEX_ATTRIBS has minimum value of 16", GL_MAX_VERTEX_ATTRIBS, 16, false},
{"max_vertex_uniform_components", "MAX_VERTEX_UNIFORM_COMPONENTS has minimum value of 1024",
GL_MAX_VERTEX_UNIFORM_COMPONENTS, 1024, false},
{"max_vertex_uniform_vectors", "MAX_VERTEX_UNIFORM_VECTORS has minimum value of 256",
GL_MAX_VERTEX_UNIFORM_VECTORS, 256, false},
{"max_vertex_uniform_blocks", "MAX_VERTEX_UNIFORM_BLOCKS has minimum value of 12", GL_MAX_VERTEX_UNIFORM_BLOCKS,
12, false},
{"max_vertex_output_components", "MAX_VERTEX_OUTPUT_COMPONENTS has minimum value of 64",
GL_MAX_VERTEX_OUTPUT_COMPONENTS, 64, false},
{"max_vertex_texture_image_units", "MAX_VERTEX_TEXTURE_IMAGE_UNITS has minimum value of 16",
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, 16, false},
{"max_fragment_uniform_components", "MAX_FRAGMENT_UNIFORM_COMPONENTS has minimum value of 896",
GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, 896, false},
{"max_fragment_uniform_vectors", "MAX_FRAGMENT_UNIFORM_VECTORS has minimum value of 224",
GL_MAX_FRAGMENT_UNIFORM_VECTORS, 224, false},
{"max_fragment_uniform_blocks", "MAX_FRAGMENT_UNIFORM_BLOCKS has minimum value of 12",
GL_MAX_FRAGMENT_UNIFORM_BLOCKS, 12, false},
{"max_fragment_input_components", "MAX_FRAGMENT_INPUT_COMPONENTS has minimum value of 60",
GL_MAX_FRAGMENT_INPUT_COMPONENTS, 60, false},
{"max_texture_image_units", "MAX_TEXTURE_IMAGE_UNITS has minimum value of 16", GL_MAX_TEXTURE_IMAGE_UNITS, 16,
false},
{"max_program_texel_offset", "MAX_PROGRAM_TEXEL_OFFSET has minimum value of 7", GL_MAX_PROGRAM_TEXEL_OFFSET, 7,
false},
{"max_uniform_buffer_bindings", "MAX_UNIFORM_BUFFER_BINDINGS has minimum value of 24",
GL_MAX_UNIFORM_BUFFER_BINDINGS, 24, false},
{"max_combined_uniform_blocks", "MAX_COMBINED_UNIFORM_BLOCKS has minimum value of 24",
GL_MAX_COMBINED_UNIFORM_BLOCKS, 24, false},
{"max_varying_components", "MAX_VARYING_COMPONENTS has minimum value of 60", GL_MAX_VARYING_COMPONENTS, 60,
false},
{"max_varying_vectors", "MAX_VARYING_VECTORS has minimum value of 15", GL_MAX_VARYING_VECTORS, 15, false},
{"max_combined_texture_image_units", "MAX_COMBINED_TEXTURE_IMAGE_UNITS has minimum value of 32",
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 32, false},
{"max_transform_feedback_interleaved_components",
"MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS has minimum value of 64",
GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, 64, false},
{"max_transform_feedback_separate_attribs", "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS has minimum value of 4",
GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, 4, false},
{"max_transform_feedback_separate_components",
"MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS has minimum value of 4",
GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, 4, false},
{"max_samples", "MAX_SAMPLES has minimum value of 4", GL_MAX_SAMPLES, 4, false},
{"red_bits", "RED_BITS has minimum value of 0", GL_RED_BITS, 0, true},
{"green_bits", "GREEN_BITS has minimum value of 0", GL_GREEN_BITS, 0, true},
{"blue_bits", "BLUE_BITS has minimum value of 0", GL_BLUE_BITS, 0, true},
{"alpha_bits", "ALPHA_BITS has minimum value of 0", GL_ALPHA_BITS, 0, true},
{"depth_bits", "DEPTH_BITS has minimum value of 0", GL_DEPTH_BITS, 0, true},
{"stencil_bits", "STENCIL_BITS has minimum value of 0", GL_STENCIL_BITS, 0, true},
};
const LimitedStateInteger implementationMaxLimits[] = {
{"min_program_texel_offset", "MIN_PROGRAM_TEXEL_OFFSET has maximum value of -8", GL_MIN_PROGRAM_TEXEL_OFFSET,
-8, false},
{"uniform_buffer_offset_alignment", "UNIFORM_BUFFER_OFFSET_ALIGNMENT has minimum value of 1",
GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, 256, false},
};
// \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};
const bool isGlCore45 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationMinLimits); testNdx++)
{
if (implementationMinLimits[testNdx].skipForGl && isGlCore45)
continue;
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")));
if (!isGlCore45)
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();
}
} // namespace Functional
} // namespace gles3
} // namespace deqp