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.
775 lines
25 KiB
775 lines
25 KiB
/*-------------------------------------------------------------------------
|
|
* 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
|