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.
3069 lines
114 KiB
3069 lines
114 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 State Query tests.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es3fIntegerStateQueryTests.hpp"
|
|
#include "es3fApiCase.hpp"
|
|
|
|
#include "glsStateQueryUtil.hpp"
|
|
|
|
#include "gluRenderContext.hpp"
|
|
#include "gluContextInfo.hpp"
|
|
#include "gluStrUtil.hpp"
|
|
|
|
#include "tcuRenderTarget.hpp"
|
|
|
|
#include "deRandom.hpp"
|
|
|
|
#include "glwEnums.hpp"
|
|
|
|
using namespace glw; // GLint and other GL types
|
|
using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
|
|
|
|
#ifndef GL_SLUMINANCE_NV
|
|
#define GL_SLUMINANCE_NV 0x8C46
|
|
#endif
|
|
#ifndef GL_SLUMINANCE_ALPHA_NV
|
|
#define GL_SLUMINANCE_ALPHA_NV 0x8C44
|
|
#endif
|
|
#ifndef GL_BGR_NV
|
|
#define GL_BGR_NV 0x80E0
|
|
#endif
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles3
|
|
{
|
|
namespace Functional
|
|
{
|
|
namespace IntegerStateQueryVerifiers
|
|
{
|
|
|
|
// StateVerifier
|
|
|
|
class StateVerifier : protected glu::CallLogWrapper
|
|
{
|
|
public:
|
|
StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
|
|
virtual ~StateVerifier (); // make GCC happy
|
|
|
|
const char* getTestNamePostfix (void) const;
|
|
|
|
virtual void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference) = DE_NULL;
|
|
virtual void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3) = DE_NULL;
|
|
virtual void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3) = DE_NULL;
|
|
virtual void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) = DE_NULL;
|
|
virtual void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference) = DE_NULL;
|
|
virtual void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference) = DE_NULL;
|
|
virtual void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1) = DE_NULL;
|
|
virtual void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength) = DE_NULL;
|
|
virtual void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits) = DE_NULL;
|
|
|
|
private:
|
|
const char* const m_testNamePostfix;
|
|
};
|
|
|
|
StateVerifier::StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
|
|
: glu::CallLogWrapper (gl, log)
|
|
, m_testNamePostfix (testNamePostfix)
|
|
{
|
|
enableLogging(true);
|
|
}
|
|
|
|
StateVerifier::~StateVerifier ()
|
|
{
|
|
}
|
|
|
|
const char* StateVerifier::getTestNamePostfix (void) const
|
|
{
|
|
return m_testNamePostfix;
|
|
}
|
|
|
|
// GetBooleanVerifier
|
|
|
|
class GetBooleanVerifier : public StateVerifier
|
|
{
|
|
public:
|
|
GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log);
|
|
void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3);
|
|
void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3);
|
|
void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference);
|
|
void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1);
|
|
void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength);
|
|
void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits);
|
|
};
|
|
|
|
GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log)
|
|
: StateVerifier(gl, log, "_getboolean")
|
|
{
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLboolean> state;
|
|
glGetBooleanv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
const GLboolean expectedGLState = reference ? GL_TRUE : GL_FALSE;
|
|
|
|
if (state != expectedGLState)
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (expectedGLState==GL_TRUE ? "GL_TRUE" : "GL_FALSE") << "; got " << (state == GL_TRUE ? "GL_TRUE" : (state == GL_FALSE ? "GL_FALSE" : "non-boolean")) << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3)
|
|
{
|
|
verifyInteger4Mask(testCtx, name, reference0, true, reference1, true, reference2, true, reference3, true);
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLboolean[4]> boolVector4;
|
|
glGetBooleanv(name, boolVector4);
|
|
|
|
if (!boolVector4.verifyValidity(testCtx))
|
|
return;
|
|
|
|
const GLboolean referenceAsGLBoolean[] =
|
|
{
|
|
reference0 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE,
|
|
reference1 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE,
|
|
reference2 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE,
|
|
reference3 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE,
|
|
};
|
|
|
|
if ((enableRef0 && (boolVector4[0] != referenceAsGLBoolean[0])) ||
|
|
(enableRef1 && (boolVector4[1] != referenceAsGLBoolean[1])) ||
|
|
(enableRef2 && (boolVector4[2] != referenceAsGLBoolean[2])) ||
|
|
(enableRef3 && (boolVector4[3] != referenceAsGLBoolean[3])))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected "
|
|
<< (enableRef0 ? (referenceAsGLBoolean[0] ? "GL_TRUE" : "GL_FALSE") : " - ") << ", "
|
|
<< (enableRef1 ? (referenceAsGLBoolean[1] ? "GL_TRUE" : "GL_FALSE") : " - ") << ", "
|
|
<< (enableRef2 ? (referenceAsGLBoolean[2] ? "GL_TRUE" : "GL_FALSE") : " - ") << ", "
|
|
<< (enableRef3 ? (referenceAsGLBoolean[3] ? "GL_TRUE" : "GL_FALSE") : " - ") << TestLog::EndMessage;
|
|
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLboolean> state;
|
|
glGetBooleanv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state == GL_TRUE) // state is non-zero, could be greater than reference (correct)
|
|
return;
|
|
|
|
if (state == GL_FALSE) // state is zero
|
|
{
|
|
if (reference > 0) // and reference is greater than zero?
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLboolean> state;
|
|
glGetBooleanv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state == GL_TRUE) // state is non-zero, could be greater than reference (correct)
|
|
return;
|
|
|
|
if (state == GL_FALSE) // state is zero
|
|
{
|
|
if (reference > 0) // and reference is greater than zero?
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLboolean> state;
|
|
glGetBooleanv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state == GL_TRUE) // state is non-zero, could be less than reference (correct)
|
|
return;
|
|
|
|
if (state == GL_FALSE) // state is zero
|
|
{
|
|
if (reference < 0) // and reference is less than zero?
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLboolean[2]> boolVector;
|
|
glGetBooleanv(name, boolVector);
|
|
|
|
if (!boolVector.verifyValidity(testCtx))
|
|
return;
|
|
|
|
const GLboolean referenceAsGLBoolean[2] =
|
|
{
|
|
reference0 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE,
|
|
reference1 ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE
|
|
};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(referenceAsGLBoolean); ++ndx)
|
|
{
|
|
if (boolVector[ndx] == GL_TRUE) // state is non-zero, could be greater than any integer
|
|
{
|
|
continue;
|
|
}
|
|
else if (boolVector[ndx] == GL_FALSE) // state is zero
|
|
{
|
|
if (referenceAsGLBoolean[ndx] > 0) // and reference is greater than zero?
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLboolean> state;
|
|
glGetBooleanv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
for (size_t ndx = 0; ndx < referencesLength; ++ndx)
|
|
{
|
|
const GLboolean expectedGLState = references[ndx] ? GL_TRUE : GL_FALSE;
|
|
|
|
if (state == expectedGLState)
|
|
return;
|
|
}
|
|
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: got " << (state==GL_TRUE ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
|
|
void GetBooleanVerifier::verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits)
|
|
{
|
|
// if stencilBits == 0, the mask is allowed to be either GL_TRUE or GL_FALSE
|
|
// otherwise it must be GL_TRUE
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLboolean> state;
|
|
glGetBooleanv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (stencilBits > 0 && state != GL_TRUE)
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
|
|
}
|
|
}
|
|
|
|
//GetIntegerVerifier
|
|
|
|
class GetIntegerVerifier : public StateVerifier
|
|
{
|
|
public:
|
|
GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log);
|
|
void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3);
|
|
void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3);
|
|
void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference);
|
|
void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1);
|
|
void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength);
|
|
void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits);
|
|
};
|
|
|
|
GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log)
|
|
: StateVerifier(gl, log, "_getinteger")
|
|
{
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint> state;
|
|
glGetIntegerv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state != reference)
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3)
|
|
{
|
|
verifyInteger4Mask(testCtx, name, reference0, true, reference1, true, reference2, true, reference3, true);
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint[4]> intVector4;
|
|
glGetIntegerv(name, intVector4);
|
|
|
|
if (!intVector4.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if ((enableRef0 && (intVector4[0] != reference0)) ||
|
|
(enableRef1 && (intVector4[1] != reference1)) ||
|
|
(enableRef2 && (intVector4[2] != reference2)) ||
|
|
(enableRef3 && (intVector4[3] != reference3)))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected "
|
|
<< (enableRef0?"":"(") << reference0 << (enableRef0?"":")") << ", "
|
|
<< (enableRef1?"":"(") << reference1 << (enableRef1?"":")") << ", "
|
|
<< (enableRef2?"":"(") << reference2 << (enableRef2?"":")") << ", "
|
|
<< (enableRef3?"":"(") << reference3 << (enableRef3?"":")") << TestLog::EndMessage;
|
|
|
|
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint> state;
|
|
glGetIntegerv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state < reference)
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint> state;
|
|
glGetIntegerv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (GLuint(state) < reference)
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference << "; got " << GLuint(state) << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint> state;
|
|
glGetIntegerv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state > reference)
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected less or equal to " << reference << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint[2]> intVector2;
|
|
glGetIntegerv(name, intVector2);
|
|
|
|
if (!intVector2.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (intVector2[0] < reference0 || intVector2[1] < reference1)
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference0 << ", " << reference1 << "; got " << intVector2[0] << ", " << intVector2[0] << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint> state;
|
|
glGetIntegerv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
for (size_t ndx = 0; ndx < referencesLength; ++ndx)
|
|
{
|
|
const GLint expectedGLState = references[ndx];
|
|
|
|
if (state == expectedGLState)
|
|
return;
|
|
}
|
|
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
|
|
void GetIntegerVerifier::verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint> state;
|
|
glGetIntegerv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
const GLint reference = (1 << stencilBits) - 1;
|
|
|
|
if ((state & reference) != reference) // the least significant stencilBits bits should be on
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected minimum mask of " << reference << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid mask value");
|
|
}
|
|
}
|
|
|
|
//GetInteger64Verifier
|
|
|
|
class GetInteger64Verifier : public StateVerifier
|
|
{
|
|
public:
|
|
GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log);
|
|
void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3);
|
|
void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3);
|
|
void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference);
|
|
void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1);
|
|
void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength);
|
|
void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits);
|
|
};
|
|
|
|
GetInteger64Verifier::GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log)
|
|
: StateVerifier(gl, log, "_getinteger64")
|
|
{
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint64> state;
|
|
glGetInteger64v(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state != GLint64(reference))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3)
|
|
{
|
|
verifyInteger4Mask(testCtx, name, reference0, true, reference1, true, reference2, true, reference3, true);
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint64[4]> intVector4;
|
|
glGetInteger64v(name, intVector4);
|
|
|
|
if (!intVector4.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if ((enableRef0 && (intVector4[0] != GLint64(reference0))) ||
|
|
(enableRef1 && (intVector4[1] != GLint64(reference1))) ||
|
|
(enableRef2 && (intVector4[2] != GLint64(reference2))) ||
|
|
(enableRef3 && (intVector4[3] != GLint64(reference3))))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected "
|
|
<< (enableRef0?"":"(") << reference0 << (enableRef0?"":")") << ", "
|
|
<< (enableRef1?"":"(") << reference1 << (enableRef1?"":")") << ", "
|
|
<< (enableRef2?"":"(") << reference2 << (enableRef2?"":")") << ", "
|
|
<< (enableRef3?"":"(") << reference3 << (enableRef3?"":")") << TestLog::EndMessage;
|
|
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint64> state;
|
|
glGetInteger64v(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state < GLint64(reference))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLint64(reference) << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint64> state;
|
|
glGetInteger64v(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (GLuint(state) < GLint64(reference))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLint64(reference) << "; got " << GLuint(state) << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint64> state;
|
|
glGetInteger64v(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state > GLint64(reference))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected less or equal to " << GLint64(reference) << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint64[2]> intVector2;
|
|
glGetInteger64v(name, intVector2);
|
|
|
|
if (!intVector2.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (intVector2[0] < GLint64(reference0) || intVector2[1] < GLint64(reference1))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLint64(reference0) << ", " << GLint64(reference1) << "; got " << intVector2[0] << ", " << intVector2[1] << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint64> state;
|
|
glGetInteger64v(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
for (size_t ndx = 0; ndx < referencesLength; ++ndx)
|
|
{
|
|
const GLint64 expectedGLState = GLint64(references[ndx]);
|
|
|
|
if (state == expectedGLState)
|
|
return;
|
|
}
|
|
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
|
|
}
|
|
|
|
void GetInteger64Verifier::verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLint64> state;
|
|
glGetInteger64v(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
const GLint64 reference = (1ULL << stencilBits) - 1;
|
|
|
|
if ((state & reference) != reference) // the least significant stencilBits bits should be on
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected mimimum mask of " << reference << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid mask value");
|
|
}
|
|
}
|
|
|
|
//GetFloatVerifier
|
|
|
|
class GetFloatVerifier : public StateVerifier
|
|
{
|
|
public:
|
|
GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log);
|
|
void verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3);
|
|
void verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3);
|
|
void verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference);
|
|
void verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference);
|
|
void verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1);
|
|
void verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength);
|
|
void verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits);
|
|
};
|
|
|
|
GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log)
|
|
: StateVerifier(gl, log, "_getfloat")
|
|
{
|
|
}
|
|
|
|
void GetFloatVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
const GLfloat referenceAsFloat = GLfloat(reference);
|
|
DE_ASSERT(reference == GLint(referenceAsFloat)); // reference integer must have 1:1 mapping to float for this to work. Reference value is always such value in these tests
|
|
|
|
StateQueryMemoryWriteGuard<GLfloat> state;
|
|
glGetFloatv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state != referenceAsFloat)
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected " << referenceAsFloat << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
|
|
}
|
|
}
|
|
|
|
void GetFloatVerifier::verifyInteger4 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1, GLint reference2, GLint reference3)
|
|
{
|
|
verifyInteger4Mask(testCtx, name, reference0, true, reference1, true, reference2, true, reference3, true);
|
|
}
|
|
|
|
void GetFloatVerifier::verifyInteger4Mask (tcu::TestContext& testCtx, GLenum name, GLint reference0, bool enableRef0, GLint reference1, bool enableRef1, GLint reference2, bool enableRef2, GLint reference3, bool enableRef3)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLfloat[4]> floatVector4;
|
|
glGetFloatv(name, floatVector4);
|
|
|
|
if (!floatVector4.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if ((enableRef0 && (floatVector4[0] != GLfloat(reference0))) ||
|
|
(enableRef1 && (floatVector4[1] != GLfloat(reference1))) ||
|
|
(enableRef2 && (floatVector4[2] != GLfloat(reference2))) ||
|
|
(enableRef3 && (floatVector4[3] != GLfloat(reference3))))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected "
|
|
<< (enableRef0?"":"(") << GLfloat(reference0) << (enableRef0?"":")") << ", "
|
|
<< (enableRef1?"":"(") << GLfloat(reference1) << (enableRef1?"":")") << ", "
|
|
<< (enableRef2?"":"(") << GLfloat(reference2) << (enableRef2?"":")") << ", "
|
|
<< (enableRef3?"":"(") << GLfloat(reference3) << (enableRef3?"":")") << TestLog::EndMessage;
|
|
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
|
|
}
|
|
}
|
|
|
|
void GetFloatVerifier::verifyIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLfloat> state;
|
|
glGetFloatv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state < GLfloat(reference))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLfloat(reference) << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
|
|
}
|
|
}
|
|
|
|
void GetFloatVerifier::verifyUnsignedIntegerGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLfloat> state;
|
|
glGetFloatv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state < GLfloat(reference))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLfloat(reference) << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
|
|
}
|
|
}
|
|
|
|
void GetFloatVerifier::verifyIntegerLessOrEqual (tcu::TestContext& testCtx, GLenum name, GLint reference)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLfloat> state;
|
|
glGetFloatv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (state > GLfloat(reference))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected less or equal to " << GLfloat(reference) << "; got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
|
|
}
|
|
}
|
|
|
|
void GetFloatVerifier::verifyIntegerGreaterOrEqual2 (tcu::TestContext& testCtx, GLenum name, GLint reference0, GLint reference1)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLfloat[2]> floatVector2;
|
|
glGetFloatv(name, floatVector2);
|
|
|
|
if (!floatVector2.verifyValidity(testCtx))
|
|
return;
|
|
|
|
if (floatVector2[0] < GLfloat(reference0) || floatVector2[1] < GLfloat(reference1))
|
|
{
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLfloat(reference0) << ", " << GLfloat(reference1) << "; got " << floatVector2[0] << ", " << floatVector2[1] << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
|
|
}
|
|
}
|
|
|
|
void GetFloatVerifier::verifyIntegerAnyOf (tcu::TestContext& testCtx, GLenum name, const GLint references[], size_t referencesLength)
|
|
{
|
|
using tcu::TestLog;
|
|
|
|
StateQueryMemoryWriteGuard<GLfloat> state;
|
|
glGetFloatv(name, &state);
|
|
|
|
if (!state.verifyValidity(testCtx))
|
|
return;
|
|
|
|
for (size_t ndx = 0; ndx < referencesLength; ++ndx)
|
|
{
|
|
const GLfloat expectedGLState = GLfloat(references[ndx]);
|
|
DE_ASSERT(references[ndx] == GLint(expectedGLState)); // reference integer must have 1:1 mapping to float for this to work. Reference value is always such value in these tests
|
|
|
|
if (state == expectedGLState)
|
|
return;
|
|
}
|
|
|
|
testCtx.getLog() << TestLog::Message << "// ERROR: got " << state << TestLog::EndMessage;
|
|
if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
|
|
testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
|
|
}
|
|
|
|
void GetFloatVerifier::verifyStencilMaskInitial (tcu::TestContext& testCtx, GLenum name, int stencilBits)
|
|
{
|
|
// checking the mask bits with float doesn't make much sense because of conversion errors
|
|
// just verify that the value is greater or equal to the minimum value
|
|
const GLint reference = (1 << stencilBits) - 1;
|
|
verifyIntegerGreaterOrEqual(testCtx, name, reference);
|
|
}
|
|
|
|
} // IntegerStateQueryVerifiers
|
|
|
|
namespace
|
|
{
|
|
|
|
using namespace IntegerStateQueryVerifiers;
|
|
using namespace deqp::gls::StateQueryUtil;
|
|
|
|
class ConstantMinimumValueTestCase : public ApiCase
|
|
{
|
|
public:
|
|
ConstantMinimumValueTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName, GLint minValue)
|
|
: ApiCase (context, name, description)
|
|
, m_targetName (targetName)
|
|
, m_minValue (minValue)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyUnsignedIntegerGreaterOrEqual(m_testCtx, m_targetName, m_minValue);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
|
|
private:
|
|
GLenum m_targetName;
|
|
GLint m_minValue;
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class ConstantMaximumValueTestCase : public ApiCase
|
|
{
|
|
public:
|
|
ConstantMaximumValueTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName, GLint minValue)
|
|
: ApiCase (context, name, description)
|
|
, m_targetName (targetName)
|
|
, m_minValue (minValue)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyIntegerLessOrEqual(m_testCtx, m_targetName, m_minValue);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
|
|
private:
|
|
GLenum m_targetName;
|
|
GLint m_minValue;
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class SampleBuffersTestCase : public ApiCase
|
|
{
|
|
public:
|
|
SampleBuffersTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
const int expectedSampleBuffers = (m_context.getRenderTarget().getNumSamples() > 1) ? 1 : 0;
|
|
|
|
m_log << tcu::TestLog::Message << "Sample count is " << (m_context.getRenderTarget().getNumSamples()) << ", expecting GL_SAMPLE_BUFFERS to be " << expectedSampleBuffers << tcu::TestLog::EndMessage;
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_SAMPLE_BUFFERS, expectedSampleBuffers);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class SamplesTestCase : public ApiCase
|
|
{
|
|
public:
|
|
SamplesTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
// MSAA?
|
|
if (m_context.getRenderTarget().getNumSamples() > 1)
|
|
{
|
|
m_log << tcu::TestLog::Message << "Sample count is " << (m_context.getRenderTarget().getNumSamples()) << tcu::TestLog::EndMessage;
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_SAMPLES, m_context.getRenderTarget().getNumSamples());
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
else
|
|
{
|
|
const glw::GLint validSamples[] = {0, 1};
|
|
|
|
m_log << tcu::TestLog::Message << "Expecting GL_SAMPLES to be 0 or 1" << tcu::TestLog::EndMessage;
|
|
|
|
m_verifier->verifyIntegerAnyOf(m_testCtx, GL_SAMPLES, validSamples, DE_LENGTH_OF_ARRAY(validSamples));
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class HintTestCase : public ApiCase
|
|
{
|
|
public:
|
|
HintTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName)
|
|
: ApiCase (context, name, description)
|
|
, m_targetName (targetName)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, m_targetName, GL_DONT_CARE);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glHint(m_targetName, GL_NICEST);
|
|
m_verifier->verifyInteger(m_testCtx, m_targetName, GL_NICEST);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glHint(m_targetName, GL_FASTEST);
|
|
m_verifier->verifyInteger(m_testCtx, m_targetName, GL_FASTEST);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glHint(m_targetName, GL_DONT_CARE);
|
|
m_verifier->verifyInteger(m_testCtx, m_targetName, GL_DONT_CARE);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
|
|
private:
|
|
GLenum m_targetName;
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class DepthFuncTestCase : public ApiCase
|
|
{
|
|
public:
|
|
DepthFuncTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, GL_DEPTH_FUNC, GL_LESS);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const GLenum depthFunctions[] = {GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GREATER, GL_GEQUAL, GL_NOTEQUAL};
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthFunctions); ndx++)
|
|
{
|
|
glDepthFunc(depthFunctions[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_DEPTH_FUNC, depthFunctions[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class CullFaceTestCase : public ApiCase
|
|
{
|
|
public:
|
|
CullFaceTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, GL_CULL_FACE_MODE, GL_BACK);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const GLenum cullFaces[] = {GL_FRONT, GL_BACK, GL_FRONT_AND_BACK};
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cullFaces); ndx++)
|
|
{
|
|
glCullFace(cullFaces[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_CULL_FACE_MODE, cullFaces[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class FrontFaceTestCase : public ApiCase
|
|
{
|
|
public:
|
|
FrontFaceTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, GL_FRONT_FACE, GL_CCW);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const GLenum frontFaces[] = {GL_CW, GL_CCW};
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(frontFaces); ndx++)
|
|
{
|
|
glFrontFace(frontFaces[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_FRONT_FACE, frontFaces[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class ViewPortTestCase : public ApiCase
|
|
{
|
|
public:
|
|
ViewPortTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
de::Random rnd(0xabcdef);
|
|
|
|
GLint maxViewportDimensions[2] = {0};
|
|
GLfloat viewportBoundsRange[2] = {0.0f};
|
|
GLboolean hasViewportArray = false;
|
|
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, maxViewportDimensions);
|
|
hasViewportArray = m_context.getContextInfo().isExtensionSupported("GL_OES_viewport_array") ||
|
|
m_context.getContextInfo().isExtensionSupported("GL_NV_viewport_array");
|
|
if (hasViewportArray)
|
|
{
|
|
glGetFloatv(GL_VIEWPORT_BOUNDS_RANGE, viewportBoundsRange);
|
|
}
|
|
|
|
// verify initial value of first two values
|
|
m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, 0, 0, m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const int numIterations = 120;
|
|
for (int i = 0; i < numIterations; ++i)
|
|
{
|
|
GLint x = rnd.getInt(-64000, 64000);
|
|
GLint y = rnd.getInt(-64000, 64000);
|
|
GLsizei width = rnd.getInt(0, maxViewportDimensions[0]);
|
|
GLsizei height = rnd.getInt(0, maxViewportDimensions[1]);
|
|
|
|
glViewport(x, y, width, height);
|
|
|
|
if (hasViewportArray)
|
|
{
|
|
m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT,
|
|
de::clamp(x, deFloorFloatToInt32(viewportBoundsRange[0]), deFloorFloatToInt32(viewportBoundsRange[1])),
|
|
de::clamp(y, deFloorFloatToInt32(viewportBoundsRange[0]), deFloorFloatToInt32(viewportBoundsRange[1])),
|
|
width, height);
|
|
}
|
|
else
|
|
{
|
|
m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, x, y, width, height);
|
|
}
|
|
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class ScissorBoxTestCase : public ApiCase
|
|
{
|
|
public:
|
|
ScissorBoxTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
de::Random rnd(0xabcdef);
|
|
|
|
// verify initial value of first two values
|
|
m_verifier->verifyInteger4Mask(m_testCtx, GL_SCISSOR_BOX, 0, true, 0, true, 0, false, 0, false);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const int numIterations = 120;
|
|
for (int i = 0; i < numIterations; ++i)
|
|
{
|
|
GLint left = rnd.getInt(-64000, 64000);
|
|
GLint bottom = rnd.getInt(-64000, 64000);
|
|
GLsizei width = rnd.getInt(0, 64000);
|
|
GLsizei height = rnd.getInt(0, 64000);
|
|
|
|
glScissor(left, bottom, width, height);
|
|
m_verifier->verifyInteger4(m_testCtx, GL_SCISSOR_BOX, left, bottom, width, height);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class MaxViewportDimsTestCase : public ApiCase
|
|
{
|
|
public:
|
|
MaxViewportDimsTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyIntegerGreaterOrEqual2(m_testCtx, GL_MAX_VIEWPORT_DIMS, m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class StencilRefTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilRefTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, 0);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const int stencilBits = m_context.getRenderTarget().getStencilBits();
|
|
|
|
for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit)
|
|
{
|
|
const int ref = 1 << stencilBit;
|
|
|
|
glStencilFunc(GL_ALWAYS, ref, 0); // mask should not affect the REF
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, ref);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glStencilFunc(GL_ALWAYS, ref, ref);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, ref);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
};
|
|
|
|
class StencilRefSeparateTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilRefSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, GLenum stencilFuncTargetFace)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
, m_stencilFuncTargetFace (stencilFuncTargetFace)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, 0);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const int stencilBits = m_context.getRenderTarget().getStencilBits();
|
|
|
|
for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit)
|
|
{
|
|
const int ref = 1 << stencilBit;
|
|
|
|
glStencilFuncSeparate(m_stencilFuncTargetFace, GL_ALWAYS, ref, 0);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, ref);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glStencilFuncSeparate(m_stencilFuncTargetFace, GL_ALWAYS, ref, ref);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, ref);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
GLenum m_stencilFuncTargetFace;
|
|
};
|
|
|
|
class StencilOpTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilOpTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum stencilOpName)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_stencilOpName (stencilOpName)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, m_stencilOpName, GL_KEEP);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const GLenum stencilOpValues[] = {GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilOpValues); ++ndx)
|
|
{
|
|
SetStencilOp(stencilOpValues[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_stencilOpName, stencilOpValues[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
protected:
|
|
virtual void SetStencilOp (GLenum stencilOpValue)
|
|
{
|
|
switch (m_stencilOpName)
|
|
{
|
|
case GL_STENCIL_FAIL:
|
|
case GL_STENCIL_BACK_FAIL:
|
|
glStencilOp(stencilOpValue, GL_KEEP, GL_KEEP);
|
|
break;
|
|
|
|
case GL_STENCIL_PASS_DEPTH_FAIL:
|
|
case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
|
|
glStencilOp(GL_KEEP, stencilOpValue, GL_KEEP);
|
|
break;
|
|
|
|
case GL_STENCIL_PASS_DEPTH_PASS:
|
|
case GL_STENCIL_BACK_PASS_DEPTH_PASS:
|
|
glStencilOp(GL_KEEP, GL_KEEP, stencilOpValue);
|
|
break;
|
|
|
|
default:
|
|
DE_ASSERT(false && "should not happen");
|
|
break;
|
|
}
|
|
}
|
|
|
|
StateVerifier* m_verifier;
|
|
GLenum m_stencilOpName;
|
|
};
|
|
|
|
|
|
class StencilOpSeparateTestCase : public StencilOpTestCase
|
|
{
|
|
public:
|
|
StencilOpSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum stencilOpName, GLenum stencilOpFace)
|
|
: StencilOpTestCase (context, verifier, name, description, stencilOpName)
|
|
, m_stencilOpFace (stencilOpFace)
|
|
{
|
|
}
|
|
|
|
private:
|
|
void SetStencilOp (GLenum stencilOpValue)
|
|
{
|
|
switch (m_stencilOpName)
|
|
{
|
|
case GL_STENCIL_FAIL:
|
|
case GL_STENCIL_BACK_FAIL:
|
|
glStencilOpSeparate(m_stencilOpFace, stencilOpValue, GL_KEEP, GL_KEEP);
|
|
break;
|
|
|
|
case GL_STENCIL_PASS_DEPTH_FAIL:
|
|
case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
|
|
glStencilOpSeparate(m_stencilOpFace, GL_KEEP, stencilOpValue, GL_KEEP);
|
|
break;
|
|
|
|
case GL_STENCIL_PASS_DEPTH_PASS:
|
|
case GL_STENCIL_BACK_PASS_DEPTH_PASS:
|
|
glStencilOpSeparate(m_stencilOpFace, GL_KEEP, GL_KEEP, stencilOpValue);
|
|
break;
|
|
|
|
default:
|
|
DE_ASSERT(false && "should not happen");
|
|
break;
|
|
}
|
|
}
|
|
|
|
GLenum m_stencilOpFace;
|
|
};
|
|
|
|
class StencilFuncTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilFuncTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, GL_STENCIL_FUNC, GL_ALWAYS);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const GLenum stencilfuncValues[] = {GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilfuncValues); ++ndx)
|
|
{
|
|
glStencilFunc(stencilfuncValues[ndx], 0, 0);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_STENCIL_FUNC, stencilfuncValues[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_STENCIL_BACK_FUNC, stencilfuncValues[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class StencilFuncSeparateTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilFuncSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum stencilFuncName, GLenum stencilFuncFace)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_stencilFuncName (stencilFuncName)
|
|
, m_stencilFuncFace (stencilFuncFace)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, m_stencilFuncName, GL_ALWAYS);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const GLenum stencilfuncValues[] = {GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilfuncValues); ++ndx)
|
|
{
|
|
glStencilFuncSeparate(m_stencilFuncFace, stencilfuncValues[ndx], 0, 0);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_stencilFuncName, stencilfuncValues[ndx]);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_stencilFuncName;
|
|
GLenum m_stencilFuncFace;
|
|
};
|
|
|
|
class StencilMaskTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilMaskTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
const int stencilBits = m_context.getRenderTarget().getStencilBits();
|
|
|
|
m_verifier->verifyStencilMaskInitial(m_testCtx, m_testTargetName, stencilBits);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit)
|
|
{
|
|
const int mask = 1 << stencilBit;
|
|
|
|
glStencilFunc(GL_ALWAYS, 0, mask);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, mask);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
};
|
|
|
|
class StencilMaskSeparateTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilMaskSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, GLenum stencilFuncTargetFace)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
, m_stencilFuncTargetFace (stencilFuncTargetFace)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
const int stencilBits = m_context.getRenderTarget().getStencilBits();
|
|
|
|
m_verifier->verifyStencilMaskInitial(m_testCtx, m_testTargetName, stencilBits);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit)
|
|
{
|
|
const int mask = 1 << stencilBit;
|
|
|
|
glStencilFuncSeparate(m_stencilFuncTargetFace, GL_ALWAYS, 0, mask);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, mask);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
GLenum m_stencilFuncTargetFace;
|
|
};
|
|
|
|
class StencilWriteMaskTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilWriteMaskTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
const int stencilBits = m_context.getRenderTarget().getStencilBits();
|
|
|
|
for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit)
|
|
{
|
|
const int mask = 1 << stencilBit;
|
|
|
|
glStencilMask(mask);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, mask);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
};
|
|
|
|
class StencilWriteMaskSeparateTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilWriteMaskSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, GLenum stencilTargetFace)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
, m_stencilTargetFace (stencilTargetFace)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
const int stencilBits = m_context.getRenderTarget().getStencilBits();
|
|
|
|
for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit)
|
|
{
|
|
const int mask = 1 << stencilBit;
|
|
|
|
glStencilMaskSeparate(m_stencilTargetFace, mask);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, mask);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
GLenum m_stencilTargetFace;
|
|
};
|
|
|
|
class PixelStoreTestCase : public ApiCase
|
|
{
|
|
public:
|
|
PixelStoreTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
, m_initialValue (initialValue)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
de::Random rnd(0xabcdef);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, m_initialValue);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const int numIterations = 120;
|
|
for (int i = 0; i < numIterations; ++i)
|
|
{
|
|
const int referenceValue = rnd.getInt(0, 64000);
|
|
|
|
glPixelStorei(m_testTargetName, referenceValue);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, referenceValue);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
int m_initialValue;
|
|
};
|
|
|
|
class PixelStoreAlignTestCase : public ApiCase
|
|
{
|
|
public:
|
|
PixelStoreAlignTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, 4);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const int alignments[] = {1, 2, 4, 8};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(alignments); ++ndx)
|
|
{
|
|
const int referenceValue = alignments[ndx];
|
|
|
|
glPixelStorei(m_testTargetName, referenceValue);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, referenceValue);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
};
|
|
|
|
class BlendFuncTestCase : public ApiCase
|
|
{
|
|
public:
|
|
BlendFuncTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
, m_initialValue (initialValue)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, m_initialValue);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const GLenum blendFuncValues[] =
|
|
{
|
|
GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,
|
|
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR,
|
|
GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA,
|
|
GL_SRC_ALPHA_SATURATE
|
|
};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(blendFuncValues); ++ndx)
|
|
{
|
|
const GLenum referenceValue = blendFuncValues[ndx];
|
|
|
|
SetBlendFunc(referenceValue);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, referenceValue);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
protected:
|
|
virtual void SetBlendFunc (GLenum func)
|
|
{
|
|
switch (m_testTargetName)
|
|
{
|
|
case GL_BLEND_SRC_RGB:
|
|
case GL_BLEND_SRC_ALPHA:
|
|
glBlendFunc(func, GL_ZERO);
|
|
break;
|
|
|
|
case GL_BLEND_DST_RGB:
|
|
case GL_BLEND_DST_ALPHA:
|
|
glBlendFunc(GL_ZERO, func);
|
|
break;
|
|
|
|
default:
|
|
DE_ASSERT(false && "should not happen");
|
|
break;
|
|
}
|
|
}
|
|
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
int m_initialValue;
|
|
};
|
|
|
|
class BlendFuncSeparateTestCase : public BlendFuncTestCase
|
|
{
|
|
public:
|
|
BlendFuncSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue)
|
|
: BlendFuncTestCase (context, verifier, name, description, testTargetName, initialValue)
|
|
{
|
|
}
|
|
|
|
void SetBlendFunc (GLenum func)
|
|
{
|
|
switch (m_testTargetName)
|
|
{
|
|
case GL_BLEND_SRC_RGB:
|
|
glBlendFuncSeparate(func, GL_ZERO, GL_ZERO, GL_ZERO);
|
|
break;
|
|
|
|
case GL_BLEND_DST_RGB:
|
|
glBlendFuncSeparate(GL_ZERO, func, GL_ZERO, GL_ZERO);
|
|
break;
|
|
|
|
case GL_BLEND_SRC_ALPHA:
|
|
glBlendFuncSeparate(GL_ZERO, GL_ZERO, func, GL_ZERO);
|
|
break;
|
|
|
|
case GL_BLEND_DST_ALPHA:
|
|
glBlendFuncSeparate(GL_ZERO, GL_ZERO, GL_ZERO, func);
|
|
break;
|
|
|
|
default:
|
|
DE_ASSERT(false && "should not happen");
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
class BlendEquationTestCase : public ApiCase
|
|
{
|
|
public:
|
|
BlendEquationTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
, m_initialValue (initialValue)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, m_initialValue);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const GLenum blendFuncValues[] =
|
|
{
|
|
GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX
|
|
};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(blendFuncValues); ++ndx)
|
|
{
|
|
const GLenum referenceValue = blendFuncValues[ndx];
|
|
|
|
SetBlendEquation(referenceValue);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, m_testTargetName, referenceValue);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
protected:
|
|
virtual void SetBlendEquation (GLenum equation)
|
|
{
|
|
glBlendEquation(equation);
|
|
}
|
|
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
int m_initialValue;
|
|
};
|
|
class BlendEquationSeparateTestCase : public BlendEquationTestCase
|
|
{
|
|
public:
|
|
BlendEquationSeparateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, int initialValue)
|
|
: BlendEquationTestCase (context, verifier, name, description, testTargetName, initialValue)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
void SetBlendEquation (GLenum equation)
|
|
{
|
|
switch (m_testTargetName)
|
|
{
|
|
case GL_BLEND_EQUATION_RGB:
|
|
glBlendEquationSeparate(equation, GL_FUNC_ADD);
|
|
break;
|
|
|
|
case GL_BLEND_EQUATION_ALPHA:
|
|
glBlendEquationSeparate(GL_FUNC_ADD, equation);
|
|
break;
|
|
|
|
default:
|
|
DE_ASSERT(false && "should not happen");
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
class ImplementationArrayTestCase : public ApiCase
|
|
{
|
|
public:
|
|
ImplementationArrayTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum testTargetName, GLenum testTargetLengthTargetName, int minValue)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
, m_testTargetName (testTargetName)
|
|
, m_testTargetLengthTargetName (testTargetLengthTargetName)
|
|
, m_minValue (minValue)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyIntegerGreaterOrEqual(m_testCtx, m_testTargetLengthTargetName, m_minValue);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
GLint targetArrayLength = 0;
|
|
glGetIntegerv(m_testTargetLengthTargetName, &targetArrayLength);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
if (targetArrayLength)
|
|
{
|
|
std::vector<GLint> queryResult;
|
|
queryResult.resize(targetArrayLength, 0);
|
|
|
|
glGetIntegerv(m_testTargetName, &queryResult[0]);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
GLenum m_testTargetName;
|
|
GLenum m_testTargetLengthTargetName;
|
|
int m_minValue;
|
|
};
|
|
|
|
class BindingTest : public TestCase
|
|
{
|
|
public:
|
|
BindingTest (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
QueryType type);
|
|
|
|
IterateResult iterate (void);
|
|
|
|
virtual void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const = 0;
|
|
|
|
protected:
|
|
const QueryType m_type;
|
|
};
|
|
|
|
BindingTest::BindingTest (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
QueryType type)
|
|
: TestCase (context, name, desc)
|
|
, m_type (type)
|
|
{
|
|
}
|
|
|
|
BindingTest::IterateResult BindingTest::iterate (void)
|
|
{
|
|
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
|
|
tcu::ResultCollector result (m_context.getTestContext().getLog(), " // ERROR: ");
|
|
|
|
gl.enableLogging(true);
|
|
|
|
test(gl, result);
|
|
|
|
result.setTestContextResult(m_testCtx);
|
|
return STOP;
|
|
}
|
|
|
|
class TransformFeedbackBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
TransformFeedbackBindingTestCase (Context& context, QueryType type, const char* name)
|
|
: BindingTest(context, name, "GL_TRANSFORM_FEEDBACK_BINDING", type)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
static const char* transformFeedbackTestVertSource =
|
|
"#version 300 es\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = vec4(0.0);\n"
|
|
"}\n\0";
|
|
static const char* transformFeedbackTestFragSource =
|
|
"#version 300 es\n"
|
|
"layout(location = 0) out mediump vec4 fragColor;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" fragColor = vec4(0.0);\n"
|
|
"}\n\0";
|
|
|
|
GLuint shaderVert;
|
|
GLuint shaderFrag;
|
|
GLuint shaderProg;
|
|
GLuint transformfeedback = 0;
|
|
GLuint feedbackBufferId = 0;
|
|
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "Initial", "Initial");
|
|
verifyStateInteger(result, gl, GL_TRANSFORM_FEEDBACK_BINDING, 0, m_type);
|
|
}
|
|
|
|
gl.glGenTransformFeedbacks(1, &transformfeedback);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenTransformFeedbacks");
|
|
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "VertexShader", "Vertex Shader");
|
|
|
|
GLint compileStatus = -1;
|
|
|
|
shaderVert = gl.glCreateShader(GL_VERTEX_SHADER);
|
|
gl.glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL);
|
|
gl.glCompileShader(shaderVert);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glCompileShader");
|
|
|
|
gl.glGetShaderiv(shaderVert, GL_COMPILE_STATUS, &compileStatus);
|
|
if (compileStatus != GL_TRUE)
|
|
result.fail("expected GL_TRUE");
|
|
}
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "FragmentShader", "Fragment Shader");
|
|
|
|
GLint compileStatus = -1;
|
|
|
|
shaderFrag = gl.glCreateShader(GL_FRAGMENT_SHADER);
|
|
gl.glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL);
|
|
gl.glCompileShader(shaderFrag);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glCompileShader");
|
|
|
|
gl.glGetShaderiv(shaderFrag, GL_COMPILE_STATUS, &compileStatus);
|
|
if (compileStatus != GL_TRUE)
|
|
result.fail("expected GL_TRUE");
|
|
}
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "Program", "Create and bind program");
|
|
|
|
const char* transform_feedback_outputs = "gl_Position";
|
|
GLint linkStatus = -1;
|
|
|
|
shaderProg = gl.glCreateProgram();
|
|
gl.glAttachShader(shaderProg, shaderVert);
|
|
gl.glAttachShader(shaderProg, shaderFrag);
|
|
gl.glTransformFeedbackVaryings(shaderProg, 1, &transform_feedback_outputs, GL_INTERLEAVED_ATTRIBS);
|
|
gl.glLinkProgram(shaderProg);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glLinkProgram");
|
|
|
|
gl.glGetProgramiv(shaderProg, GL_LINK_STATUS, &linkStatus);
|
|
if (linkStatus != GL_TRUE)
|
|
result.fail("expected GL_TRUE");
|
|
}
|
|
|
|
gl.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformfeedback);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindTransformFeedback");
|
|
|
|
gl.glGenBuffers(1, &feedbackBufferId);
|
|
gl.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBufferId);
|
|
gl.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ);
|
|
gl.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, feedbackBufferId);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind buffers");
|
|
|
|
gl.glUseProgram(shaderProg);
|
|
|
|
verifyStateInteger(result, gl, GL_TRANSFORM_FEEDBACK_BINDING, transformfeedback, m_type);
|
|
|
|
gl.glUseProgram(0);
|
|
gl.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
|
|
gl.glDeleteTransformFeedbacks(1, &transformfeedback);
|
|
|
|
verifyStateInteger(result, gl, GL_TRANSFORM_FEEDBACK_BINDING, 0, m_type);
|
|
|
|
gl.glDeleteBuffers(1, &feedbackBufferId);
|
|
gl.glDeleteShader(shaderVert);
|
|
gl.glDeleteShader(shaderFrag);
|
|
gl.glDeleteProgram(shaderProg);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteProgram");
|
|
}
|
|
};
|
|
|
|
class CurrentProgramBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
CurrentProgramBindingTestCase (Context& context, QueryType type, const char* name, const char* description)
|
|
: BindingTest(context, name, description, type)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
static const char* testVertSource =
|
|
"#version 300 es\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = vec4(0.0);\n"
|
|
"}\n\0";
|
|
static const char* testFragSource =
|
|
"#version 300 es\n"
|
|
"layout(location = 0) out mediump vec4 fragColor;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" fragColor = vec4(0.0);\n"
|
|
"}\n\0";
|
|
|
|
GLuint shaderVert;
|
|
GLuint shaderFrag;
|
|
GLuint shaderProg;
|
|
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "Initial", "Initial");
|
|
|
|
verifyStateInteger(result, gl, GL_CURRENT_PROGRAM, 0, m_type);
|
|
}
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "VertexShader", "Vertex Shader");
|
|
|
|
GLint compileStatus = -1;
|
|
|
|
shaderVert = gl.glCreateShader(GL_VERTEX_SHADER);
|
|
gl.glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
|
|
gl.glCompileShader(shaderVert);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glCompileShader");
|
|
|
|
gl.glGetShaderiv(shaderVert, GL_COMPILE_STATUS, &compileStatus);
|
|
if (compileStatus != GL_TRUE)
|
|
result.fail("expected GL_TRUE");
|
|
}
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "FragmentShader", "Fragment Shader");
|
|
|
|
GLint compileStatus = -1;
|
|
|
|
shaderFrag = gl.glCreateShader(GL_FRAGMENT_SHADER);
|
|
gl.glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
|
|
gl.glCompileShader(shaderFrag);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glCompileShader");
|
|
|
|
gl.glGetShaderiv(shaderFrag, GL_COMPILE_STATUS, &compileStatus);
|
|
if (compileStatus != GL_TRUE)
|
|
result.fail("expected GL_TRUE");
|
|
}
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "Program", "Create and bind program");
|
|
|
|
GLint linkStatus = -1;
|
|
|
|
shaderProg = gl.glCreateProgram();
|
|
gl.glAttachShader(shaderProg, shaderVert);
|
|
gl.glAttachShader(shaderProg, shaderFrag);
|
|
gl.glLinkProgram(shaderProg);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glLinkProgram");
|
|
|
|
gl.glGetProgramiv(shaderProg, GL_LINK_STATUS, &linkStatus);
|
|
if (linkStatus != GL_TRUE)
|
|
result.fail("expected GL_TRUE");
|
|
|
|
gl.glUseProgram(shaderProg);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glUseProgram");
|
|
|
|
verifyStateInteger(result, gl, GL_CURRENT_PROGRAM, shaderProg, m_type);
|
|
}
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "Delete", "Delete program while in use");
|
|
|
|
gl.glDeleteShader(shaderVert);
|
|
gl.glDeleteShader(shaderFrag);
|
|
gl.glDeleteProgram(shaderProg);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteProgram");
|
|
|
|
verifyStateInteger(result, gl, GL_CURRENT_PROGRAM, shaderProg, m_type);
|
|
}
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "Unbind", "Unbind program");
|
|
gl.glUseProgram(0);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glUseProgram");
|
|
|
|
verifyStateInteger(result, gl, GL_CURRENT_PROGRAM, 0, m_type);
|
|
}
|
|
}
|
|
};
|
|
|
|
class VertexArrayBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
VertexArrayBindingTestCase (Context& context, QueryType type, const char* name, const char* description)
|
|
: BindingTest(context, name, description, type)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
verifyStateInteger(result, gl, GL_VERTEX_ARRAY_BINDING, 0, m_type);
|
|
|
|
GLuint vertexArrayObject = 0;
|
|
gl.glGenVertexArrays(1, &vertexArrayObject);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenVertexArrays");
|
|
|
|
gl.glBindVertexArray(vertexArrayObject);
|
|
verifyStateInteger(result, gl, GL_VERTEX_ARRAY_BINDING, vertexArrayObject, m_type);
|
|
|
|
gl.glDeleteVertexArrays(1, &vertexArrayObject);
|
|
verifyStateInteger(result, gl, GL_VERTEX_ARRAY_BINDING, 0, m_type);
|
|
}
|
|
};
|
|
|
|
class BufferBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
BufferBindingTestCase (Context& context, QueryType type, const char* name, const char* description, GLenum bufferBindingName, GLenum bufferType)
|
|
: BindingTest (context, name, description, type)
|
|
, m_bufferBindingName (bufferBindingName)
|
|
, m_bufferType (bufferType)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
verifyStateInteger(result, gl, m_bufferBindingName, 0, m_type);
|
|
|
|
GLuint bufferObject = 0;
|
|
gl.glGenBuffers(1, &bufferObject);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenBuffers");
|
|
|
|
gl.glBindBuffer(m_bufferType, bufferObject);
|
|
verifyStateInteger(result, gl, m_bufferBindingName, bufferObject, m_type);
|
|
|
|
gl.glDeleteBuffers(1, &bufferObject);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteBuffers");
|
|
|
|
verifyStateInteger(result, gl, m_bufferBindingName, 0, m_type);
|
|
}
|
|
|
|
private:
|
|
const GLenum m_bufferBindingName;
|
|
const GLenum m_bufferType;
|
|
};
|
|
|
|
class ElementArrayBufferBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
ElementArrayBufferBindingTestCase (Context& context, QueryType type, const char* name)
|
|
: BindingTest(context, name, "GL_ELEMENT_ARRAY_BUFFER_BINDING", type)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
// Test with default VAO
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "DefaultVAO", "Test with default VAO");
|
|
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type);
|
|
|
|
GLuint bufferObject = 0;
|
|
gl.glGenBuffers(1, &bufferObject);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenBuffers");
|
|
|
|
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObject);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, bufferObject, m_type);
|
|
|
|
gl.glDeleteBuffers(1, &bufferObject);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type);
|
|
}
|
|
|
|
// Test with multiple VAOs
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "WithVAO", "Test with VAO");
|
|
|
|
GLuint vaos[2] = {0};
|
|
GLuint buffers[2] = {0};
|
|
|
|
gl.glGenVertexArrays(2, vaos);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenVertexArrays");
|
|
|
|
gl.glGenBuffers(2, buffers);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenBuffers");
|
|
|
|
// initial
|
|
gl.glBindVertexArray(vaos[0]);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type);
|
|
|
|
// after setting
|
|
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[0]);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, buffers[0], m_type);
|
|
|
|
// initial of vao 2
|
|
gl.glBindVertexArray(vaos[1]);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type);
|
|
|
|
// after setting to 2
|
|
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, buffers[1], m_type);
|
|
|
|
// vao 1 still has buffer 1 bound?
|
|
gl.glBindVertexArray(vaos[0]);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, buffers[0], m_type);
|
|
|
|
// deleting clears from bound vaos ...
|
|
gl.glDeleteBuffers(2, buffers);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, m_type);
|
|
|
|
// ... but does not from non-bound vaos?
|
|
gl.glBindVertexArray(vaos[1]);
|
|
verifyStateInteger(result, gl, GL_ELEMENT_ARRAY_BUFFER_BINDING, buffers[1], m_type);
|
|
|
|
gl.glDeleteVertexArrays(2, vaos);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteVertexArrays");
|
|
}
|
|
}
|
|
};
|
|
|
|
class StencilClearValueTestCase : public ApiCase
|
|
{
|
|
public:
|
|
StencilClearValueTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, GL_STENCIL_CLEAR_VALUE, 0);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
const int stencilBits = m_context.getRenderTarget().getStencilBits();
|
|
|
|
for (int stencilBit = 0; stencilBit < stencilBits; ++stencilBit)
|
|
{
|
|
const int ref = 1 << stencilBit;
|
|
|
|
glClearStencil(ref); // mask should not affect the REF
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_STENCIL_CLEAR_VALUE, ref);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class ActiveTextureTestCase : public ApiCase
|
|
{
|
|
public:
|
|
ActiveTextureTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
m_verifier->verifyInteger(m_testCtx, GL_ACTIVE_TEXTURE, GL_TEXTURE0);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
GLint textureUnits = 0;
|
|
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &textureUnits);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
for (int ndx = 0; ndx < textureUnits; ++ndx)
|
|
{
|
|
glActiveTexture(GL_TEXTURE0 + ndx);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_ACTIVE_TEXTURE, GL_TEXTURE0 + ndx);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class RenderbufferBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
RenderbufferBindingTestCase (Context& context, QueryType type, const char* name, const char* description)
|
|
: BindingTest(context, name, description, type)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
verifyStateInteger(result, gl, GL_RENDERBUFFER_BINDING, 0, m_type);
|
|
|
|
GLuint renderBuffer = 0;
|
|
gl.glGenRenderbuffers(1, &renderBuffer);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenRenderbuffers");
|
|
|
|
gl.glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindRenderbuffer");
|
|
|
|
verifyStateInteger(result, gl, GL_RENDERBUFFER_BINDING, renderBuffer, m_type);
|
|
|
|
gl.glDeleteRenderbuffers(1, &renderBuffer);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteRenderbuffers");
|
|
|
|
verifyStateInteger(result, gl, GL_RENDERBUFFER_BINDING, 0, m_type);
|
|
}
|
|
};
|
|
|
|
class SamplerObjectBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
SamplerObjectBindingTestCase (Context& context, QueryType type, const char* name, const char* description)
|
|
: BindingTest(context, name, description, type)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
verifyStateInteger(result, gl, GL_SAMPLER_BINDING, 0, m_type);
|
|
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "SingleUnit", "Single unit");
|
|
|
|
GLuint sampler = 0;
|
|
gl.glGenSamplers(1, &sampler);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenSamplers");
|
|
|
|
gl.glBindSampler(0, sampler);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindSampler");
|
|
|
|
verifyStateInteger(result, gl, GL_SAMPLER_BINDING, sampler, m_type);
|
|
|
|
gl.glDeleteSamplers(1, &sampler);
|
|
verifyStateInteger(result, gl, GL_SAMPLER_BINDING, 0, m_type);
|
|
}
|
|
|
|
{
|
|
const tcu::ScopedLogSection section(gl.getLog(), "MultipleUnits", "Multiple units");
|
|
|
|
GLuint samplerA = 0;
|
|
GLuint samplerB = 0;
|
|
gl.glGenSamplers(1, &samplerA);
|
|
gl.glGenSamplers(1, &samplerB);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenSamplers");
|
|
|
|
gl.glBindSampler(1, samplerA);
|
|
gl.glBindSampler(2, samplerB);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindSampler");
|
|
|
|
verifyStateInteger(result, gl, GL_SAMPLER_BINDING, 0, m_type);
|
|
|
|
gl.glActiveTexture(GL_TEXTURE1);
|
|
verifyStateInteger(result, gl, GL_SAMPLER_BINDING, samplerA, m_type);
|
|
|
|
gl.glActiveTexture(GL_TEXTURE2);
|
|
verifyStateInteger(result, gl, GL_SAMPLER_BINDING, samplerB, m_type);
|
|
|
|
gl.glDeleteSamplers(1, &samplerB);
|
|
gl.glDeleteSamplers(1, &samplerA);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteSamplers");
|
|
}
|
|
}
|
|
};
|
|
|
|
class TextureBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
TextureBindingTestCase (Context& context, QueryType type, const char* name, const char* description, GLenum testBindingName, GLenum textureType)
|
|
: BindingTest (context, name, description, type)
|
|
, m_testBindingName (testBindingName)
|
|
, m_textureType (textureType)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
verifyStateInteger(result, gl, m_testBindingName, 0, m_type);
|
|
|
|
GLuint texture = 0;
|
|
gl.glGenTextures(1, &texture);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenTextures");
|
|
|
|
gl.glBindTexture(m_textureType, texture);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindTexture");
|
|
|
|
verifyStateInteger(result, gl, m_testBindingName, texture, m_type);
|
|
|
|
gl.glDeleteTextures(1, &texture);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteTextures");
|
|
|
|
verifyStateInteger(result, gl, m_testBindingName, 0, m_type);
|
|
}
|
|
private:
|
|
const GLenum m_testBindingName;
|
|
const GLenum m_textureType;
|
|
};
|
|
|
|
class FrameBufferBindingTestCase : public BindingTest
|
|
{
|
|
public:
|
|
FrameBufferBindingTestCase (Context& context, QueryType type, const char* name, const char* description)
|
|
: BindingTest(context, name, description, type)
|
|
{
|
|
}
|
|
|
|
void test (glu::CallLogWrapper& gl, tcu::ResultCollector& result) const
|
|
{
|
|
verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, 0, m_type);
|
|
verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, 0, m_type);
|
|
verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, 0, m_type);
|
|
|
|
GLuint framebufferId = 0;
|
|
gl.glGenFramebuffers(1, &framebufferId);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenFramebuffers");
|
|
|
|
gl.glBindFramebuffer(GL_FRAMEBUFFER, framebufferId);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind GL_FRAMEBUFFER");
|
|
|
|
verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, framebufferId, m_type);
|
|
verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, framebufferId, m_type);
|
|
verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, framebufferId, m_type);
|
|
|
|
gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "unbind GL_FRAMEBUFFER");
|
|
|
|
verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, 0, m_type);
|
|
verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, 0, m_type);
|
|
verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, 0, m_type);
|
|
|
|
gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferId);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind GL_READ_FRAMEBUFFER");
|
|
|
|
verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, 0, m_type);
|
|
verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, 0, m_type);
|
|
verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, framebufferId, m_type);
|
|
|
|
gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferId);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind GL_DRAW_FRAMEBUFFER");
|
|
|
|
verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, framebufferId, m_type);
|
|
verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, framebufferId, m_type);
|
|
verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, framebufferId, m_type);
|
|
|
|
gl.glDeleteFramebuffers(1, &framebufferId);
|
|
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDeleteFramebuffers");
|
|
|
|
verifyStateInteger(result, gl, GL_DRAW_FRAMEBUFFER_BINDING, 0, m_type);
|
|
verifyStateInteger(result, gl, GL_FRAMEBUFFER_BINDING, 0, m_type);
|
|
verifyStateInteger(result, gl, GL_READ_FRAMEBUFFER_BINDING, 0, m_type);
|
|
}
|
|
};
|
|
|
|
class ImplementationColorReadTestCase : public ApiCase
|
|
{
|
|
public:
|
|
ImplementationColorReadTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
const GLint defaultColorTypes[] =
|
|
{
|
|
GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
|
|
GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_SHORT_5_6_5,
|
|
GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_5_5_5_1,
|
|
GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV
|
|
};
|
|
const GLint defaultColorFormats[] =
|
|
{
|
|
GL_RGBA, GL_RGBA_INTEGER, GL_RGB, GL_RGB_INTEGER,
|
|
GL_RG, GL_RG_INTEGER, GL_RED, GL_RED_INTEGER
|
|
};
|
|
|
|
std::vector<GLint> validColorTypes;
|
|
std::vector<GLint> validColorFormats;
|
|
|
|
// Defined by the spec
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(defaultColorTypes); ++ndx)
|
|
validColorTypes.push_back(defaultColorTypes[ndx]);
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(defaultColorFormats); ++ndx)
|
|
validColorFormats.push_back(defaultColorFormats[ndx]);
|
|
|
|
// Extensions
|
|
|
|
if (m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888") ||
|
|
m_context.getContextInfo().isExtensionSupported("GL_APPLE_texture_format_BGRA8888"))
|
|
validColorFormats.push_back(GL_BGRA);
|
|
|
|
if (m_context.getContextInfo().isExtensionSupported("GL_EXT_read_format_bgra"))
|
|
{
|
|
validColorFormats.push_back(GL_BGRA);
|
|
validColorTypes.push_back(GL_UNSIGNED_SHORT_4_4_4_4_REV);
|
|
validColorTypes.push_back(GL_UNSIGNED_SHORT_1_5_5_5_REV);
|
|
}
|
|
|
|
if (m_context.getContextInfo().isExtensionSupported("GL_IMG_read_format"))
|
|
{
|
|
validColorFormats.push_back(GL_BGRA);
|
|
validColorTypes.push_back(GL_UNSIGNED_SHORT_4_4_4_4_REV);
|
|
}
|
|
|
|
if (m_context.getContextInfo().isExtensionSupported("GL_NV_sRGB_formats"))
|
|
{
|
|
validColorFormats.push_back(GL_SLUMINANCE_NV);
|
|
validColorFormats.push_back(GL_SLUMINANCE_ALPHA_NV);
|
|
}
|
|
|
|
if (m_context.getContextInfo().isExtensionSupported("GL_NV_bgr"))
|
|
{
|
|
validColorFormats.push_back(GL_BGR_NV);
|
|
}
|
|
|
|
m_verifier->verifyIntegerAnyOf(m_testCtx, GL_IMPLEMENTATION_COLOR_READ_TYPE, &validColorTypes[0], validColorTypes.size());
|
|
m_verifier->verifyIntegerAnyOf(m_testCtx, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &validColorFormats[0], validColorFormats.size());
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class ReadBufferCase : public ApiCase
|
|
{
|
|
public:
|
|
ReadBufferCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
const GLint validInitialValues[] = {GL_BACK, GL_NONE};
|
|
m_verifier->verifyIntegerAnyOf(m_testCtx, GL_READ_BUFFER, validInitialValues, DE_LENGTH_OF_ARRAY(validInitialValues));
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glReadBuffer(GL_NONE);
|
|
m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, GL_NONE);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glReadBuffer(GL_BACK);
|
|
m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, GL_BACK);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
// test GL_READ_BUFFER with framebuffers
|
|
|
|
GLuint framebufferId = 0;
|
|
glGenFramebuffers(1, &framebufferId);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
GLuint renderbuffer_id = 0;
|
|
glGenRenderbuffers(1, &renderbuffer_id);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_id);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 128, 128);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferId);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_id);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, GL_COLOR_ATTACHMENT0);
|
|
|
|
glDeleteFramebuffers(1, &framebufferId);
|
|
glDeleteRenderbuffers(1, &renderbuffer_id);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_READ_BUFFER, GL_BACK);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
class DrawBufferCase : public ApiCase
|
|
{
|
|
public:
|
|
DrawBufferCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
|
|
: ApiCase (context, name, description)
|
|
, m_verifier (verifier)
|
|
{
|
|
}
|
|
|
|
void test (void)
|
|
{
|
|
const GLint validInitialValues[] = {GL_BACK, GL_NONE};
|
|
m_verifier->verifyIntegerAnyOf(m_testCtx, GL_DRAW_BUFFER0, validInitialValues, DE_LENGTH_OF_ARRAY(validInitialValues));
|
|
expectError(GL_NO_ERROR);
|
|
|
|
GLenum bufs = GL_NONE;
|
|
glDrawBuffers(1, &bufs);
|
|
m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_NONE);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
bufs = GL_BACK;
|
|
glDrawBuffers(1, &bufs);
|
|
m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_BACK);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
// test GL_DRAW_BUFFER with framebuffers
|
|
|
|
GLuint framebufferId = 0;
|
|
glGenFramebuffers(1, &framebufferId);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
GLuint renderbuffer_ids[2] = {0};
|
|
glGenRenderbuffers(2, renderbuffer_ids);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_ids[0]);
|
|
expectError(GL_NO_ERROR);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 128, 128);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_ids[1]);
|
|
expectError(GL_NO_ERROR);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 128, 128);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferId);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_ids[0]);
|
|
expectError(GL_NO_ERROR);
|
|
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, renderbuffer_ids[1]);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
// only the initial state the draw buffer for fragment color zero is defined
|
|
m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_COLOR_ATTACHMENT0);
|
|
|
|
GLenum bufTargets[2] = {GL_NONE, GL_COLOR_ATTACHMENT1};
|
|
glDrawBuffers(2, bufTargets);
|
|
m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_NONE);
|
|
m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER1, GL_COLOR_ATTACHMENT1);
|
|
|
|
glDeleteFramebuffers(1, &framebufferId);
|
|
glDeleteRenderbuffers(2, renderbuffer_ids);
|
|
expectError(GL_NO_ERROR);
|
|
|
|
m_verifier->verifyInteger(m_testCtx, GL_DRAW_BUFFER0, GL_BACK);
|
|
expectError(GL_NO_ERROR);
|
|
}
|
|
private:
|
|
StateVerifier* m_verifier;
|
|
};
|
|
|
|
static const char* getQueryTypeSuffix (QueryType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case QUERY_BOOLEAN: return "_getboolean";
|
|
case QUERY_INTEGER: return "_getinteger";
|
|
case QUERY_INTEGER64: return "_getinteger64";
|
|
case QUERY_FLOAT: return "_getfloat";
|
|
default:
|
|
DE_ASSERT(DE_FALSE);
|
|
return DE_NULL;
|
|
}
|
|
}
|
|
|
|
#define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK) \
|
|
for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++) \
|
|
{ \
|
|
StateVerifier* verifier = (VERIFIERS)[_verifierNdx]; \
|
|
CODE_BLOCK; \
|
|
}
|
|
|
|
#define FOR_EACH_QUERYTYPE(QUERYTYPES, CODE_BLOCK) \
|
|
for (int _queryTypeNdx = 0; _queryTypeNdx < DE_LENGTH_OF_ARRAY(QUERYTYPES); _queryTypeNdx++) \
|
|
{ \
|
|
const QueryType queryType = (QUERYTYPES)[_queryTypeNdx]; \
|
|
CODE_BLOCK; \
|
|
}
|
|
|
|
} // anonymous
|
|
|
|
IntegerStateQueryTests::IntegerStateQueryTests (Context& context)
|
|
: TestCaseGroup (context, "integers", "Integer Values")
|
|
, m_verifierBoolean (DE_NULL)
|
|
, m_verifierInteger (DE_NULL)
|
|
, m_verifierInteger64 (DE_NULL)
|
|
, m_verifierFloat (DE_NULL)
|
|
{
|
|
}
|
|
|
|
IntegerStateQueryTests::~IntegerStateQueryTests (void)
|
|
{
|
|
deinit();
|
|
}
|
|
|
|
void IntegerStateQueryTests::init (void)
|
|
{
|
|
static const QueryType queryTypes[] =
|
|
{
|
|
QUERY_BOOLEAN,
|
|
QUERY_INTEGER,
|
|
QUERY_INTEGER64,
|
|
QUERY_FLOAT,
|
|
};
|
|
|
|
DE_ASSERT(m_verifierBoolean == DE_NULL);
|
|
DE_ASSERT(m_verifierInteger == DE_NULL);
|
|
DE_ASSERT(m_verifierInteger64 == DE_NULL);
|
|
DE_ASSERT(m_verifierFloat == DE_NULL);
|
|
|
|
m_verifierBoolean = new GetBooleanVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
|
|
m_verifierInteger = new GetIntegerVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
|
|
m_verifierInteger64 = new GetInteger64Verifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
|
|
m_verifierFloat = new GetFloatVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
|
|
|
|
const struct LimitedStateInteger
|
|
{
|
|
const char* name;
|
|
const char* description;
|
|
GLenum targetName;
|
|
GLint value;
|
|
} implementationMinLimits[] =
|
|
{
|
|
{ "subpixel_bits", "SUBPIXEL_BITS has minimum value of 4", GL_SUBPIXEL_BITS, 4 },
|
|
{ "max_3d_texture_size", "MAX_3D_TEXTURE_SIZE has minimum value of 256", GL_MAX_3D_TEXTURE_SIZE, 256 },
|
|
{ "max_texture_size", "MAX_TEXTURE_SIZE has minimum value of 2048", GL_MAX_TEXTURE_SIZE, 2048},
|
|
{ "max_array_texture_layers", "MAX_ARRAY_TEXTURE_LAYERS has minimum value of 256", GL_MAX_ARRAY_TEXTURE_LAYERS, 256 },
|
|
{ "max_cube_map_texture_size", "MAX_CUBE_MAP_TEXTURE_SIZE has minimum value of 2048", GL_MAX_CUBE_MAP_TEXTURE_SIZE, 2048},
|
|
{ "max_renderbuffer_size", "MAX_RENDERBUFFER_SIZE has minimum value of 2048", GL_MAX_RENDERBUFFER_SIZE, 2048},
|
|
{ "max_draw_buffers", "MAX_DRAW_BUFFERS has minimum value of 4", GL_MAX_DRAW_BUFFERS, 4 },
|
|
{ "max_color_attachments", "MAX_COLOR_ATTACHMENTS has minimum value of 4", GL_MAX_COLOR_ATTACHMENTS, 4 },
|
|
{ "max_elements_indices", "MAX_ELEMENTS_INDICES has minimum value of 0", GL_MAX_ELEMENTS_INDICES, 0 },
|
|
{ "max_elements_vertices", "MAX_ELEMENTS_VERTICES has minimum value of 0", GL_MAX_ELEMENTS_VERTICES, 0 },
|
|
{ "num_extensions", "NUM_EXTENSIONS has minimum value of 0", GL_NUM_EXTENSIONS, 0 },
|
|
{ "major_version", "MAJOR_VERSION has minimum value of 3", GL_MAJOR_VERSION, 3 },
|
|
{ "minor_version", "MINOR_VERSION has minimum value of 0", GL_MINOR_VERSION, 0 },
|
|
{ "max_vertex_attribs", "MAX_VERTEX_ATTRIBS has minimum value of 16", GL_MAX_VERTEX_ATTRIBS, 16 },
|
|
{ "max_vertex_uniform_components", "MAX_VERTEX_UNIFORM_COMPONENTS has minimum value of 1024", GL_MAX_VERTEX_UNIFORM_COMPONENTS, 1024},
|
|
{ "max_vertex_uniform_vectors", "MAX_VERTEX_UNIFORM_VECTORS has minimum value of 256", GL_MAX_VERTEX_UNIFORM_VECTORS, 256 },
|
|
{ "max_vertex_uniform_blocks", "MAX_VERTEX_UNIFORM_BLOCKS has minimum value of 12", GL_MAX_VERTEX_UNIFORM_BLOCKS, 12 },
|
|
{ "max_vertex_output_components", "MAX_VERTEX_OUTPUT_COMPONENTS has minimum value of 64", GL_MAX_VERTEX_OUTPUT_COMPONENTS, 64 },
|
|
{ "max_vertex_texture_image_units", "MAX_VERTEX_TEXTURE_IMAGE_UNITS has minimum value of 16", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, 16 },
|
|
{ "max_fragment_uniform_components", "MAX_FRAGMENT_UNIFORM_COMPONENTS has minimum value of 896", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, 896 },
|
|
{ "max_fragment_uniform_vectors", "MAX_FRAGMENT_UNIFORM_VECTORS has minimum value of 224", GL_MAX_FRAGMENT_UNIFORM_VECTORS, 224 },
|
|
{ "max_fragment_uniform_blocks", "MAX_FRAGMENT_UNIFORM_BLOCKS has minimum value of 12", GL_MAX_FRAGMENT_UNIFORM_BLOCKS, 12 },
|
|
{ "max_fragment_input_components", "MAX_FRAGMENT_INPUT_COMPONENTS has minimum value of 60", GL_MAX_FRAGMENT_INPUT_COMPONENTS, 60 },
|
|
{ "max_texture_image_units", "MAX_TEXTURE_IMAGE_UNITS has minimum value of 16", GL_MAX_TEXTURE_IMAGE_UNITS, 16 },
|
|
{ "max_program_texel_offset", "MAX_PROGRAM_TEXEL_OFFSET has minimum value of 7", GL_MAX_PROGRAM_TEXEL_OFFSET, 7 },
|
|
{ "max_uniform_buffer_bindings", "MAX_UNIFORM_BUFFER_BINDINGS has minimum value of 24", GL_MAX_UNIFORM_BUFFER_BINDINGS, 24 },
|
|
{ "max_combined_uniform_blocks", "MAX_COMBINED_UNIFORM_BLOCKS has minimum value of 24", GL_MAX_COMBINED_UNIFORM_BLOCKS, 24 },
|
|
{ "max_varying_components", "MAX_VARYING_COMPONENTS has minimum value of 60", GL_MAX_VARYING_COMPONENTS, 60 },
|
|
{ "max_varying_vectors", "MAX_VARYING_VECTORS has minimum value of 15", GL_MAX_VARYING_VECTORS, 15 },
|
|
{ "max_combined_texture_image_units", "MAX_COMBINED_TEXTURE_IMAGE_UNITS has minimum value of 32", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 32 },
|
|
{ "max_transform_feedback_interleaved_components", "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS has minimum value of 64", GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, 64 },
|
|
{ "max_transform_feedback_separate_attribs", "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS has minimum value of 4", GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, 4 },
|
|
{ "max_transform_feedback_separate_components", "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS has minimum value of 4", GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, 4 },
|
|
{ "max_samples", "MAX_SAMPLES has minimum value of 4", GL_MAX_SAMPLES, 4 },
|
|
{ "red_bits", "RED_BITS has minimum value of 0", GL_RED_BITS, 0 },
|
|
{ "green_bits", "GREEN_BITS has minimum value of 0", GL_GREEN_BITS, 0 },
|
|
{ "blue_bits", "BLUE_BITS has minimum value of 0", GL_BLUE_BITS, 0 },
|
|
{ "alpha_bits", "ALPHA_BITS has minimum value of 0", GL_ALPHA_BITS, 0 },
|
|
{ "depth_bits", "DEPTH_BITS has minimum value of 0", GL_DEPTH_BITS, 0 },
|
|
{ "stencil_bits", "STENCIL_BITS has minimum value of 0", GL_STENCIL_BITS, 0 },
|
|
};
|
|
const LimitedStateInteger implementationMaxLimits[] =
|
|
{
|
|
{ "min_program_texel_offset", "MIN_PROGRAM_TEXEL_OFFSET has maximum value of -8", GL_MIN_PROGRAM_TEXEL_OFFSET, -8 },
|
|
{ "uniform_buffer_offset_alignment", "UNIFORM_BUFFER_OFFSET_ALIGNMENT has minimum value of 1", GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, 256 },
|
|
};
|
|
|
|
// \note implementation defined limits have their own tests so just check the conversions to boolean, int64 and float
|
|
StateVerifier* implementationLimitVerifiers[] = {m_verifierBoolean, m_verifierInteger64, m_verifierFloat};
|
|
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationMinLimits); testNdx++)
|
|
FOR_EACH_VERIFIER(implementationLimitVerifiers, addChild(new ConstantMinimumValueTestCase(m_context, verifier, (std::string(implementationMinLimits[testNdx].name) + verifier->getTestNamePostfix()).c_str(), implementationMinLimits[testNdx].description, implementationMinLimits[testNdx].targetName, implementationMinLimits[testNdx].value)));
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationMaxLimits); testNdx++)
|
|
FOR_EACH_VERIFIER(implementationLimitVerifiers, addChild(new ConstantMaximumValueTestCase(m_context, verifier, (std::string(implementationMaxLimits[testNdx].name) + verifier->getTestNamePostfix()).c_str(), implementationMaxLimits[testNdx].description, implementationMaxLimits[testNdx].targetName, implementationMaxLimits[testNdx].value)));
|
|
|
|
StateVerifier* normalVerifiers[] = {m_verifierBoolean, m_verifierInteger, m_verifierInteger64, m_verifierFloat};
|
|
|
|
FOR_EACH_VERIFIER(implementationLimitVerifiers, addChild(new SampleBuffersTestCase (m_context, verifier, (std::string("sample_buffers") + verifier->getTestNamePostfix()).c_str(), "SAMPLE_BUFFERS")));
|
|
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new SamplesTestCase (m_context, verifier, (std::string("samples") + verifier->getTestNamePostfix()).c_str(), "SAMPLES")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new HintTestCase (m_context, verifier, (std::string("generate_mipmap_hint") + verifier->getTestNamePostfix()).c_str(), "GENERATE_MIPMAP_HINT", GL_GENERATE_MIPMAP_HINT)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new HintTestCase (m_context, verifier, (std::string("fragment_shader_derivative_hint") + verifier->getTestNamePostfix()).c_str(), "FRAGMENT_SHADER_DERIVATIVE_HINT", GL_FRAGMENT_SHADER_DERIVATIVE_HINT)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new DepthFuncTestCase (m_context, verifier, (std::string("depth_func") + verifier->getTestNamePostfix()).c_str(), "DEPTH_FUNC")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new CullFaceTestCase (m_context, verifier, (std::string("cull_face_mode") + verifier->getTestNamePostfix()).c_str(), "CULL_FACE_MODE")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new FrontFaceTestCase (m_context, verifier, (std::string("front_face_mode") + verifier->getTestNamePostfix()).c_str(), "FRONT_FACE")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new ViewPortTestCase (m_context, verifier, (std::string("viewport") + verifier->getTestNamePostfix()).c_str(), "VIEWPORT")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new ScissorBoxTestCase (m_context, verifier, (std::string("scissor_box") + verifier->getTestNamePostfix()).c_str(), "SCISSOR_BOX")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new MaxViewportDimsTestCase (m_context, verifier, (std::string("max_viewport_dims") + verifier->getTestNamePostfix()).c_str(), "MAX_VIEWPORT_DIMS")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefTestCase (m_context, verifier, (std::string("stencil_ref") + verifier->getTestNamePostfix()).c_str(), "STENCIL_REF", GL_STENCIL_REF)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefTestCase (m_context, verifier, (std::string("stencil_back_ref") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_REF", GL_STENCIL_BACK_REF)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefSeparateTestCase (m_context, verifier, (std::string("stencil_ref_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_REF (separate)", GL_STENCIL_REF, GL_FRONT)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefSeparateTestCase (m_context, verifier, (std::string("stencil_ref_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_REF (separate)", GL_STENCIL_REF, GL_FRONT_AND_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefSeparateTestCase (m_context, verifier, (std::string("stencil_back_ref_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_REF (separate)", GL_STENCIL_BACK_REF, GL_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilRefSeparateTestCase (m_context, verifier, (std::string("stencil_back_ref_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_REF (separate)", GL_STENCIL_BACK_REF, GL_FRONT_AND_BACK)));
|
|
|
|
const struct NamedStencilOp
|
|
{
|
|
const char* name;
|
|
|
|
const char* frontDescription;
|
|
GLenum frontTarget;
|
|
const char* backDescription;
|
|
GLenum backTarget;
|
|
} stencilOps[] =
|
|
{
|
|
{ "fail", "STENCIL_FAIL", GL_STENCIL_FAIL, "STENCIL_BACK_FAIL", GL_STENCIL_BACK_FAIL },
|
|
{ "depth_fail", "STENCIL_PASS_DEPTH_FAIL", GL_STENCIL_PASS_DEPTH_FAIL, "STENCIL_BACK_PASS_DEPTH_FAIL", GL_STENCIL_BACK_PASS_DEPTH_FAIL },
|
|
{ "depth_pass", "STENCIL_PASS_DEPTH_PASS", GL_STENCIL_PASS_DEPTH_PASS, "STENCIL_BACK_PASS_DEPTH_PASS", GL_STENCIL_BACK_PASS_DEPTH_PASS }
|
|
};
|
|
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(stencilOps); testNdx++)
|
|
{
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpTestCase (m_context, verifier, (std::string("stencil_") + stencilOps[testNdx].name + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpTestCase (m_context, verifier, (std::string("stencil_back_") + stencilOps[testNdx].name + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget)));
|
|
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpSeparateTestCase (m_context, verifier, (std::string("stencil_") + stencilOps[testNdx].name + "_separate_both" + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget, GL_FRONT_AND_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpSeparateTestCase (m_context, verifier, (std::string("stencil_back_") + stencilOps[testNdx].name + "_separate_both" + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget, GL_FRONT_AND_BACK)));
|
|
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpSeparateTestCase (m_context, verifier, (std::string("stencil_") + stencilOps[testNdx].name + "_separate" + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget, GL_FRONT)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilOpSeparateTestCase (m_context, verifier, (std::string("stencil_back_") + stencilOps[testNdx].name + "_separate" + verifier->getTestNamePostfix()).c_str(), stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget, GL_BACK)));
|
|
}
|
|
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncTestCase (m_context, verifier, (std::string("stencil_func") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncSeparateTestCase (m_context, verifier, (std::string("stencil_func_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC (separate)", GL_STENCIL_FUNC, GL_FRONT)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncSeparateTestCase (m_context, verifier, (std::string("stencil_func_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC (separate)", GL_STENCIL_FUNC, GL_FRONT_AND_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncSeparateTestCase (m_context, verifier, (std::string("stencil_back_func_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC (separate)", GL_STENCIL_BACK_FUNC, GL_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilFuncSeparateTestCase (m_context, verifier, (std::string("stencil_back_func_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_FUNC (separate)", GL_STENCIL_BACK_FUNC, GL_FRONT_AND_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskTestCase (m_context, verifier, (std::string("stencil_value_mask") + verifier->getTestNamePostfix()).c_str(), "STENCIL_VALUE_MASK", GL_STENCIL_VALUE_MASK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskTestCase (m_context, verifier, (std::string("stencil_back_value_mask") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_VALUE_MASK", GL_STENCIL_BACK_VALUE_MASK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskSeparateTestCase (m_context, verifier, (std::string("stencil_value_mask_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_VALUE_MASK (separate)", GL_STENCIL_VALUE_MASK, GL_FRONT)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskSeparateTestCase (m_context, verifier, (std::string("stencil_value_mask_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_VALUE_MASK (separate)", GL_STENCIL_VALUE_MASK, GL_FRONT_AND_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskSeparateTestCase (m_context, verifier, (std::string("stencil_back_value_mask_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_VALUE_MASK (separate)", GL_STENCIL_BACK_VALUE_MASK, GL_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilMaskSeparateTestCase (m_context, verifier, (std::string("stencil_back_value_mask_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_VALUE_MASK (separate)", GL_STENCIL_BACK_VALUE_MASK, GL_FRONT_AND_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskTestCase (m_context, verifier, (std::string("stencil_writemask") + verifier->getTestNamePostfix()).c_str(), "STENCIL_WRITEMASK", GL_STENCIL_WRITEMASK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskTestCase (m_context, verifier, (std::string("stencil_back_writemask") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_WRITEMASK", GL_STENCIL_BACK_WRITEMASK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskSeparateTestCase (m_context, verifier, (std::string("stencil_writemask_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_WRITEMASK (separate)", GL_STENCIL_WRITEMASK, GL_FRONT)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskSeparateTestCase (m_context, verifier, (std::string("stencil_writemask_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_WRITEMASK (separate)", GL_STENCIL_WRITEMASK, GL_FRONT_AND_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskSeparateTestCase (m_context, verifier, (std::string("stencil_back_writemask_separate") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_WRITEMASK (separate)", GL_STENCIL_BACK_WRITEMASK, GL_BACK)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilWriteMaskSeparateTestCase (m_context, verifier, (std::string("stencil_back_writemask_separate_both") + verifier->getTestNamePostfix()).c_str(), "STENCIL_BACK_WRITEMASK (separate)", GL_STENCIL_BACK_WRITEMASK, GL_FRONT_AND_BACK)));
|
|
|
|
const struct PixelStoreState
|
|
{
|
|
const char* name;
|
|
const char* description;
|
|
GLenum target;
|
|
int initialValue;
|
|
} pixelStoreStates[] =
|
|
{
|
|
{ "unpack_image_height","UNPACK_IMAGE_HEIGHT", GL_UNPACK_IMAGE_HEIGHT, 0 },
|
|
{ "unpack_skip_images", "UNPACK_SKIP_IMAGES", GL_UNPACK_SKIP_IMAGES, 0 },
|
|
{ "unpack_row_length", "UNPACK_ROW_LENGTH", GL_UNPACK_ROW_LENGTH, 0 },
|
|
{ "unpack_skip_rows", "UNPACK_SKIP_ROWS", GL_UNPACK_SKIP_ROWS, 0 },
|
|
{ "unpack_skip_pixels", "UNPACK_SKIP_PIXELS", GL_UNPACK_SKIP_PIXELS, 0 },
|
|
{ "pack_row_length", "PACK_ROW_LENGTH", GL_PACK_ROW_LENGTH, 0 },
|
|
{ "pack_skip_rows", "PACK_SKIP_ROWS", GL_PACK_SKIP_ROWS, 0 },
|
|
{ "pack_skip_pixels", "PACK_SKIP_PIXELS", GL_PACK_SKIP_PIXELS, 0 }
|
|
};
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(pixelStoreStates); testNdx++)
|
|
{
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new PixelStoreTestCase(m_context, verifier, (std::string(pixelStoreStates[testNdx].name) + verifier->getTestNamePostfix()).c_str(), pixelStoreStates[testNdx].description, pixelStoreStates[testNdx].target, pixelStoreStates[testNdx].initialValue)));
|
|
}
|
|
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new PixelStoreAlignTestCase(m_context, verifier, (std::string("unpack_alignment") + verifier->getTestNamePostfix()).c_str(), "UNPACK_ALIGNMENT", GL_UNPACK_ALIGNMENT)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new PixelStoreAlignTestCase(m_context, verifier, (std::string("pack_alignment") + verifier->getTestNamePostfix()).c_str(), "PACK_ALIGNMENT", GL_PACK_ALIGNMENT)));
|
|
|
|
const struct BlendColorState
|
|
{
|
|
const char* name;
|
|
const char* description;
|
|
GLenum target;
|
|
int initialValue;
|
|
} blendColorStates[] =
|
|
{
|
|
{ "blend_src_rgb", "BLEND_SRC_RGB", GL_BLEND_SRC_RGB, GL_ONE },
|
|
{ "blend_src_alpha", "BLEND_SRC_ALPHA", GL_BLEND_SRC_ALPHA, GL_ONE },
|
|
{ "blend_dst_rgb", "BLEND_DST_RGB", GL_BLEND_DST_RGB, GL_ZERO },
|
|
{ "blend_dst_alpha", "BLEND_DST_ALPHA", GL_BLEND_DST_ALPHA, GL_ZERO }
|
|
};
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(blendColorStates); testNdx++)
|
|
{
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new BlendFuncTestCase (m_context, verifier, (std::string(blendColorStates[testNdx].name) + verifier->getTestNamePostfix()).c_str(), blendColorStates[testNdx].description, blendColorStates[testNdx].target, blendColorStates[testNdx].initialValue)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new BlendFuncSeparateTestCase (m_context, verifier, (std::string(blendColorStates[testNdx].name) + "_separate" + verifier->getTestNamePostfix()).c_str(), blendColorStates[testNdx].description, blendColorStates[testNdx].target, blendColorStates[testNdx].initialValue)));
|
|
}
|
|
|
|
const struct BlendEquationState
|
|
{
|
|
const char* name;
|
|
const char* description;
|
|
GLenum target;
|
|
int initialValue;
|
|
} blendEquationStates[] =
|
|
{
|
|
{ "blend_equation_rgb", "BLEND_EQUATION_RGB", GL_BLEND_EQUATION_RGB, GL_FUNC_ADD },
|
|
{ "blend_equation_alpha", "BLEND_EQUATION_ALPHA", GL_BLEND_EQUATION_ALPHA, GL_FUNC_ADD }
|
|
};
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(blendEquationStates); testNdx++)
|
|
{
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new BlendEquationTestCase (m_context, verifier, (std::string(blendEquationStates[testNdx].name) + + verifier->getTestNamePostfix()).c_str(), blendEquationStates[testNdx].description, blendEquationStates[testNdx].target, blendEquationStates[testNdx].initialValue)));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new BlendEquationSeparateTestCase (m_context, verifier, (std::string(blendEquationStates[testNdx].name) + "_separate" + verifier->getTestNamePostfix()).c_str(), blendEquationStates[testNdx].description, blendEquationStates[testNdx].target, blendEquationStates[testNdx].initialValue)));
|
|
}
|
|
|
|
const struct ImplementationArrayReturningState
|
|
{
|
|
const char* name;
|
|
const char* description;
|
|
GLenum target;
|
|
GLenum targetLengthTarget;
|
|
int minLength;
|
|
} implementationArrayReturningStates[] =
|
|
{
|
|
{ "compressed_texture_formats", "COMPRESSED_TEXTURE_FORMATS", GL_COMPRESSED_TEXTURE_FORMATS, GL_NUM_COMPRESSED_TEXTURE_FORMATS, 10 },
|
|
{ "program_binary_formats", "PROGRAM_BINARY_FORMATS", GL_PROGRAM_BINARY_FORMATS, GL_NUM_PROGRAM_BINARY_FORMATS, 0 },
|
|
{ "shader_binary_formats", "SHADER_BINARY_FORMATS", GL_SHADER_BINARY_FORMATS, GL_NUM_SHADER_BINARY_FORMATS, 0 }
|
|
};
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationArrayReturningStates); testNdx++)
|
|
{
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new ImplementationArrayTestCase(m_context, verifier, (std::string(implementationArrayReturningStates[testNdx].name) + verifier->getTestNamePostfix()).c_str(), implementationArrayReturningStates[testNdx].description, implementationArrayReturningStates[testNdx].target, implementationArrayReturningStates[testNdx].targetLengthTarget, implementationArrayReturningStates[testNdx].minLength)));
|
|
}
|
|
|
|
const struct BufferBindingState
|
|
{
|
|
const char* name;
|
|
const char* description;
|
|
GLenum target;
|
|
GLenum type;
|
|
} bufferBindingStates[] =
|
|
{
|
|
{ "array_buffer_binding", "ARRAY_BUFFER_BINDING", GL_ARRAY_BUFFER_BINDING, GL_ARRAY_BUFFER },
|
|
{ "uniform_buffer_binding", "UNIFORM_BUFFER_BINDING", GL_UNIFORM_BUFFER_BINDING, GL_UNIFORM_BUFFER },
|
|
{ "pixel_pack_buffer_binding", "PIXEL_PACK_BUFFER_BINDING", GL_PIXEL_PACK_BUFFER_BINDING, GL_PIXEL_PACK_BUFFER },
|
|
{ "pixel_unpack_buffer_binding", "PIXEL_UNPACK_BUFFER_BINDING", GL_PIXEL_UNPACK_BUFFER_BINDING, GL_PIXEL_UNPACK_BUFFER },
|
|
{ "transform_feedback_buffer_binding", "TRANSFORM_FEEDBACK_BUFFER_BINDING", GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_TRANSFORM_FEEDBACK_BUFFER},
|
|
{ "copy_read_buffer_binding", "COPY_READ_BUFFER_BINDING", GL_COPY_READ_BUFFER_BINDING, GL_COPY_READ_BUFFER },
|
|
{ "copy_write_buffer_binding", "COPY_WRITE_BUFFER_BINDING", GL_COPY_WRITE_BUFFER_BINDING, GL_COPY_WRITE_BUFFER }
|
|
};
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(bufferBindingStates); testNdx++)
|
|
{
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new BufferBindingTestCase(m_context, queryType, (std::string(bufferBindingStates[testNdx].name) + getQueryTypeSuffix(queryType)).c_str(), bufferBindingStates[testNdx].description, bufferBindingStates[testNdx].target, bufferBindingStates[testNdx].type)));
|
|
}
|
|
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new ElementArrayBufferBindingTestCase (m_context, queryType, (std::string("element_array_buffer_binding") + getQueryTypeSuffix(queryType)).c_str())));
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new TransformFeedbackBindingTestCase (m_context, queryType, (std::string("transform_feedback_binding") + getQueryTypeSuffix(queryType)).c_str())));
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new CurrentProgramBindingTestCase (m_context, queryType, (std::string("current_program_binding") + getQueryTypeSuffix(queryType)).c_str(), "CURRENT_PROGRAM")));
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new VertexArrayBindingTestCase (m_context, queryType, (std::string("vertex_array_binding") + getQueryTypeSuffix(queryType)).c_str(), "VERTEX_ARRAY_BINDING")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new StencilClearValueTestCase (m_context, verifier, (std::string("stencil_clear_value") + verifier->getTestNamePostfix()).c_str(), "STENCIL_CLEAR_VALUE")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new ActiveTextureTestCase (m_context, verifier, (std::string("active_texture") + verifier->getTestNamePostfix()).c_str(), "ACTIVE_TEXTURE")));
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new RenderbufferBindingTestCase (m_context, queryType, (std::string("renderbuffer_binding") + getQueryTypeSuffix(queryType)).c_str(), "RENDERBUFFER_BINDING")));
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new SamplerObjectBindingTestCase (m_context, queryType, (std::string("sampler_binding") + getQueryTypeSuffix(queryType)).c_str(), "SAMPLER_BINDING")));
|
|
|
|
const struct TextureBinding
|
|
{
|
|
const char* name;
|
|
const char* description;
|
|
GLenum target;
|
|
GLenum type;
|
|
} textureBindings[] =
|
|
{
|
|
{ "texture_binding_2d", "TEXTURE_BINDING_2D", GL_TEXTURE_BINDING_2D, GL_TEXTURE_2D },
|
|
{ "texture_binding_3d", "TEXTURE_BINDING_3D", GL_TEXTURE_BINDING_3D, GL_TEXTURE_3D },
|
|
{ "texture_binding_2d_array", "TEXTURE_BINDING_2D_ARRAY", GL_TEXTURE_BINDING_2D_ARRAY, GL_TEXTURE_2D_ARRAY },
|
|
{ "texture_binding_cube_map", "TEXTURE_BINDING_CUBE_MAP", GL_TEXTURE_BINDING_CUBE_MAP, GL_TEXTURE_CUBE_MAP }
|
|
};
|
|
|
|
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(textureBindings); testNdx++)
|
|
{
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new TextureBindingTestCase(m_context, queryType, (std::string(textureBindings[testNdx].name) + getQueryTypeSuffix(queryType)).c_str(), textureBindings[testNdx].description, textureBindings[testNdx].target, textureBindings[testNdx].type)));
|
|
}
|
|
|
|
|
|
FOR_EACH_QUERYTYPE(queryTypes, addChild(new FrameBufferBindingTestCase (m_context, queryType, (std::string("framebuffer_binding") + getQueryTypeSuffix(queryType)).c_str(), "DRAW_FRAMEBUFFER_BINDING and READ_FRAMEBUFFER_BINDING")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new ImplementationColorReadTestCase (m_context, verifier, (std::string("implementation_color_read") + verifier->getTestNamePostfix()).c_str(), "IMPLEMENTATION_COLOR_READ_TYPE and IMPLEMENTATION_COLOR_READ_FORMAT")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new ReadBufferCase (m_context, verifier, (std::string("read_buffer") + verifier->getTestNamePostfix()).c_str(), "READ_BUFFER")));
|
|
FOR_EACH_VERIFIER(normalVerifiers, addChild(new DrawBufferCase (m_context, verifier, (std::string("draw_buffer") + verifier->getTestNamePostfix()).c_str(), "DRAW_BUFFER")));
|
|
}
|
|
|
|
void IntegerStateQueryTests::deinit (void)
|
|
{
|
|
if (m_verifierBoolean)
|
|
{
|
|
delete m_verifierBoolean;
|
|
m_verifierBoolean = DE_NULL;
|
|
}
|
|
if (m_verifierInteger)
|
|
{
|
|
delete m_verifierInteger;
|
|
m_verifierInteger = DE_NULL;
|
|
}
|
|
if (m_verifierInteger64)
|
|
{
|
|
delete m_verifierInteger64;
|
|
m_verifierInteger64 = DE_NULL;
|
|
}
|
|
if (m_verifierFloat)
|
|
{
|
|
delete m_verifierFloat;
|
|
m_verifierFloat = DE_NULL;
|
|
}
|
|
|
|
this->TestCaseGroup::deinit();
|
|
}
|
|
|
|
} // Functional
|
|
} // gles3
|
|
} // deqp
|