| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES 2.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 "es2sVertexArrayTests.hpp" |
| #include "glsVertexArrayTests.hpp" |
| |
| #include "glwEnums.hpp" |
| |
| using namespace deqp::gls; |
| |
| namespace deqp |
| { |
| namespace gles2 |
| { |
| namespace Stress |
| { |
| namespace |
| { |
| |
| template<class T> |
| static std::string typeToString (T t) |
| { |
| std::stringstream strm; |
| strm << t; |
| return strm.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}; |
| int counts[] = {1, 256}; |
| int strides[] = {17}; |
| 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++) |
| { |
| for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++) |
| { |
| const int componentCount = 2; |
| const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount : strides[strideNdx]); |
| const bool aligned = (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0; |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], |
| Array::OUTPUTTYPE_VEC2, |
| Array::STORAGE_BUFFER, |
| usages[usageNdx], |
| componentCount, |
| 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); |
| |
| std::string name = spec.getName(); |
| |
| if (!aligned) |
| 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) |
| { |
| // Test strides with different input types, component counts and storage, Usage(?) |
| Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED}; |
| Array::Storage storages[] = {Array::STORAGE_BUFFER}; |
| int counts[] = {1, 256}; |
| int strides[] = {17}; |
| |
| for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) |
| { |
| 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 int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount : strides[strideNdx]); |
| const bool bufferUnaligned = (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) != 0; |
| |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], |
| Array::OUTPUTTYPE_VEC4, |
| storages[storageNdx], |
| Array::USAGE_DYNAMIC_DRAW, |
| componentCount, |
| 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); |
| |
| std::string name = spec.getName(); |
| if (bufferUnaligned) |
| 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 atribute different first values") |
| { |
| } |
| |
| SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void) |
| { |
| } |
| |
| void SingleVertexArrayFirstTests::init (void) |
| { |
| // Test strides with different input types, component counts and storage, Usage(?) |
| Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED}; |
| 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 inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) |
| { |
| 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 int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]); |
| const bool aligned = ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) && (offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx]) == 0); |
| |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], |
| Array::OUTPUTTYPE_VEC2, |
| Array::STORAGE_BUFFER, |
| Array::USAGE_DYNAMIC_DRAW, |
| 2, |
| offsets[offsetNdx], |
| stride, |
| false, |
| GLValue::getMinValue(inputTypes[inputTypeNdx]), |
| GLValue::getMaxValue(inputTypes[inputTypeNdx])); |
| |
| MultiVertexArrayTest::Spec spec; |
| spec.primitive = Array::PRIMITIVE_TRIANGLES; |
| spec.drawCount = counts[countNdx]; |
| spec.first = firsts[firstNdx]; |
| spec.arrays.push_back(arraySpec); |
| |
| std::string name = Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]); |
| 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 strides with different input types, component counts and storage, Usage(?) |
| Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED}; |
| 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 inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) |
| { |
| 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 int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]); |
| const bool aligned = ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) && ((offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0); |
| |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], |
| Array::OUTPUTTYPE_VEC2, |
| Array::STORAGE_BUFFER, |
| Array::USAGE_DYNAMIC_DRAW, |
| 2, |
| offsets[offsetNdx], |
| 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); |
| |
| std::string name = spec.getName(); |
| if (!aligned) |
| addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); |
| } |
| } |
| } |
| } |
| } |
| |
| } // 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 |
| } // gles2 |
| } // deqp |