class LimitCase : public deqp::TestCase
{
public:
- LimitCase(deqp::Context& context, const char* caseName, deUint32 limitToken, DataType limitBoundry,
- bool isBoundryMaximum, const char* glslVersion = "", const char* glslBuiltin = "",
+ LimitCase(deqp::Context& context, const char* caseName, deUint32 limitToken, DataType limitBoundary,
+ bool isBoundaryMaximum, const char* glslVersion = "", const char* glslBuiltin = "",
const char* glslExtension = "");
virtual ~LimitCase(void);
tcu::TestNode::IterateResult iterate(void);
protected:
- bool isWithinBoundry(DataType value, bool isBuiltin = false) const;
+ bool isWithinBoundary(DataType value, bool isBuiltin = false) const;
std::string createShader() const;
// those functions require specialization for some data types
LimitCase(const LimitCase&); // not allowed!
LimitCase& operator=(const LimitCase&); // not allowed!
+ void adjustBoundaryForMaxFragmentInterpolationOffset();
+
deUint32 m_limitToken;
- DataType m_limitBoundry; // min/max value
- bool m_isBoundryMaximum;
+ DataType m_limitBoundary; // min/max value
+ bool m_isBoundaryMaximum;
const std::string m_glslVersion;
const std::string m_glslBuiltin;
const std::string m_glslExtension;
LimitCase<DataType>::LimitCase(deqp::Context& context,
const char* caseName,
deUint32 limitToken,
- DataType limitBoundry,
- bool isBoundryMaximum,
+ DataType limitBoundary,
+ bool isBoundaryMaximum,
const char* glslVersion,
const char* glslBuiltin,
const char* glslExtension)
: deqp::TestCase(context, caseName, "Token limit validation.")
, m_limitToken(limitToken)
- , m_limitBoundry(limitBoundry)
- , m_isBoundryMaximum(isBoundryMaximum)
+ , m_limitBoundary(limitBoundary)
+ , m_isBoundaryMaximum(isBoundaryMaximum)
, m_glslVersion(glslVersion)
, m_glslBuiltin(glslBuiltin)
, m_glslExtension(glslExtension)
{
+ // GL_MAX_FRAGMENT_INTERPOLATION_OFFSET is special in that its limit is dependent on
+ // GL_FRAGMENT_INTERPOLATION_OFFSET_BITS. Adjust the limit automatically here.
+ adjustBoundaryForMaxFragmentInterpolationOffset();
}
template<typename DataType>
}
template<typename DataType>
+void LimitCase<DataType>::adjustBoundaryForMaxFragmentInterpolationOffset()
+{
+}
+
+template<>
+void LimitCase<GLfloat>::adjustBoundaryForMaxFragmentInterpolationOffset()
+{
+ if (m_limitToken == GL_MAX_FRAGMENT_INTERPOLATION_OFFSET)
+ {
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ GLfloat fragmentInterpolationOffsetBits = 0;
+ gl.getFloatv(GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, &fragmentInterpolationOffsetBits);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");
+
+ GLfloat ULP = 1.0f / powf(2, fragmentInterpolationOffsetBits);
+ m_limitBoundary -= ULP;
+ }
+}
+
+template<typename DataType>
tcu::TestNode::IterateResult LimitCase<DataType>::iterate(void)
{
DataType limitValue = DataType();
// check if limit was specified
if (m_limitToken)
{
- // check if limit is not smaller or greater then boundry defined in specification
+ // check if limit is not smaller or greater then boundary defined in specification
limitValue = getLimitValue(gl);
- if (!isWithinBoundry(limitValue))
+ if (!isWithinBoundary(limitValue))
{
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
return STOP;
m_testCtx.getLog() << tcu::TestLog::Message
<< "Shader builtin has value: "
<< builtinValue
- << " which is different then the value of corresponding limit: "
+ << " which is different from the value of corresponding limit: "
<< limitValue
<< tcu::TestLog::EndMessage;
}
}
else
{
- // limit token was not specified - compare builtin to the boundry
- if (isWithinBoundry(builtinValue, true))
+ // limit token was not specified - compare builtin to the boundary
+ if (isWithinBoundary(builtinValue, true))
{
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}
m_testCtx.getLog() << tcu::TestLog::Message
<< "Shader builtin value is: "
<< builtinValue
- << " which is outside of specified boundry."
+ << " which is outside of specified boundary."
<< tcu::TestLog::EndMessage;
}
}
}
template<typename DataType>
-bool LimitCase<DataType>::isWithinBoundry(DataType value, bool isBuiltin) const
+bool LimitCase<DataType>::isWithinBoundary(DataType value, bool isBuiltin) const
{
- if (m_isBoundryMaximum)
+ if (m_isBoundaryMaximum)
{
- // value should be smaller or euqual to boundry
- if (isGreater(value, m_limitBoundry))
+ // value should be smaller or euqual to boundary
+ if (isGreater(value, m_limitBoundary))
{
m_testCtx.getLog() << tcu::TestLog::Message
<< (isBuiltin ? "Builtin" : "Limit")
<< " value is: "
<< value
<< " when it should not be greater than "
- << m_limitBoundry
+ << m_limitBoundary
<< tcu::TestLog::EndMessage;
return false;
}
}
else
{
- // value should be greater or euqual to boundry
- if (isSmaller(value, m_limitBoundry))
+ // value should be greater or euqual to boundary
+ if (isSmaller(value, m_limitBoundary))
{
m_testCtx.getLog() << tcu::TestLog::Message
<< (isBuiltin ? "Builtin" : "Limit")
<< " value is: "
<< value
<< "when it should not be smaller than "
- << m_limitBoundry
+ << m_limitBoundary
<< tcu::TestLog::EndMessage;
return false;
}
gl.enableLogging(true);
if (m_testType == TEST_MAX_OFFSET)
- verifyStateFloatMin(result, gl, GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, 0.5, m_verifier);
+ {
+ glw::GLfloat fragmentInterpolationOffsetBits = 0.0;
+ gl.glGetFloatv(GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, &fragmentInterpolationOffsetBits);
+ GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv");
+
+ glw::GLfloat ULP = 1.0f / powf(2, fragmentInterpolationOffsetBits);
+
+ verifyStateFloatMin(result, gl, GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, 0.5f-ULP, m_verifier);
+ }
else if (m_testType == TEST_MIN_OFFSET)
- verifyStateFloatMax(result, gl, GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, -0.5, m_verifier);
+ verifyStateFloatMax(result, gl, GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, -0.5f, m_verifier);
else
DE_ASSERT(false);