blob: fe825d39d0d63ee1dc3f194db46731e07c02f65f [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 Float State Query tests.
*//*--------------------------------------------------------------------*/
#include "es3fFloatStateQueryTests.hpp"
#include "glsStateQueryUtil.hpp"
#include "es3fApiCase.hpp"
#include "gluRenderContext.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuFormatUtil.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "glwEnums.hpp"
#include <limits>
using namespace glw; // GLint and other GL types
using namespace deqp::gls;
using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
namespace deqp
{
namespace gles3
{
namespace Functional
{
namespace FloatStateQueryVerifiers
{
namespace
{
const int FLOAT_EXPANSION_E = 0x03FF; // 10 bits error allowed, requires 22 accurate bits
const int FLOAT_EXPANSION_E_64 = 0x07FF;
GLint64 expandGLFloatToInteger(GLfloat f)
{
const GLuint64 referenceValue = (GLint64)(f * 2147483647.0);
return referenceValue;
}
GLint clampToGLint(GLint64 val)
{
return (GLint)de::clamp<GLint64>(val, std::numeric_limits<GLint>::min(), std::numeric_limits<GLint>::max());
}
} // namespace
// 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 verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference) = DE_NULL;
// "Expanded" == Float to int conversion converts from [-1.0 to 1.0] -> [MIN_INT MAX_INT]
virtual void verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference) = DE_NULL;
virtual void verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0,
GLfloat reference1) = DE_NULL;
virtual void verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1,
GLfloat reference2, GLfloat reference3) = DE_NULL;
// verify that the given range is completely whitin the GL state range
virtual void verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max) = DE_NULL;
virtual void verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat reference) = 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 verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
void verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
void verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
void verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1,
GLfloat reference2, GLfloat reference3);
void verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max);
void verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
};
GetBooleanVerifier::GetBooleanVerifier(const glw::Functions &gl, tcu::TestLog &log)
: StateVerifier(gl, log, "_getboolean")
{
}
void GetBooleanVerifier::verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLboolean> state;
glGetBooleanv(name, &state);
if (!state.verifyValidity(testCtx))
return;
const GLboolean expectedGLState = reference != 0.0f ? 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::verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
verifyFloat(testCtx, name, reference);
}
void GetBooleanVerifier::verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0,
GLfloat reference1)
{
DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLboolean[2]> boolVector2;
glGetBooleanv(name, boolVector2);
if (!boolVector2.verifyValidity(testCtx))
return;
const GLboolean referenceAsGLBoolean[] = {
reference0 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
reference1 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
};
if (boolVector2[0] != referenceAsGLBoolean[0] || boolVector2[1] != referenceAsGLBoolean[1])
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (boolVector2[0] ? "GL_TRUE" : "GL_FALSE")
<< " " << (boolVector2[1] ? "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::verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0,
GLfloat reference1, GLfloat reference2, GLfloat reference3)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLboolean[4]> boolVector4;
glGetBooleanv(name, boolVector4);
if (!boolVector4.verifyValidity(testCtx))
return;
const GLboolean referenceAsGLBoolean[] = {
reference0 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
reference1 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
reference2 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
reference3 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
};
if (boolVector4[0] != referenceAsGLBoolean[0] || boolVector4[1] != referenceAsGLBoolean[1] ||
boolVector4[2] != referenceAsGLBoolean[2] || boolVector4[3] != referenceAsGLBoolean[3])
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected "
<< (referenceAsGLBoolean[0] ? "GL_TRUE" : "GL_FALSE") << " "
<< (referenceAsGLBoolean[1] ? "GL_TRUE" : "GL_FALSE") << " "
<< (referenceAsGLBoolean[2] ? "GL_TRUE" : "GL_FALSE") << " "
<< (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::verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLboolean[2]> range;
glGetBooleanv(name, range);
if (!range.verifyValidity(testCtx))
return;
if (range[0] == GL_FALSE)
{
if (max < 0 || min < 0)
{
testCtx.getLog() << TestLog::Message << "// ERROR: range [" << min << ", " << max << "] is not in range ["
<< (range[0] == GL_TRUE ? "GL_TRUE" : (range[0] == GL_FALSE ? "GL_FALSE" : "non-boolean"))
<< ", "
<< (range[1] == GL_TRUE ? "GL_TRUE" : (range[1] == GL_FALSE ? "GL_FALSE" : "non-boolean"))
<< "]" << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean range");
return;
}
}
if (range[1] == GL_FALSE)
{
if (max > 0 || min > 0)
{
testCtx.getLog() << TestLog::Message << "// ERROR: range [" << min << ", " << max << "] is not in range ["
<< (range[0] == GL_TRUE ? "GL_TRUE" : (range[0] == GL_FALSE ? "GL_FALSE" : "non-boolean"))
<< ", "
<< (range[1] == GL_TRUE ? "GL_TRUE" : (range[1] == GL_FALSE ? "GL_FALSE" : "non-boolean"))
<< "]" << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean range");
return;
}
}
}
void GetBooleanVerifier::verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat 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");
}
}
//GetIntegerVerifier
class GetIntegerVerifier : public StateVerifier
{
public:
GetIntegerVerifier(const glw::Functions &gl, tcu::TestLog &log);
void verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
void verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
void verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
void verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1,
GLfloat reference2, GLfloat reference3);
void verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max);
void verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
};
GetIntegerVerifier::GetIntegerVerifier(const glw::Functions &gl, tcu::TestLog &log)
: StateVerifier(gl, log, "_getinteger")
{
}
void GetIntegerVerifier::verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
using tcu::TestLog;
const GLint expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(reference);
const GLint expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);
StateQueryMemoryWriteGuard<GLint> state;
glGetIntegerv(name, &state);
if (!state.verifyValidity(testCtx))
return;
if (state < expectedGLStateMin || state > expectedGLStateMax)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected rounding to the nearest integer, valid range ["
<< expectedGLStateMin << "," << expectedGLStateMax << "]; got " << state
<< TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
void GetIntegerVerifier::verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
using tcu::TestLog;
using tcu::toHex;
StateQueryMemoryWriteGuard<GLint> state;
glGetIntegerv(name, &state);
if (!state.verifyValidity(testCtx))
return;
const GLint expectedGLStateMax = clampToGLint(expandGLFloatToInteger(reference) + FLOAT_EXPANSION_E);
const GLint expectedGLStateMin = clampToGLint(expandGLFloatToInteger(reference) - FLOAT_EXPANSION_E);
if (state < expectedGLStateMin || state > expectedGLStateMax)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << toHex(expectedGLStateMin) << ","
<< toHex(expectedGLStateMax) << "]; got " << toHex((GLint)state) << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
void GetIntegerVerifier::verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0,
GLfloat reference1)
{
DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));
using tcu::TestLog;
using tcu::toHex;
StateQueryMemoryWriteGuard<GLint[2]> floatVector2;
glGetIntegerv(name, floatVector2);
if (!floatVector2.verifyValidity(testCtx))
return;
const GLint referenceAsGLintMin[] = {clampToGLint(expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E),
clampToGLint(expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E)};
const GLint referenceAsGLintMax[] = {clampToGLint(expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E),
clampToGLint(expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E)};
if (floatVector2[0] < referenceAsGLintMin[0] || floatVector2[0] > referenceAsGLintMax[0] ||
floatVector2[1] < referenceAsGLintMin[1] || floatVector2[1] > referenceAsGLintMax[1])
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected in ranges "
<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "]"
<< "; got " << toHex(floatVector2[0]) << ", " << toHex(floatVector2[1]) << " "
<< TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
void GetIntegerVerifier::verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0,
GLfloat reference1, GLfloat reference2, GLfloat reference3)
{
using tcu::TestLog;
using tcu::toHex;
StateQueryMemoryWriteGuard<GLint[4]> floatVector4;
glGetIntegerv(name, floatVector4);
if (!floatVector4.verifyValidity(testCtx))
return;
const GLint referenceAsGLintMin[] = {clampToGLint(expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E),
clampToGLint(expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E),
clampToGLint(expandGLFloatToInteger(reference2) - FLOAT_EXPANSION_E),
clampToGLint(expandGLFloatToInteger(reference3) - FLOAT_EXPANSION_E)};
const GLint referenceAsGLintMax[] = {clampToGLint(expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E),
clampToGLint(expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E),
clampToGLint(expandGLFloatToInteger(reference2) + FLOAT_EXPANSION_E),
clampToGLint(expandGLFloatToInteger(reference3) + FLOAT_EXPANSION_E)};
if (floatVector4[0] < referenceAsGLintMin[0] || floatVector4[0] > referenceAsGLintMax[0] ||
floatVector4[1] < referenceAsGLintMin[1] || floatVector4[1] > referenceAsGLintMax[1] ||
floatVector4[2] < referenceAsGLintMin[2] || floatVector4[2] > referenceAsGLintMax[2] ||
floatVector4[3] < referenceAsGLintMin[3] || floatVector4[3] > referenceAsGLintMax[3])
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected in ranges "
<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "], "
<< "[" << toHex(referenceAsGLintMin[2]) << " " << toHex(referenceAsGLintMax[2]) << "], "
<< "[" << toHex(referenceAsGLintMin[3]) << " " << toHex(referenceAsGLintMax[3]) << "]"
<< "; got " << toHex(floatVector4[0]) << ", " << toHex(floatVector4[1]) << ", "
<< toHex(floatVector4[2]) << ", " << toHex(floatVector4[3]) << " " << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
void GetIntegerVerifier::verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLint[2]> range;
glGetIntegerv(name, range);
if (!range.verifyValidity(testCtx))
return;
const GLint testRangeAsGLint[] = {StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(min),
StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(max)};
// check if test range outside of gl state range
if (testRangeAsGLint[0] < range[0] || testRangeAsGLint[1] > range[1])
{
testCtx.getLog() << TestLog::Message << "// ERROR: range [" << testRangeAsGLint[0] << ", "
<< testRangeAsGLint[1] << "]"
<< " is not in range [" << range[0] << ", " << range[1] << "]" << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer range");
}
}
void GetIntegerVerifier::verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLint> state;
glGetIntegerv(name, &state);
if (!state.verifyValidity(testCtx))
return;
const GLint referenceAsInt = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);
if (state < referenceAsInt)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected expected greater or equal to " << referenceAsInt
<< "; got " << state << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
//GetInteger64Verifier
class GetInteger64Verifier : public StateVerifier
{
public:
GetInteger64Verifier(const glw::Functions &gl, tcu::TestLog &log);
void verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
void verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
void verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
void verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1,
GLfloat reference2, GLfloat reference3);
void verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max);
void verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
};
GetInteger64Verifier::GetInteger64Verifier(const glw::Functions &gl, tcu::TestLog &log)
: StateVerifier(gl, log, "_getinteger64")
{
}
void GetInteger64Verifier::verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
using tcu::TestLog;
const GLint64 expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint64>(reference);
const GLint64 expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(reference);
StateQueryMemoryWriteGuard<GLint64> state;
glGetInteger64v(name, &state);
if (!state.verifyValidity(testCtx))
return;
if (state < expectedGLStateMin || state > expectedGLStateMax)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected rounding to the nearest integer, valid range ["
<< expectedGLStateMin << "," << expectedGLStateMax << "]; got " << state
<< TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
void GetInteger64Verifier::verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
using tcu::TestLog;
using tcu::toHex;
StateQueryMemoryWriteGuard<GLint64> state;
glGetInteger64v(name, &state);
if (!state.verifyValidity(testCtx))
return;
const GLint64 expectedGLStateMax = expandGLFloatToInteger(reference) + FLOAT_EXPANSION_E_64;
const GLint64 expectedGLStateMin = expandGLFloatToInteger(reference) - FLOAT_EXPANSION_E_64;
if (state < expectedGLStateMin || state > expectedGLStateMax)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << toHex(expectedGLStateMin) << ","
<< toHex(expectedGLStateMax) << "]; got " << toHex((GLint64)state) << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
void GetInteger64Verifier::verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0,
GLfloat reference1)
{
DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));
using tcu::TestLog;
using tcu::toHex;
StateQueryMemoryWriteGuard<GLint64[2]> floatVector2;
glGetInteger64v(name, floatVector2);
if (!floatVector2.verifyValidity(testCtx))
return;
const GLint64 referenceAsGLintMin[] = {expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E_64,
expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E_64};
const GLint64 referenceAsGLintMax[] = {expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E_64,
expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E_64};
if (floatVector2[0] < referenceAsGLintMin[0] || floatVector2[0] > referenceAsGLintMax[0] ||
floatVector2[1] < referenceAsGLintMin[1] || floatVector2[1] > referenceAsGLintMax[1])
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected in ranges "
<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "]"
<< "; got " << toHex(floatVector2[0]) << ", " << toHex(floatVector2[1]) << " "
<< TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
void GetInteger64Verifier::verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0,
GLfloat reference1, GLfloat reference2, GLfloat reference3)
{
using tcu::TestLog;
using tcu::toHex;
StateQueryMemoryWriteGuard<GLint64[4]> floatVector4;
glGetInteger64v(name, floatVector4);
if (!floatVector4.verifyValidity(testCtx))
return;
const GLint64 referenceAsGLintMin[] = {expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E_64,
expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E_64,
expandGLFloatToInteger(reference2) - FLOAT_EXPANSION_E_64,
expandGLFloatToInteger(reference3) - FLOAT_EXPANSION_E_64};
const GLint64 referenceAsGLintMax[] = {expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E_64,
expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E_64,
expandGLFloatToInteger(reference2) + FLOAT_EXPANSION_E_64,
expandGLFloatToInteger(reference3) + FLOAT_EXPANSION_E_64};
if (floatVector4[0] < referenceAsGLintMin[0] || floatVector4[0] > referenceAsGLintMax[0] ||
floatVector4[1] < referenceAsGLintMin[1] || floatVector4[1] > referenceAsGLintMax[1] ||
floatVector4[2] < referenceAsGLintMin[2] || floatVector4[2] > referenceAsGLintMax[2] ||
floatVector4[3] < referenceAsGLintMin[3] || floatVector4[3] > referenceAsGLintMax[3])
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected in ranges "
<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "], "
<< "[" << toHex(referenceAsGLintMin[2]) << " " << toHex(referenceAsGLintMax[2]) << "], "
<< "[" << toHex(referenceAsGLintMin[3]) << " " << toHex(referenceAsGLintMax[3]) << "]"
<< "; got " << toHex(floatVector4[0]) << ", " << toHex(floatVector4[1]) << ", "
<< toHex(floatVector4[2]) << ", " << toHex(floatVector4[3]) << " " << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
void GetInteger64Verifier::verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLint64[2]> range;
glGetInteger64v(name, range);
if (!range.verifyValidity(testCtx))
return;
const GLint64 testRangeAsGLint[] = {StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint64>(min),
StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(max)};
// check if test range outside of gl state range
if (testRangeAsGLint[0] < range[0] || testRangeAsGLint[1] > range[1])
{
testCtx.getLog() << TestLog::Message << "// ERROR: range [" << testRangeAsGLint[0] << ", "
<< testRangeAsGLint[1] << "]"
<< " is not in range [" << range[0] << ", " << range[1] << "]" << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer range");
}
}
void GetInteger64Verifier::verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLint64> state;
glGetInteger64v(name, &state);
if (!state.verifyValidity(testCtx))
return;
const GLint64 referenceAsInt = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(reference);
if (state < referenceAsInt)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected expected greater or equal to " << referenceAsInt
<< "; got " << state << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
}
}
//GetFloatVerifier
class GetFloatVerifier : public StateVerifier
{
public:
GetFloatVerifier(const glw::Functions &gl, tcu::TestLog &log);
void verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
void verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
void verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
void verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1,
GLfloat reference2, GLfloat reference3);
void verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max);
void verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat reference);
};
GetFloatVerifier::GetFloatVerifier(const glw::Functions &gl, tcu::TestLog &log) : StateVerifier(gl, log, "_getfloat")
{
}
void GetFloatVerifier::verifyFloat(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLfloat> state;
glGetFloatv(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 float value");
}
}
void GetFloatVerifier::verifyFloatExpanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
verifyFloat(testCtx, name, reference);
}
void GetFloatVerifier::verifyFloat2Expanded(tcu::TestContext &testCtx, GLenum name, GLfloat reference0,
GLfloat reference1)
{
DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLfloat[2]> floatVector2;
glGetFloatv(name, floatVector2);
if (!floatVector2.verifyValidity(testCtx))
return;
if (floatVector2[0] != reference0 || floatVector2[1] != reference1)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference0 << ", " << 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::verifyFloat4Color(tcu::TestContext &testCtx, GLenum name, GLfloat reference0, GLfloat reference1,
GLfloat reference2, GLfloat reference3)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLfloat[4]> floatVector4;
glGetFloatv(name, floatVector4);
if (!floatVector4.verifyValidity(testCtx))
return;
if (floatVector4[0] != reference0 || floatVector4[1] != reference1 || floatVector4[2] != reference2 ||
floatVector4[3] != reference3)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference0 << ", " << reference1 << ", "
<< reference2 << ", " << reference3 << "; got " << floatVector4[0] << ", " << floatVector4[1]
<< ", " << floatVector4[2] << ", " << floatVector4[3] << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
}
}
void GetFloatVerifier::verifyFloatRange(tcu::TestContext &testCtx, GLenum name, GLfloat min, GLfloat max)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLfloat[2]> floatVector2;
glGetFloatv(name, floatVector2);
if (!floatVector2.verifyValidity(testCtx))
return;
if (floatVector2[0] > min || floatVector2[1] < max)
{
testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << min << ", " << max << "]; got ["
<< floatVector2[0] << " " << floatVector2[1] << "]" << TestLog::EndMessage;
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float range");
}
}
void GetFloatVerifier::verifyFloatGreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLfloat reference)
{
using tcu::TestLog;
StateQueryMemoryWriteGuard<GLfloat> state;
glGetFloatv(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 float value");
}
}
} // namespace FloatStateQueryVerifiers
namespace
{
using namespace FloatStateQueryVerifiers;
class DepthRangeCase : public ApiCase
{
public:
DepthRangeCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
de::Random rnd(0xabcdef);
m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, 0.0f, 1.0f);
expectError(GL_NO_ERROR);
const struct FixedTest
{
float n, f;
} fixedTests[] = {{0.5f, 1.0f}, {0.0f, 0.5f}, {0.0f, 0.0f}, {1.0f, 1.0f}};
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
{
glDepthRangef(fixedTests[ndx].n, fixedTests[ndx].f);
m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, fixedTests[ndx].n, fixedTests[ndx].f);
expectError(GL_NO_ERROR);
}
const int numIterations = 120;
for (int i = 0; i < numIterations; ++i)
{
GLfloat n = rnd.getFloat(0, 1);
GLfloat f = rnd.getFloat(0, 1);
glDepthRangef(n, f);
m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, n, f);
expectError(GL_NO_ERROR);
}
}
private:
StateVerifier *m_verifier;
};
class LineWidthCase : public ApiCase
{
public:
LineWidthCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
de::Random rnd(0xabcdef);
m_verifier->verifyFloat(m_testCtx, GL_LINE_WIDTH, 1.0f);
expectError(GL_NO_ERROR);
GLfloat range[2] = {1};
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
expectError(GL_NO_ERROR);
const int numIterations = 120;
for (int i = 0; i < numIterations; ++i)
{
const GLfloat reference = rnd.getFloat(range[0], range[1]);
glLineWidth(reference);
m_verifier->verifyFloat(m_testCtx, GL_LINE_WIDTH, reference);
expectError(GL_NO_ERROR);
}
}
private:
StateVerifier *m_verifier;
};
class PolygonOffsetFactorCase : public ApiCase
{
public:
PolygonOffsetFactorCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
de::Random rnd(0xabcdef);
m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, 0.0f);
expectError(GL_NO_ERROR);
const float fixedTests[] = {0.0f, 0.5f, -0.5f, 1.5f};
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
{
glPolygonOffset(fixedTests[ndx], 0);
m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, fixedTests[ndx]);
expectError(GL_NO_ERROR);
}
const int numIterations = 120;
for (int i = 0; i < numIterations; ++i)
{
const GLfloat reference = rnd.getFloat(-64000, 64000);
glPolygonOffset(reference, 0);
m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, reference);
expectError(GL_NO_ERROR);
}
}
private:
StateVerifier *m_verifier;
};
class PolygonOffsetUnitsCase : public ApiCase
{
public:
PolygonOffsetUnitsCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
de::Random rnd(0xabcdef);
m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, 0.0f);
expectError(GL_NO_ERROR);
const float fixedTests[] = {0.0f, 0.5f, -0.5f, 1.5f};
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
{
glPolygonOffset(0, fixedTests[ndx]);
m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, fixedTests[ndx]);
expectError(GL_NO_ERROR);
}
const int numIterations = 120;
for (int i = 0; i < numIterations; ++i)
{
const GLfloat reference = rnd.getFloat(-64000, 64000);
glPolygonOffset(0, reference);
m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, reference);
expectError(GL_NO_ERROR);
}
}
private:
StateVerifier *m_verifier;
};
class SampleCoverageCase : public ApiCase
{
public:
SampleCoverageCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
de::Random rnd(0xabcdef);
m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, 1.0f);
expectError(GL_NO_ERROR);
{
const float fixedTests[] = {0.0f, 0.5f, 0.45f, 0.55f};
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
{
glSampleCoverage(fixedTests[ndx], GL_FALSE);
m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, fixedTests[ndx]);
expectError(GL_NO_ERROR);
}
}
{
const float clampTests[] = {-1.0f, -1.5f, 1.45f, 3.55f};
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(clampTests); ++ndx)
{
glSampleCoverage(clampTests[ndx], GL_FALSE);
m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, de::clamp(clampTests[ndx], 0.0f, 1.0f));
expectError(GL_NO_ERROR);
}
}
{
const int numIterations = 120;
for (int i = 0; i < numIterations; ++i)
{
GLfloat reference = rnd.getFloat(0, 1);
GLboolean invert = rnd.getBool() ? GL_TRUE : GL_FALSE;
glSampleCoverage(reference, invert);
m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, reference);
expectError(GL_NO_ERROR);
}
}
}
private:
StateVerifier *m_verifier;
};
class BlendColorCase : public ApiCase
{
public:
BlendColorCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
de::Random rnd(0xabcdef);
m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, 0, 0, 0, 0);
expectError(GL_NO_ERROR);
const struct FixedTest
{
float r, g, b, a;
} fixedTests[] = {
{0.5f, 1.0f, 0.5f, 1.0f},
{0.0f, 0.5f, 0.0f, 0.5f},
{0.0f, 0.0f, 0.0f, 0.0f},
{1.0f, 1.0f, 1.0f, 1.0f},
};
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
{
glBlendColor(fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, fixedTests[ndx].r, fixedTests[ndx].g,
fixedTests[ndx].b, fixedTests[ndx].a);
expectError(GL_NO_ERROR);
}
const int numIterations = 120;
for (int i = 0; i < numIterations; ++i)
{
const GLfloat r = rnd.getFloat(0, 1);
const GLfloat g = rnd.getFloat(0, 1);
const GLfloat b = rnd.getFloat(0, 1);
const GLfloat a = rnd.getFloat(0, 1);
glBlendColor(r, g, b, a);
m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, r, g, b, a);
expectError(GL_NO_ERROR);
}
}
private:
StateVerifier *m_verifier;
};
class ColorClearCase : public ApiCase
{
public:
ColorClearCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
de::Random rnd(0xabcdef);
// \note Initial color clear value check is temorarily removed. (until the framework does not alter it)
//m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, 0, 0, 0, 0);
//expectError(GL_NO_ERROR);
const struct FixedTest
{
float r, g, b, a;
} fixedTests[] = {
{0.5f, 1.0f, 0.5f, 1.0f},
{0.0f, 0.5f, 0.0f, 0.5f},
{0.0f, 0.0f, 0.0f, 0.0f},
{1.0f, 1.0f, 1.0f, 1.0f},
};
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
{
glClearColor(fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, fixedTests[ndx].r, fixedTests[ndx].g,
fixedTests[ndx].b, fixedTests[ndx].a);
expectError(GL_NO_ERROR);
}
const int numIterations = 120;
for (int i = 0; i < numIterations; ++i)
{
const GLfloat r = rnd.getFloat(0, 1);
const GLfloat g = rnd.getFloat(0, 1);
const GLfloat b = rnd.getFloat(0, 1);
const GLfloat a = rnd.getFloat(0, 1);
glClearColor(r, g, b, a);
m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, r, g, b, a);
expectError(GL_NO_ERROR);
}
}
private:
StateVerifier *m_verifier;
};
class DepthClearCase : public ApiCase
{
public:
DepthClearCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
de::Random rnd(0xabcdef);
m_verifier->verifyFloatExpanded(m_testCtx, GL_DEPTH_CLEAR_VALUE, 1);
expectError(GL_NO_ERROR);
const int numIterations = 120;
for (int i = 0; i < numIterations; ++i)
{
const GLfloat ref = rnd.getFloat(0, 1);
glClearDepthf(ref);
m_verifier->verifyFloatExpanded(m_testCtx, GL_DEPTH_CLEAR_VALUE, ref);
expectError(GL_NO_ERROR);
}
}
private:
StateVerifier *m_verifier;
};
class MaxTextureLODBiasCase : public ApiCase
{
public:
MaxTextureLODBiasCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
m_verifier->verifyFloatGreaterOrEqual(m_testCtx, GL_MAX_TEXTURE_LOD_BIAS, 2.0f);
expectError(GL_NO_ERROR);
}
private:
StateVerifier *m_verifier;
};
class AliasedPointSizeRangeCase : public ApiCase
{
public:
AliasedPointSizeRangeCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
m_verifier->verifyFloatRange(m_testCtx, GL_ALIASED_POINT_SIZE_RANGE, 1, 1);
expectError(GL_NO_ERROR);
}
private:
StateVerifier *m_verifier;
};
class AliasedLineWidthRangeCase : public ApiCase
{
public:
AliasedLineWidthRangeCase(Context &context, StateVerifier *verifier, const char *name, const char *description)
: ApiCase(context, name, description)
, m_verifier(verifier)
{
}
void test(void)
{
m_verifier->verifyFloatRange(m_testCtx, GL_ALIASED_LINE_WIDTH_RANGE, 1, 1);
expectError(GL_NO_ERROR);
}
private:
StateVerifier *m_verifier;
};
#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)
} // namespace
FloatStateQueryTests::FloatStateQueryTests(Context &context)
: TestCaseGroup(context, "floats", "Float Values")
, m_verifierBoolean(DE_NULL)
, m_verifierInteger(DE_NULL)
, m_verifierInteger64(DE_NULL)
, m_verifierFloat(DE_NULL)
{
}
FloatStateQueryTests::~FloatStateQueryTests(void)
{
deinit();
}
void FloatStateQueryTests::init(void)
{
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());
StateVerifier *verifiers[] = {m_verifierBoolean, m_verifierInteger, m_verifierInteger64, m_verifierFloat};
FOR_EACH_VERIFIER(verifiers,
addChild(new DepthRangeCase(m_context, verifier,
(std::string("depth_range") + verifier->getTestNamePostfix()).c_str(),
"DEPTH_RANGE")));
FOR_EACH_VERIFIER(verifiers,
addChild(new LineWidthCase(m_context, verifier,
(std::string("line_width") + verifier->getTestNamePostfix()).c_str(),
"LINE_WIDTH")));
FOR_EACH_VERIFIER(verifiers, addChild(new PolygonOffsetFactorCase(
m_context, verifier,
(std::string("polygon_offset_factor") + verifier->getTestNamePostfix()).c_str(),
"POLYGON_OFFSET_FACTOR")));
FOR_EACH_VERIFIER(verifiers, addChild(new PolygonOffsetUnitsCase(
m_context, verifier,
(std::string("polygon_offset_units") + verifier->getTestNamePostfix()).c_str(),
"POLYGON_OFFSET_UNITS")));
FOR_EACH_VERIFIER(verifiers, addChild(new SampleCoverageCase(
m_context, verifier,
(std::string("sample_coverage_value") + verifier->getTestNamePostfix()).c_str(),
"SAMPLE_COVERAGE_VALUE")));
FOR_EACH_VERIFIER(verifiers,
addChild(new BlendColorCase(m_context, verifier,
(std::string("blend_color") + verifier->getTestNamePostfix()).c_str(),
"BLEND_COLOR")));
FOR_EACH_VERIFIER(
verifiers, addChild(new ColorClearCase(
m_context, verifier, (std::string("color_clear_value") + verifier->getTestNamePostfix()).c_str(),
"COLOR_CLEAR_VALUE")));
FOR_EACH_VERIFIER(
verifiers, addChild(new DepthClearCase(
m_context, verifier, (std::string("depth_clear_value") + verifier->getTestNamePostfix()).c_str(),
"DEPTH_CLEAR_VALUE")));
FOR_EACH_VERIFIER(verifiers, addChild(new MaxTextureLODBiasCase(
m_context, verifier,
(std::string("max_texture_lod_bias") + verifier->getTestNamePostfix()).c_str(),
"MAX_TEXTURE_LOD_BIAS")));
FOR_EACH_VERIFIER(verifiers, addChild(new AliasedPointSizeRangeCase(
m_context, verifier,
(std::string("aliased_point_size_range") + verifier->getTestNamePostfix()).c_str(),
"ALIASED_POINT_SIZE_RANGE")));
FOR_EACH_VERIFIER(verifiers, addChild(new AliasedLineWidthRangeCase(
m_context, verifier,
(std::string("aliased_line_width_range") + verifier->getTestNamePostfix()).c_str(),
"ALIASED_LINE_WIDTH_RANGE")));
}
void FloatStateQueryTests::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