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.
484 lines
17 KiB
484 lines
17 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 Vertex array and buffer unaligned access stress tests
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es3sVertexArrayTests.hpp"
|
|
#include "glsVertexArrayTests.hpp"
|
|
|
|
#include <sstream>
|
|
|
|
using namespace deqp::gls;
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles3
|
|
{
|
|
namespace Stress
|
|
{
|
|
namespace
|
|
{
|
|
|
|
|
|
class SingleVertexArrayUsageGroup : public TestCaseGroup
|
|
{
|
|
public:
|
|
SingleVertexArrayUsageGroup (Context& context, Array::Usage usage);
|
|
virtual ~SingleVertexArrayUsageGroup (void);
|
|
|
|
virtual void init (void);
|
|
|
|
private:
|
|
SingleVertexArrayUsageGroup (const SingleVertexArrayUsageGroup& other);
|
|
SingleVertexArrayUsageGroup& operator= (const SingleVertexArrayUsageGroup& other);
|
|
|
|
Array::Usage m_usage;
|
|
};
|
|
|
|
SingleVertexArrayUsageGroup::SingleVertexArrayUsageGroup (Context& context, Array::Usage usage)
|
|
: TestCaseGroup (context, Array::usageTypeToString(usage).c_str(), Array::usageTypeToString(usage).c_str())
|
|
, m_usage (usage)
|
|
{
|
|
}
|
|
|
|
SingleVertexArrayUsageGroup::~SingleVertexArrayUsageGroup (void)
|
|
{
|
|
}
|
|
|
|
template<class T>
|
|
static std::string typeToString (T t)
|
|
{
|
|
std::stringstream strm;
|
|
strm << t;
|
|
return strm.str();
|
|
}
|
|
|
|
void SingleVertexArrayUsageGroup::init (void)
|
|
{
|
|
int counts[] = {1, 256};
|
|
int strides[] = {0, -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
|
|
Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE};
|
|
|
|
for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
|
|
{
|
|
for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
|
|
{
|
|
for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
|
|
{
|
|
const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
|
|
const bool aligned = (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
|
|
const std::string name = "stride" + typeToString(stride) + "_" + Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_quads" + typeToString(counts[countNdx]);
|
|
|
|
MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
|
|
Array::OUTPUTTYPE_VEC2,
|
|
Array::STORAGE_BUFFER,
|
|
m_usage,
|
|
2,
|
|
0,
|
|
stride,
|
|
false,
|
|
GLValue::getMinValue(inputTypes[inputTypeNdx]),
|
|
GLValue::getMaxValue(inputTypes[inputTypeNdx]));
|
|
|
|
MultiVertexArrayTest::Spec spec;
|
|
spec.primitive = Array::PRIMITIVE_TRIANGLES;
|
|
spec.drawCount = counts[countNdx];
|
|
spec.first = 0;
|
|
spec.arrays.push_back(arraySpec);
|
|
|
|
if (!aligned)
|
|
addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class SingleVertexArrayUsageTests : public TestCaseGroup
|
|
{
|
|
public:
|
|
SingleVertexArrayUsageTests (Context& context);
|
|
virtual ~SingleVertexArrayUsageTests (void);
|
|
|
|
virtual void init (void);
|
|
|
|
private:
|
|
SingleVertexArrayUsageTests (const SingleVertexArrayUsageTests& other);
|
|
SingleVertexArrayUsageTests& operator= (const SingleVertexArrayUsageTests& other);
|
|
};
|
|
|
|
SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
|
|
: TestCaseGroup(context, "usages", "Single vertex atribute, usage")
|
|
{
|
|
}
|
|
|
|
SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
|
|
{
|
|
}
|
|
|
|
void SingleVertexArrayUsageTests::init (void)
|
|
{
|
|
// Test usage
|
|
Array::Usage usages[] = { Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW, Array::USAGE_STATIC_COPY, Array::USAGE_STREAM_COPY, Array::USAGE_DYNAMIC_COPY, Array::USAGE_STATIC_READ, Array::USAGE_STREAM_READ, Array::USAGE_DYNAMIC_READ };
|
|
for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
|
|
{
|
|
addChild(new SingleVertexArrayUsageGroup(m_context, usages[usageNdx]));
|
|
}
|
|
}
|
|
|
|
class SingleVertexArrayStrideGroup : public TestCaseGroup
|
|
{
|
|
public:
|
|
SingleVertexArrayStrideGroup (Context& context, Array::InputType type);
|
|
virtual ~SingleVertexArrayStrideGroup (void);
|
|
|
|
virtual void init (void);
|
|
|
|
private:
|
|
SingleVertexArrayStrideGroup (const SingleVertexArrayStrideGroup& other);
|
|
SingleVertexArrayStrideGroup& operator= (const SingleVertexArrayStrideGroup& other);
|
|
|
|
Array::InputType m_type;
|
|
};
|
|
|
|
SingleVertexArrayStrideGroup::SingleVertexArrayStrideGroup (Context& context, Array::InputType type)
|
|
: TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
|
|
, m_type (type)
|
|
{
|
|
}
|
|
|
|
SingleVertexArrayStrideGroup::~SingleVertexArrayStrideGroup (void)
|
|
{
|
|
}
|
|
|
|
void SingleVertexArrayStrideGroup::init (void)
|
|
{
|
|
Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER};
|
|
int counts[] = {1, 256};
|
|
int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
|
|
|
|
for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
|
|
{
|
|
for (int componentCount = 2; componentCount < 5; componentCount++)
|
|
{
|
|
for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
|
|
{
|
|
for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
|
|
{
|
|
const bool packed = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
|
|
const int stride = (strides[strideNdx] < 0) ? ((packed) ? (16) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
|
|
const int alignment = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
|
|
const bool bufferUnaligned = (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % alignment) != 0;
|
|
|
|
std::string name = Array::storageToString(storages[storageNdx]) + "_stride" + typeToString(stride) + "_components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]);
|
|
|
|
if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
|
|
continue;
|
|
|
|
MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
|
|
Array::OUTPUTTYPE_VEC4,
|
|
storages[storageNdx],
|
|
Array::USAGE_DYNAMIC_DRAW,
|
|
componentCount,
|
|
0,
|
|
stride,
|
|
false,
|
|
GLValue::getMinValue(m_type),
|
|
GLValue::getMaxValue(m_type));
|
|
|
|
MultiVertexArrayTest::Spec spec;
|
|
spec.primitive = Array::PRIMITIVE_TRIANGLES;
|
|
spec.drawCount = counts[countNdx];
|
|
spec.first = 0;
|
|
spec.arrays.push_back(arraySpec);
|
|
|
|
if (bufferUnaligned)
|
|
addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class SingleVertexArrayStrideTests : public TestCaseGroup
|
|
{
|
|
public:
|
|
SingleVertexArrayStrideTests (Context& context);
|
|
virtual ~SingleVertexArrayStrideTests (void);
|
|
|
|
virtual void init (void);
|
|
|
|
private:
|
|
SingleVertexArrayStrideTests (const SingleVertexArrayStrideTests& other);
|
|
SingleVertexArrayStrideTests& operator= (const SingleVertexArrayStrideTests& other);
|
|
};
|
|
|
|
SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
|
|
: TestCaseGroup(context, "strides", "Single stride vertex atribute")
|
|
{
|
|
}
|
|
|
|
SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
|
|
{
|
|
}
|
|
|
|
void SingleVertexArrayStrideTests::init (void)
|
|
{
|
|
Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED, Array::INPUTTYPE_INT_2_10_10_10 };
|
|
|
|
for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
|
|
{
|
|
addChild(new SingleVertexArrayStrideGroup(m_context, inputTypes[inputTypeNdx]));
|
|
}
|
|
}
|
|
|
|
class SingleVertexArrayFirstGroup : public TestCaseGroup
|
|
{
|
|
public:
|
|
SingleVertexArrayFirstGroup (Context& context, Array::InputType type);
|
|
virtual ~SingleVertexArrayFirstGroup (void);
|
|
|
|
virtual void init (void);
|
|
|
|
private:
|
|
SingleVertexArrayFirstGroup (const SingleVertexArrayFirstGroup& other);
|
|
SingleVertexArrayFirstGroup& operator= (const SingleVertexArrayFirstGroup& other);
|
|
Array::InputType m_type;
|
|
};
|
|
|
|
SingleVertexArrayFirstGroup::SingleVertexArrayFirstGroup (Context& context, Array::InputType type)
|
|
: TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
|
|
, m_type (type)
|
|
{
|
|
}
|
|
|
|
SingleVertexArrayFirstGroup::~SingleVertexArrayFirstGroup (void)
|
|
{
|
|
}
|
|
|
|
void SingleVertexArrayFirstGroup::init (void)
|
|
{
|
|
int counts[] = {5, 256};
|
|
int firsts[] = {6, 24};
|
|
int offsets[] = {1, 17};
|
|
int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
|
|
|
|
for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
|
|
{
|
|
for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
|
|
{
|
|
for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
|
|
{
|
|
for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
|
|
{
|
|
const bool packed = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
|
|
const int componentCount = (packed) ? (4) : (2);
|
|
const int stride = (strides[strideNdx] < 0) ? ((packed) ? (8) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
|
|
const int alignment = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
|
|
const bool aligned = ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
|
|
std::string name = "first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
|
|
|
|
MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
|
|
Array::OUTPUTTYPE_VEC2,
|
|
Array::STORAGE_BUFFER,
|
|
Array::USAGE_DYNAMIC_DRAW,
|
|
componentCount,
|
|
offsets[offsetNdx],
|
|
stride,
|
|
false,
|
|
GLValue::getMinValue(m_type),
|
|
GLValue::getMaxValue(m_type));
|
|
|
|
MultiVertexArrayTest::Spec spec;
|
|
spec.primitive = Array::PRIMITIVE_TRIANGLES;
|
|
spec.drawCount = counts[countNdx];
|
|
spec.first = firsts[firstNdx];
|
|
spec.arrays.push_back(arraySpec);
|
|
|
|
if (!aligned)
|
|
addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class SingleVertexArrayFirstTests : public TestCaseGroup
|
|
{
|
|
public:
|
|
SingleVertexArrayFirstTests (Context& context);
|
|
virtual ~SingleVertexArrayFirstTests (void);
|
|
|
|
virtual void init (void);
|
|
|
|
private:
|
|
SingleVertexArrayFirstTests (const SingleVertexArrayFirstTests& other);
|
|
SingleVertexArrayFirstTests& operator= (const SingleVertexArrayFirstTests& other);
|
|
};
|
|
|
|
SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
|
|
: TestCaseGroup(context, "first", "Single vertex attribute, different first values to drawArrays")
|
|
{
|
|
}
|
|
|
|
SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
|
|
{
|
|
}
|
|
|
|
void SingleVertexArrayFirstTests::init (void)
|
|
{
|
|
// Test offset with different input types, component counts and storage, Usage(?)
|
|
Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_INT_2_10_10_10 };
|
|
|
|
for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
|
|
{
|
|
addChild(new SingleVertexArrayFirstGroup(m_context, inputTypes[inputTypeNdx]));
|
|
}
|
|
}
|
|
|
|
class SingleVertexArrayOffsetGroup : public TestCaseGroup
|
|
{
|
|
public:
|
|
SingleVertexArrayOffsetGroup (Context& context, Array::InputType type);
|
|
virtual ~SingleVertexArrayOffsetGroup (void);
|
|
|
|
virtual void init (void);
|
|
|
|
private:
|
|
SingleVertexArrayOffsetGroup (const SingleVertexArrayOffsetGroup& other);
|
|
SingleVertexArrayOffsetGroup& operator= (const SingleVertexArrayOffsetGroup& other);
|
|
Array::InputType m_type;
|
|
};
|
|
|
|
SingleVertexArrayOffsetGroup::SingleVertexArrayOffsetGroup (Context& context, Array::InputType type)
|
|
: TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
|
|
, m_type (type)
|
|
{
|
|
}
|
|
|
|
SingleVertexArrayOffsetGroup::~SingleVertexArrayOffsetGroup (void)
|
|
{
|
|
}
|
|
|
|
void SingleVertexArrayOffsetGroup::init (void)
|
|
{
|
|
int counts[] = {1, 256};
|
|
int offsets[] = {1, 4, 17, 32};
|
|
int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
|
|
|
|
for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
|
|
{
|
|
for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
|
|
{
|
|
for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
|
|
{
|
|
const bool packed = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
|
|
const int componentCount = (packed) ? (4) : (2);
|
|
const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(m_type) * componentCount : strides[strideNdx]);
|
|
const int alignment = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
|
|
const bool aligned = ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
|
|
const std::string name = "offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(strides[strideNdx]) + "_quads" + typeToString(counts[countNdx]);
|
|
|
|
MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
|
|
Array::OUTPUTTYPE_VEC2,
|
|
Array::STORAGE_BUFFER,
|
|
Array::USAGE_DYNAMIC_DRAW,
|
|
componentCount,
|
|
offsets[offsetNdx],
|
|
stride,
|
|
false,
|
|
GLValue::getMinValue(m_type),
|
|
GLValue::getMaxValue(m_type));
|
|
|
|
MultiVertexArrayTest::Spec spec;
|
|
spec.primitive = Array::PRIMITIVE_TRIANGLES;
|
|
spec.drawCount = counts[countNdx];
|
|
spec.first = 0;
|
|
spec.arrays.push_back(arraySpec);
|
|
|
|
if (!aligned)
|
|
addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class SingleVertexArrayOffsetTests : public TestCaseGroup
|
|
{
|
|
public:
|
|
SingleVertexArrayOffsetTests (Context& context);
|
|
virtual ~SingleVertexArrayOffsetTests (void);
|
|
|
|
virtual void init (void);
|
|
|
|
private:
|
|
SingleVertexArrayOffsetTests (const SingleVertexArrayOffsetTests& other);
|
|
SingleVertexArrayOffsetTests& operator= (const SingleVertexArrayOffsetTests& other);
|
|
};
|
|
|
|
SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
|
|
: TestCaseGroup(context, "offset", "Single vertex atribute offset element")
|
|
{
|
|
}
|
|
|
|
SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
|
|
{
|
|
}
|
|
|
|
void SingleVertexArrayOffsetTests::init (void)
|
|
{
|
|
// Test offset with different input types, component counts and storage, Usage(?)
|
|
Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_INT_2_10_10_10 };
|
|
|
|
for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
|
|
{
|
|
addChild(new SingleVertexArrayOffsetGroup(m_context, inputTypes[inputTypeNdx]));
|
|
}
|
|
}
|
|
|
|
} // anonymous
|
|
|
|
VertexArrayTests::VertexArrayTests (Context& context)
|
|
: TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
|
|
{
|
|
}
|
|
|
|
VertexArrayTests::~VertexArrayTests (void)
|
|
{
|
|
}
|
|
|
|
void VertexArrayTests::init (void)
|
|
{
|
|
tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "single_attribute", "Single attribute");
|
|
addChild(group);
|
|
|
|
// .single_attribute
|
|
{
|
|
group->addChild(new SingleVertexArrayStrideTests(m_context));
|
|
group->addChild(new SingleVertexArrayUsageTests(m_context));
|
|
group->addChild(new SingleVertexArrayOffsetTests(m_context));
|
|
group->addChild(new SingleVertexArrayFirstTests(m_context));
|
|
}
|
|
}
|
|
|
|
} // Stress
|
|
} // gles3
|
|
} // deqp
|