You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1317 lines
44 KiB
1317 lines
44 KiB
/*------------------------------------------------------------------------- |
|
* 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()); |
|
} |
|
|
|
} // anonymous |
|
|
|
// 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"); |
|
} |
|
} |
|
|
|
|
|
} // 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) \ |
|
for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++) \ |
|
{ \ |
|
StateVerifier* verifier = (VERIFIERS)[_verifierNdx]; \ |
|
CODE_BLOCK; \ |
|
} |
|
|
|
} // anonymous |
|
|
|
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(); |
|
} |
|
|
|
} // Functional |
|
} // gles3 |
|
} // deqp
|
|
|