/*-------------------------------------------------------------------------
* drawElements Quality Program OpenGL ES 3.1 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 Vertex attribute binding state query tests.
*//*--------------------------------------------------------------------*/
#include "es31fVertexAttributeBindingStateQueryTests.hpp"
#include "tcuTestLog.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluRenderContext.hpp"
#include "gluObjectWrapper.hpp"
#include "gluStrUtil.hpp"
#include "glsStateQueryUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "glsStateQueryUtil.hpp"
#include "deRandom.hpp"
namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{
using namespace gls::StateQueryUtil;
class AttributeCase : public TestCase
{
public:
AttributeCase (Context& context, const char* name, const char* desc, QueryType verifier);
IterateResult iterate (void);
virtual void test (tcu::ResultCollector& result) = 0;
protected:
const QueryType m_verifier;
};
AttributeCase::AttributeCase (Context& context, const char* name, const char* desc, QueryType verifier)
: TestCase (context, name, desc)
, m_verifier (verifier)
{
}
AttributeCase::IterateResult AttributeCase::iterate (void)
{
tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
test(result);
result.setTestContextResult(m_testCtx);
return STOP;
}
class AttributeBindingCase : public AttributeCase
{
public:
AttributeBindingCase (Context& context, const char* name, const char* desc, QueryType verifier);
void test (tcu::ResultCollector& result);
};
AttributeBindingCase::AttributeBindingCase (Context& context, const char* name, const char* desc, QueryType verifier)
: AttributeCase(context, name, desc, verifier)
{
}
void AttributeBindingCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::VertexArray vao (m_context.getRenderContext());
glw::GLint maxAttrs = -1;
gl.enableLogging(true);
gl.glBindVertexArray(*vao);
gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrs);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
// initial
{
const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
for (int attr = 0; attr < de::max(16, maxAttrs); ++attr)
verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_BINDING, attr, attr, m_verifier);
}
// is part of vao
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state");
glu::VertexArray otherVao (m_context.getRenderContext());
// set to value A in vao1
gl.glVertexAttribBinding(1, 4);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribBinding");
// set to value B in vao2
gl.glBindVertexArray(*otherVao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
gl.glVertexAttribBinding(1, 7);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribBinding");
// check value is still ok in original vao
gl.glBindVertexArray(*vao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_BINDING, 1, 4, m_verifier);
}
// random values
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values");
de::Random rnd (0xabc);
const int numRandomTests = 10;
for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
{
// switch random va to random binding
const int va = rnd.getInt(0, de::max(16, maxAttrs)-1);
const int binding = rnd.getInt(0, 16);
gl.glVertexAttribBinding(va, binding);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribBinding");
verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_BINDING, va, binding, m_verifier);
}
}
}
class AttributeRelativeOffsetCase : public AttributeCase
{
public:
AttributeRelativeOffsetCase (Context& context, const char* name, const char* desc, QueryType verifier);
void test (tcu::ResultCollector& result);
};
AttributeRelativeOffsetCase::AttributeRelativeOffsetCase (Context& context, const char* name, const char* desc, QueryType verifier)
: AttributeCase(context, name, desc, verifier)
{
}
void AttributeRelativeOffsetCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::VertexArray vao (m_context.getRenderContext());
glw::GLint maxAttrs = -1;
gl.enableLogging(true);
gl.glBindVertexArray(*vao);
gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrs);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
// initial
{
const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
for (int attr = 0; attr < de::max(16, maxAttrs); ++attr)
verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, attr, 0, m_verifier);
}
// is part of vao
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state");
glu::VertexArray otherVao (m_context.getRenderContext());
// set to value A in vao1
gl.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 9);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
// set to value B in vao2
gl.glBindVertexArray(*otherVao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
gl.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 21);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
// check value is still ok in original vao
gl.glBindVertexArray(*vao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 1, 9, m_verifier);
}
// random values
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values");
de::Random rnd (0xabc);
const int numRandomTests = 10;
for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
{
const int va = rnd.getInt(0, de::max(16, maxAttrs)-1);
const int offset = rnd.getInt(0, 2047);
gl.glVertexAttribFormat(va, 4, GL_FLOAT, GL_FALSE, offset);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, va, offset, m_verifier);
}
}
}
class IndexedCase : public TestCase
{
public:
IndexedCase (Context& context, const char* name, const char* desc, QueryType verifier);
IterateResult iterate (void);
virtual void test (tcu::ResultCollector& result) = 0;
protected:
const QueryType m_verifier;
};
IndexedCase::IndexedCase (Context& context, const char* name, const char* desc, QueryType verifier)
: TestCase (context, name, desc)
, m_verifier (verifier)
{
}
IndexedCase::IterateResult IndexedCase::iterate (void)
{
tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
test(result);
result.setTestContextResult(m_testCtx);
return STOP;
}
class VertexBindingDivisorCase : public IndexedCase
{
public:
VertexBindingDivisorCase (Context& context, const char* name, const char* desc, QueryType verifier);
void test (tcu::ResultCollector& result);
};
VertexBindingDivisorCase::VertexBindingDivisorCase (Context& context, const char* name, const char* desc, QueryType verifier)
: IndexedCase(context, name, desc, verifier)
{
}
void VertexBindingDivisorCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::VertexArray vao (m_context.getRenderContext());
glw::GLint reportedMaxBindings = -1;
glw::GLint maxBindings;
gl.enableLogging(true);
gl.glBindVertexArray(*vao);
gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
maxBindings = de::max(16, reportedMaxBindings);
// initial
{
const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
for (int binding = 0; binding < maxBindings; ++binding)
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, binding, 0, m_verifier);
}
// is part of vao
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state");
glu::VertexArray otherVao (m_context.getRenderContext());
// set to value A in vao1
gl.glVertexBindingDivisor(1, 4);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
// set to value B in vao2
gl.glBindVertexArray(*otherVao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
gl.glVertexBindingDivisor(1, 9);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
// check value is still ok in original vao
gl.glBindVertexArray(*vao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, 1, 4, m_verifier);
}
// random values
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values");
de::Random rnd (0xabc);
const int numRandomTests = 10;
for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
{
const int binding = rnd.getInt(0, maxBindings-1);
const int divisor = rnd.getInt(0, 2047);
gl.glVertexBindingDivisor(binding, divisor);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, binding, divisor, m_verifier);
}
}
}
class VertexBindingOffsetCase : public IndexedCase
{
public:
VertexBindingOffsetCase (Context& context, const char* name, const char* desc, QueryType verifier);
void test (tcu::ResultCollector& result);
};
VertexBindingOffsetCase::VertexBindingOffsetCase (Context& context, const char* name, const char* desc, QueryType verifier)
: IndexedCase(context, name, desc, verifier)
{
}
void VertexBindingOffsetCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::VertexArray vao (m_context.getRenderContext());
glu::Buffer buffer (m_context.getRenderContext());
glw::GLint reportedMaxBindings = -1;
glw::GLint maxBindings;
gl.enableLogging(true);
gl.glBindVertexArray(*vao);
gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
maxBindings = de::max(16, reportedMaxBindings);
// initial
{
const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
for (int binding = 0; binding < maxBindings; ++binding)
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, binding, 0, m_verifier);
}
// is part of vao
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state");
glu::VertexArray otherVao (m_context.getRenderContext());
// set to value A in vao1
gl.glBindVertexBuffer(1, *buffer, 4, 32);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
// set to value B in vao2
gl.glBindVertexArray(*otherVao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
gl.glBindVertexBuffer(1, *buffer, 13, 32);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
// check value is still ok in original vao
gl.glBindVertexArray(*vao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, 1, 4, m_verifier);
}
// random values
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values");
de::Random rnd (0xabc);
const int numRandomTests = 10;
for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
{
const int binding = rnd.getInt(0, maxBindings-1);
const int offset = rnd.getInt(0, 4000);
gl.glBindVertexBuffer(binding, *buffer, offset, 32);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, binding, offset, m_verifier);
}
}
}
class VertexBindingStrideCase : public IndexedCase
{
public:
VertexBindingStrideCase (Context& context, const char* name, const char* desc, QueryType verifier);
void test (tcu::ResultCollector& result);
};
VertexBindingStrideCase::VertexBindingStrideCase (Context& context, const char* name, const char* desc, QueryType verifier)
: IndexedCase(context, name, desc, verifier)
{
}
void VertexBindingStrideCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::VertexArray vao (m_context.getRenderContext());
glu::Buffer buffer (m_context.getRenderContext());
glw::GLint reportedMaxBindings = -1;
glw::GLint maxBindings;
gl.enableLogging(true);
gl.glBindVertexArray(*vao);
gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
maxBindings = de::max(16, reportedMaxBindings);
// initial
{
const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
for (int binding = 0; binding < maxBindings; ++binding)
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, binding, 16, m_verifier);
}
// is part of vao
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state");
glu::VertexArray otherVao (m_context.getRenderContext());
// set to value A in vao1
gl.glBindVertexBuffer(1, *buffer, 0, 32);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
// set to value B in vao2
gl.glBindVertexArray(*otherVao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
gl.glBindVertexBuffer(1, *buffer, 0, 64);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
// check value is still ok in original vao
gl.glBindVertexArray(*vao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 32, m_verifier);
}
// random values
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values");
de::Random rnd (0xabc);
const int numRandomTests = 10;
for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
{
const int binding = rnd.getInt(0, maxBindings-1);
const int stride = rnd.getInt(0, 2048);
gl.glBindVertexBuffer(binding, *buffer, 0, stride);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, binding, stride, m_verifier);
}
}
}
class VertexBindingBufferCase : public IndexedCase
{
public:
VertexBindingBufferCase (Context& context, const char* name, const char* desc, QueryType verifier);
void test (tcu::ResultCollector& result);
};
VertexBindingBufferCase::VertexBindingBufferCase (Context& context, const char* name, const char* desc, QueryType verifier)
: IndexedCase(context, name, desc, verifier)
{
}
void VertexBindingBufferCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::VertexArray vao (m_context.getRenderContext());
glu::Buffer buffer (m_context.getRenderContext());
glw::GLint reportedMaxBindings = -1;
glw::GLint maxBindings;
gl.enableLogging(true);
gl.glBindVertexArray(*vao);
gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
maxBindings = de::max(16, reportedMaxBindings);
// initial
{
const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
for (int binding = 0; binding < maxBindings; ++binding)
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, binding, 0, m_verifier);
}
// is part of vao
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "vao", "VAO state");
glu::VertexArray otherVao (m_context.getRenderContext());
glu::Buffer otherBuffer (m_context.getRenderContext());
// set to value A in vao1
gl.glBindVertexBuffer(1, *buffer, 0, 32);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
// set to value B in vao2
gl.glBindVertexArray(*otherVao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
gl.glBindVertexBuffer(1, *otherBuffer, 0, 32);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
// check value is still ok in original vao
gl.glBindVertexArray(*vao);
GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, *buffer, m_verifier);
}
// Is detached in delete from active vao and not from deactive
{
const tcu::ScopedLogSection section (m_testCtx.getLog(), "autoUnbind", "Unbind on delete");
glu::VertexArray otherVao (m_context.getRenderContext());
glw::GLuint otherBuffer = -1;
gl.glGenBuffers(1, &otherBuffer);
// set in vao1 and vao2
gl.glBindVertexBuffer(1, otherBuffer, 0, 32);
gl.glBindVertexArray(*otherVao);
gl.glBindVertexBuffer(1, otherBuffer, 0, 32);
// delete buffer. This unbinds it from active (vao2) but not from unactive
gl.glDeleteBuffers(1, &otherBuffer);
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, 0, m_verifier);
gl.glBindVertexArray(*vao);
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, otherBuffer, m_verifier);
}
}
class MixedVertexBindingDivisorCase : public IndexedCase
{
public:
MixedVertexBindingDivisorCase (Context& context, const char* name, const char* desc);
void test (tcu::ResultCollector& result);
};
MixedVertexBindingDivisorCase::MixedVertexBindingDivisorCase (Context& context, const char* name, const char* desc)
: IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
{
}
void MixedVertexBindingDivisorCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::VertexArray vao (m_context.getRenderContext());
gl.enableLogging(true);
gl.glBindVertexArray(*vao);
gl.glVertexAttribDivisor(1, 4);
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, 1, 4, m_verifier);
}
class MixedVertexBindingOffsetCase : public IndexedCase
{
public:
MixedVertexBindingOffsetCase (Context& context, const char* name, const char* desc);
void test (tcu::ResultCollector& result);
};
MixedVertexBindingOffsetCase::MixedVertexBindingOffsetCase (Context& context, const char* name, const char* desc)
: IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
{
}
void MixedVertexBindingOffsetCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::Buffer buffer (m_context.getRenderContext());
gl.enableLogging(true);
gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, glu::BufferOffsetAsPointer(12));
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, 1, 12, m_verifier);
}
class MixedVertexBindingStrideCase : public IndexedCase
{
public:
MixedVertexBindingStrideCase (Context& context, const char* name, const char* desc);
void test (tcu::ResultCollector& result);
};
MixedVertexBindingStrideCase::MixedVertexBindingStrideCase (Context& context, const char* name, const char* desc)
: IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
{
}
void MixedVertexBindingStrideCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::Buffer buffer (m_context.getRenderContext());
gl.enableLogging(true);
gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 12, 0);
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 12, m_verifier);
// test effectiveStride
gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 16, m_verifier);
}
class MixedVertexBindingBufferCase : public IndexedCase
{
public:
MixedVertexBindingBufferCase (Context& context, const char* name, const char* desc);
void test (tcu::ResultCollector& result);
};
MixedVertexBindingBufferCase::MixedVertexBindingBufferCase (Context& context, const char* name, const char* desc)
: IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
{
}
void MixedVertexBindingBufferCase::test (tcu::ResultCollector& result)
{
glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
glu::Buffer buffer (m_context.getRenderContext());
gl.enableLogging(true);
gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, *buffer, m_verifier);
}
} // anonymous
VertexAttributeBindingStateQueryTests::VertexAttributeBindingStateQueryTests (Context& context)
: TestCaseGroup(context, "vertex_attribute_binding", "Query vertex attribute binding state.")
{
}
VertexAttributeBindingStateQueryTests::~VertexAttributeBindingStateQueryTests (void)
{
}
void VertexAttributeBindingStateQueryTests::init (void)
{
tcu::TestCaseGroup* const attributeGroup = new TestCaseGroup(m_context, "vertex_attrib", "Vertex attribute state");
tcu::TestCaseGroup* const indexedGroup = new TestCaseGroup(m_context, "indexed", "Indexed state");
addChild(attributeGroup);
addChild(indexedGroup);
// .vertex_attrib
{
static const struct Verifier
{
const char* suffix;
QueryType type;
} verifiers[] =
{
{ "", QUERY_ATTRIBUTE_INTEGER }, // avoid renaming tests
{ "_getvertexattribfv", QUERY_ATTRIBUTE_FLOAT },
{ "_getvertexattribiiv", QUERY_ATTRIBUTE_PURE_INTEGER },
{ "_getvertexattribiuiv", QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER },
};
for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
{
attributeGroup->addChild(new AttributeBindingCase (m_context, (std::string("vertex_attrib_binding") + verifiers[verifierNdx].suffix).c_str(), "Test VERTEX_ATTRIB_BINDING", verifiers[verifierNdx].type));
attributeGroup->addChild(new AttributeRelativeOffsetCase(m_context, (std::string("vertex_attrib_relative_offset") + verifiers[verifierNdx].suffix).c_str(), "Test VERTEX_ATTRIB_RELATIVE_OFFSET", verifiers[verifierNdx].type));
}
}
// .indexed
{
static const struct Verifier
{
const char* name;
QueryType type;
} verifiers[] =
{
{ "getintegeri", QUERY_INDEXED_INTEGER },
{ "getintegeri64", QUERY_INDEXED_INTEGER64 },
{ "getboolean", QUERY_INDEXED_BOOLEAN },
};
// states
for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
{
indexedGroup->addChild(new VertexBindingDivisorCase (m_context, (std::string("vertex_binding_divisor_") + verifiers[verifierNdx].name).c_str(), "Test VERTEX_BINDING_DIVISOR", verifiers[verifierNdx].type));
indexedGroup->addChild(new VertexBindingOffsetCase (m_context, (std::string("vertex_binding_offset_") + verifiers[verifierNdx].name).c_str(), "Test VERTEX_BINDING_OFFSET", verifiers[verifierNdx].type));
indexedGroup->addChild(new VertexBindingStrideCase (m_context, (std::string("vertex_binding_stride_") + verifiers[verifierNdx].name).c_str(), "Test VERTEX_BINDING_STRIDE", verifiers[verifierNdx].type));
indexedGroup->addChild(new VertexBindingBufferCase (m_context, (std::string("vertex_binding_buffer_") + verifiers[verifierNdx].name).c_str(), "Test VERTEX_BINDING_BUFFER", verifiers[verifierNdx].type));
}
// mixed apis
indexedGroup->addChild(new MixedVertexBindingDivisorCase(m_context, "vertex_binding_divisor_mixed", "Test VERTEX_BINDING_DIVISOR"));
indexedGroup->addChild(new MixedVertexBindingOffsetCase (m_context, "vertex_binding_offset_mixed", "Test VERTEX_BINDING_OFFSET"));
indexedGroup->addChild(new MixedVertexBindingStrideCase (m_context, "vertex_binding_stride_mixed", "Test VERTEX_BINDING_STRIDE"));
indexedGroup->addChild(new MixedVertexBindingBufferCase (m_context, "vertex_binding_buffer_mixed", "Test VERTEX_BINDING_BUFFER"));
}
}
} // Functional
} // gles31
} // deqp