/*------------------------------------------------------------------------- * 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::RenderContext& renderContext = m_context.getRenderContext(); glu::CallLogWrapper gl (renderContext.getFunctions(), m_testCtx.getLog()); glu::Buffer buffer (renderContext); deUint32 vao = 0; gl.enableLogging(true); if (!glu::isContextTypeES(renderContext.getType())) { gl.glGenVertexArrays(1, &vao); gl.glBindVertexArray(vao); } 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); if (vao) gl.glDeleteVertexArrays(1, &vao); } 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::RenderContext& renderContext = m_context.getRenderContext(); glu::CallLogWrapper gl (renderContext.getFunctions(), m_testCtx.getLog()); glu::Buffer buffer (renderContext); deUint32 vao = 0; gl.enableLogging(true); if (!glu::isContextTypeES(renderContext.getType())) { gl.glGenVertexArrays(1, &vao); gl.glBindVertexArray(vao); } 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); if (vao) gl.glDeleteVertexArrays(1, &vao); } 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::RenderContext& renderContext = m_context.getRenderContext(); glu::CallLogWrapper gl (renderContext.getFunctions(), m_testCtx.getLog()); glu::Buffer buffer (renderContext); deUint32 vao = 0; gl.enableLogging(true); if (!glu::isContextTypeES(renderContext.getType())) { gl.glGenVertexArrays(1, &vao); gl.glBindVertexArray(vao); } 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); if (vao) gl.glDeleteVertexArrays(1, &vao); } } // 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