| /*------------------------------------------------------------------------- |
| * 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 tests |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "es3fVertexArrayTest.hpp" |
| #include "glsVertexArrayTests.hpp" |
| |
| #include <sstream> |
| |
| using namespace deqp::gls; |
| |
| namespace deqp |
| { |
| namespace gles3 |
| { |
| namespace Functional |
| { |
| |
| 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_BYTE, /*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, 16, 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_BYTE, 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(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 = 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_BYTE, 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])); |
| } |
| } |
| |
| class SingleVertexArrayNormalizeGroup : public TestCaseGroup |
| { |
| public: |
| SingleVertexArrayNormalizeGroup (Context& context, Array::InputType type); |
| virtual ~SingleVertexArrayNormalizeGroup (void); |
| |
| virtual void init (void); |
| |
| private: |
| SingleVertexArrayNormalizeGroup (const SingleVertexArrayNormalizeGroup& other); |
| SingleVertexArrayNormalizeGroup& operator= (const SingleVertexArrayNormalizeGroup& other); |
| Array::InputType m_type; |
| }; |
| |
| SingleVertexArrayNormalizeGroup::SingleVertexArrayNormalizeGroup (Context& context, Array::InputType type) |
| : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str()) |
| , m_type (type) |
| { |
| } |
| |
| SingleVertexArrayNormalizeGroup::~SingleVertexArrayNormalizeGroup (void) |
| { |
| } |
| |
| void SingleVertexArrayNormalizeGroup::init (void) |
| { |
| int counts[] = {1, 256}; |
| |
| for (int componentCount = 2; componentCount < 5; componentCount++) |
| { |
| for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(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; |
| |
| std::string name = "components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]); |
| |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type, |
| Array::OUTPUTTYPE_VEC4, |
| Array::STORAGE_USER, |
| Array::USAGE_DYNAMIC_DRAW, |
| componentCount, |
| 0, |
| 0, |
| true, |
| 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); |
| |
| addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); |
| } |
| } |
| } |
| |
| class SingleVertexArrayNormalizeTests : public TestCaseGroup |
| { |
| public: |
| SingleVertexArrayNormalizeTests (Context& context); |
| virtual ~SingleVertexArrayNormalizeTests (void); |
| |
| virtual void init (void); |
| |
| private: |
| SingleVertexArrayNormalizeTests (const SingleVertexArrayNormalizeTests& other); |
| SingleVertexArrayNormalizeTests& operator= (const SingleVertexArrayNormalizeTests& other); |
| }; |
| |
| SingleVertexArrayNormalizeTests::SingleVertexArrayNormalizeTests (Context& context) |
| : TestCaseGroup(context, "normalize", "Single normalize vertex atribute") |
| { |
| } |
| |
| SingleVertexArrayNormalizeTests::~SingleVertexArrayNormalizeTests (void) |
| { |
| } |
| |
| void SingleVertexArrayNormalizeTests::init (void) |
| { |
| // Test normalization with different input types, component counts and storage |
| Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_UNSIGNED_INT, Array::INPUTTYPE_INT, Array::INPUTTYPE_HALF , Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10, Array::INPUTTYPE_INT_2_10_10_10 }; |
| |
| for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) |
| { |
| addChild(new SingleVertexArrayNormalizeGroup(m_context, inputTypes[inputTypeNdx])); |
| } |
| } |
| |
| class SingleVertexArrayOutputTypeGroup : public TestCaseGroup |
| { |
| public: |
| SingleVertexArrayOutputTypeGroup (Context& context, Array::InputType type); |
| virtual ~SingleVertexArrayOutputTypeGroup (void); |
| |
| virtual void init (void); |
| |
| private: |
| SingleVertexArrayOutputTypeGroup (const SingleVertexArrayOutputTypeGroup& other); |
| SingleVertexArrayOutputTypeGroup& operator= (const SingleVertexArrayOutputTypeGroup& other); |
| Array::InputType m_type; |
| }; |
| |
| SingleVertexArrayOutputTypeGroup::SingleVertexArrayOutputTypeGroup (Context& context, Array::InputType type) |
| : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str()) |
| , m_type (type) |
| { |
| } |
| |
| SingleVertexArrayOutputTypeGroup::~SingleVertexArrayOutputTypeGroup (void) |
| { |
| } |
| |
| void SingleVertexArrayOutputTypeGroup::init (void) |
| { |
| Array::OutputType outputTypes[] = {Array::OUTPUTTYPE_VEC2, Array::OUTPUTTYPE_VEC3, Array::OUTPUTTYPE_VEC4, Array::OUTPUTTYPE_IVEC2, Array::OUTPUTTYPE_IVEC3, Array::OUTPUTTYPE_IVEC4, Array::OUTPUTTYPE_UVEC2, Array::OUTPUTTYPE_UVEC3, Array::OUTPUTTYPE_UVEC4 }; |
| Array::Storage storages[] = {Array::STORAGE_USER}; |
| int counts[] = {1, 256}; |
| |
| for (int outputTypeNdx = 0; outputTypeNdx < DE_LENGTH_OF_ARRAY(outputTypes); outputTypeNdx++) |
| { |
| 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++) |
| { |
| std::string name = "components" + typeToString(componentCount) + "_" + Array::outputTypeToString(outputTypes[outputTypeNdx]) + "_quads" + typeToString(counts[countNdx]); |
| |
| const bool inputIsSignedInteger = m_type == Array::INPUTTYPE_INT || m_type == Array::INPUTTYPE_SHORT || m_type == Array::INPUTTYPE_BYTE; |
| const bool inputIsUnignedInteger = m_type == Array::INPUTTYPE_UNSIGNED_INT || m_type == Array::INPUTTYPE_UNSIGNED_SHORT || m_type == Array::INPUTTYPE_UNSIGNED_BYTE; |
| const bool outputIsSignedInteger = outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC2 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC3 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC4; |
| const bool outputIsUnsignedInteger = outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC2 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC3 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC4; |
| |
| // If input type is float type and output type is int type skip |
| if ((m_type == Array::INPUTTYPE_FLOAT || m_type == Array::INPUTTYPE_HALF || m_type == Array::INPUTTYPE_FIXED) && (outputTypes[outputTypeNdx] >= Array::OUTPUTTYPE_INT)) |
| continue; |
| |
| if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && (outputTypes[outputTypeNdx] >= Array::OUTPUTTYPE_INT)) |
| continue; |
| |
| if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4) |
| continue; |
| |
| // Loading signed data as unsigned causes undefined values and vice versa |
| if (inputIsSignedInteger && outputIsUnsignedInteger) |
| continue; |
| if (inputIsUnignedInteger && outputIsSignedInteger) |
| continue; |
| |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type, |
| outputTypes[outputTypeNdx], |
| storages[storageNdx], |
| Array::USAGE_DYNAMIC_DRAW, |
| componentCount, |
| 0, |
| 0, |
| 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); |
| |
| addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); |
| } |
| } |
| } |
| } |
| } |
| |
| class SingleVertexArrayOutputTypeTests : public TestCaseGroup |
| { |
| public: |
| SingleVertexArrayOutputTypeTests (Context& context); |
| virtual ~SingleVertexArrayOutputTypeTests (void); |
| |
| virtual void init (void); |
| |
| private: |
| SingleVertexArrayOutputTypeTests (const SingleVertexArrayOutputTypeTests& other); |
| SingleVertexArrayOutputTypeTests& operator= (const SingleVertexArrayOutputTypeTests& other); |
| }; |
| |
| SingleVertexArrayOutputTypeTests::SingleVertexArrayOutputTypeTests (Context& context) |
| : TestCaseGroup(context, "output_types", "Single output type vertex atribute") |
| { |
| } |
| |
| SingleVertexArrayOutputTypeTests::~SingleVertexArrayOutputTypeTests (void) |
| { |
| } |
| |
| void SingleVertexArrayOutputTypeTests::init (void) |
| { |
| // Test output types with different input types, component counts and storage, Usage?, Precision?, float? |
| Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_UNSIGNED_INT, Array::INPUTTYPE_INT, Array::INPUTTYPE_HALF, Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10, Array::INPUTTYPE_INT_2_10_10_10 }; |
| |
| for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) |
| { |
| addChild(new SingleVertexArrayOutputTypeGroup(m_context, inputTypes[inputTypeNdx])); |
| } |
| } |
| |
| |
| class SingleVertexArrayTestGroup : public TestCaseGroup |
| { |
| public: |
| SingleVertexArrayTestGroup (Context& context); |
| virtual ~SingleVertexArrayTestGroup (void); |
| |
| virtual void init (void); |
| |
| private: |
| SingleVertexArrayTestGroup (const SingleVertexArrayTestGroup& other); |
| SingleVertexArrayTestGroup& operator= (const SingleVertexArrayTestGroup& other); |
| }; |
| |
| SingleVertexArrayTestGroup::SingleVertexArrayTestGroup (Context& context) |
| : TestCaseGroup(context, "single_attribute", "Single vertex atribute") |
| { |
| } |
| |
| SingleVertexArrayTestGroup::~SingleVertexArrayTestGroup (void) |
| { |
| } |
| |
| void SingleVertexArrayTestGroup::init (void) |
| { |
| addChild(new SingleVertexArrayStrideTests(m_context)); |
| addChild(new SingleVertexArrayNormalizeTests(m_context)); |
| addChild(new SingleVertexArrayOutputTypeTests(m_context)); |
| addChild(new SingleVertexArrayUsageTests(m_context)); |
| addChild(new SingleVertexArrayOffsetTests(m_context)); |
| addChild(new SingleVertexArrayFirstTests(m_context)); |
| } |
| |
| class MultiVertexArrayCountTests : public TestCaseGroup |
| { |
| public: |
| MultiVertexArrayCountTests (Context& context); |
| virtual ~MultiVertexArrayCountTests (void); |
| |
| virtual void init (void); |
| |
| private: |
| MultiVertexArrayCountTests (const MultiVertexArrayCountTests& other); |
| MultiVertexArrayCountTests& operator= (const MultiVertexArrayCountTests& other); |
| |
| std::string getTestName (const MultiVertexArrayTest::Spec& spec); |
| }; |
| |
| MultiVertexArrayCountTests::MultiVertexArrayCountTests (Context& context) |
| : TestCaseGroup(context, "attribute_count", "Attribute counts") |
| { |
| } |
| |
| MultiVertexArrayCountTests::~MultiVertexArrayCountTests (void) |
| { |
| } |
| |
| std::string MultiVertexArrayCountTests::getTestName (const MultiVertexArrayTest::Spec& spec) |
| { |
| std::stringstream name; |
| name |
| << spec.arrays.size(); |
| |
| return name.str(); |
| } |
| |
| void MultiVertexArrayCountTests::init (void) |
| { |
| // Test attribute counts |
| int arrayCounts[] = {2, 3, 4, 5, 6, 7, 8}; |
| |
| for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++) |
| { |
| MultiVertexArrayTest::Spec spec; |
| |
| spec.primitive = Array::PRIMITIVE_TRIANGLES; |
| spec.drawCount = 256; |
| spec.first = 0; |
| |
| for (int arrayNdx = 0; arrayNdx < arrayCounts[arrayCountNdx]; arrayNdx++) |
| { |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT, |
| Array::OUTPUTTYPE_VEC2, |
| Array::STORAGE_USER, |
| Array::USAGE_DYNAMIC_DRAW, |
| 2, |
| 0, |
| 0, |
| false, |
| GLValue::getMinValue(Array::INPUTTYPE_FLOAT), |
| GLValue::getMaxValue(Array::INPUTTYPE_FLOAT)); |
| |
| spec.arrays.push_back(arraySpec); |
| } |
| |
| std::string name = getTestName(spec); |
| std::string desc = getTestName(spec); |
| |
| addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str())); |
| } |
| } |
| |
| class MultiVertexArrayStorageTests : public TestCaseGroup |
| { |
| public: |
| MultiVertexArrayStorageTests (Context& context); |
| virtual ~MultiVertexArrayStorageTests (void); |
| |
| virtual void init (void); |
| |
| private: |
| MultiVertexArrayStorageTests (const MultiVertexArrayStorageTests& other); |
| MultiVertexArrayStorageTests& operator= (const MultiVertexArrayStorageTests& other); |
| |
| void addStorageCases (MultiVertexArrayTest::Spec spec, int depth); |
| std::string getTestName (const MultiVertexArrayTest::Spec& spec); |
| }; |
| |
| MultiVertexArrayStorageTests::MultiVertexArrayStorageTests (Context& context) |
| : TestCaseGroup(context, "storage", "Attribute storages") |
| { |
| } |
| |
| MultiVertexArrayStorageTests::~MultiVertexArrayStorageTests (void) |
| { |
| } |
| |
| std::string MultiVertexArrayStorageTests::getTestName (const MultiVertexArrayTest::Spec& spec) |
| { |
| std::stringstream name; |
| name |
| << spec.arrays.size(); |
| |
| for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++) |
| { |
| name |
| << "_" |
| << Array::storageToString(spec.arrays[arrayNdx].storage); |
| } |
| |
| return name.str(); |
| } |
| |
| void MultiVertexArrayStorageTests::addStorageCases (MultiVertexArrayTest::Spec spec, int depth) |
| { |
| if (depth == 0) |
| { |
| // Skip trivial case, used elsewhere |
| bool ok = false; |
| for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++) |
| { |
| if (spec.arrays[arrayNdx].storage != Array::STORAGE_USER) |
| { |
| ok = true; |
| break; |
| } |
| } |
| |
| if (!ok) |
| return; |
| |
| std::string name = getTestName(spec); |
| std::string desc = getTestName(spec); |
| |
| addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str())); |
| return; |
| } |
| |
| Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER}; |
| for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++) |
| { |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT, |
| Array::OUTPUTTYPE_VEC2, |
| storages[storageNdx], |
| Array::USAGE_DYNAMIC_DRAW, |
| 2, |
| 0, |
| 0, |
| false, |
| GLValue::getMinValue(Array::INPUTTYPE_FLOAT), |
| GLValue::getMaxValue(Array::INPUTTYPE_FLOAT)); |
| |
| MultiVertexArrayTest::Spec _spec = spec; |
| _spec.arrays.push_back(arraySpec); |
| addStorageCases(_spec, depth-1); |
| } |
| } |
| |
| |
| void MultiVertexArrayStorageTests::init (void) |
| { |
| // Test different storages |
| int arrayCounts[] = {3}; |
| |
| MultiVertexArrayTest::Spec spec; |
| |
| spec.primitive = Array::PRIMITIVE_TRIANGLES; |
| spec.drawCount = 256; |
| spec.first = 0; |
| |
| for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++) |
| addStorageCases(spec, arrayCounts[arrayCountNdx]); |
| } |
| |
| class MultiVertexArrayStrideTests : public TestCaseGroup |
| { |
| public: |
| MultiVertexArrayStrideTests (Context& context); |
| virtual ~MultiVertexArrayStrideTests (void); |
| |
| virtual void init (void); |
| |
| private: |
| MultiVertexArrayStrideTests (const MultiVertexArrayStrideTests& other); |
| MultiVertexArrayStrideTests& operator= (const MultiVertexArrayStrideTests& other); |
| |
| void addStrideCases (MultiVertexArrayTest::Spec spec, int depth); |
| std::string getTestName (const MultiVertexArrayTest::Spec& spec); |
| }; |
| |
| MultiVertexArrayStrideTests::MultiVertexArrayStrideTests (Context& context) |
| : TestCaseGroup(context, "stride", "Strides") |
| { |
| } |
| |
| MultiVertexArrayStrideTests::~MultiVertexArrayStrideTests (void) |
| { |
| } |
| |
| std::string MultiVertexArrayStrideTests::getTestName (const MultiVertexArrayTest::Spec& spec) |
| { |
| std::stringstream name; |
| |
| name |
| << spec.arrays.size(); |
| |
| for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++) |
| { |
| name |
| << "_" |
| << Array::inputTypeToString(spec.arrays[arrayNdx].inputType) |
| << spec.arrays[arrayNdx].componentCount << "_" |
| << spec.arrays[arrayNdx].stride; |
| } |
| |
| return name.str(); |
| } |
| |
| void MultiVertexArrayStrideTests::init (void) |
| { |
| // Test different strides, with multiple arrays, input types?? |
| int arrayCounts[] = {3}; |
| |
| MultiVertexArrayTest::Spec spec; |
| |
| spec.primitive = Array::PRIMITIVE_TRIANGLES; |
| spec.drawCount = 256; |
| spec.first = 0; |
| |
| for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++) |
| addStrideCases(spec, arrayCounts[arrayCountNdx]); |
| } |
| |
| void MultiVertexArrayStrideTests::addStrideCases (MultiVertexArrayTest::Spec spec, int depth) |
| { |
| if (depth == 0) |
| { |
| std::string name = getTestName(spec); |
| std::string desc = getTestName(spec); |
| addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str())); |
| return; |
| } |
| |
| int strides[] = {0, -1, 17, 32}; |
| |
| for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) |
| { |
| const int componentCount = 2; |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT, |
| Array::OUTPUTTYPE_VEC2, |
| Array::STORAGE_USER, |
| Array::USAGE_DYNAMIC_DRAW, |
| componentCount, |
| 0, |
| (strides[strideNdx] >= 0 ? strides[strideNdx] : componentCount * Array::inputTypeSize(Array::INPUTTYPE_FLOAT)), |
| false, |
| GLValue::getMinValue(Array::INPUTTYPE_FLOAT), |
| GLValue::getMaxValue(Array::INPUTTYPE_FLOAT)); |
| |
| MultiVertexArrayTest::Spec _spec = spec; |
| _spec.arrays.push_back(arraySpec); |
| addStrideCases(_spec, depth-1); |
| } |
| } |
| |
| class MultiVertexArrayOutputTests : public TestCaseGroup |
| { |
| public: |
| MultiVertexArrayOutputTests (Context& context); |
| virtual ~MultiVertexArrayOutputTests (void); |
| |
| virtual void init (void); |
| |
| private: |
| MultiVertexArrayOutputTests (const MultiVertexArrayOutputTests& other); |
| MultiVertexArrayOutputTests& operator= (const MultiVertexArrayOutputTests& other); |
| |
| void addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth); |
| std::string getTestName (const MultiVertexArrayTest::Spec& spec); |
| }; |
| |
| MultiVertexArrayOutputTests::MultiVertexArrayOutputTests (Context& context) |
| : TestCaseGroup(context, "input_types", "input types") |
| { |
| } |
| |
| MultiVertexArrayOutputTests::~MultiVertexArrayOutputTests (void) |
| { |
| } |
| |
| std::string MultiVertexArrayOutputTests::getTestName (const MultiVertexArrayTest::Spec& spec) |
| { |
| std::stringstream name; |
| |
| name |
| << spec.arrays.size(); |
| |
| for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++) |
| { |
| name |
| << "_" |
| << Array::inputTypeToString(spec.arrays[arrayNdx].inputType) |
| << spec.arrays[arrayNdx].componentCount << "_" |
| << Array::outputTypeToString(spec.arrays[arrayNdx].outputType); |
| } |
| |
| return name.str(); |
| } |
| |
| void MultiVertexArrayOutputTests::init (void) |
| { |
| // Test different input types, with multiple arrays |
| int arrayCounts[] = {3}; |
| |
| MultiVertexArrayTest::Spec spec; |
| |
| spec.primitive = Array::PRIMITIVE_TRIANGLES; |
| spec.drawCount = 256; |
| spec.first = 0; |
| |
| for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++) |
| addInputTypeCases(spec, arrayCounts[arrayCountNdx]); |
| } |
| |
| void MultiVertexArrayOutputTests::addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth) |
| { |
| if (depth == 0) |
| { |
| std::string name = getTestName(spec); |
| std::string desc = getTestName(spec); |
| addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str())); |
| return; |
| } |
| |
| Array::InputType inputTypes[] = {Array::INPUTTYPE_FIXED, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT}; |
| for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) |
| { |
| MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], |
| Array::OUTPUTTYPE_VEC2, |
| Array::STORAGE_USER, |
| Array::USAGE_DYNAMIC_DRAW, |
| 2, |
| 0, |
| 0, |
| false, |
| GLValue::getMinValue(inputTypes[inputTypeNdx]), |
| GLValue::getMaxValue(inputTypes[inputTypeNdx])); |
| |
| MultiVertexArrayTest::Spec _spec = spec; |
| _spec.arrays.push_back(arraySpec); |
| addInputTypeCases(_spec, depth-1); |
| } |
| } |
| |
| class MultiVertexArrayTestGroup : public TestCaseGroup |
| { |
| public: |
| MultiVertexArrayTestGroup (Context& context); |
| virtual ~MultiVertexArrayTestGroup (void); |
| |
| virtual void init (void); |
| |
| private: |
| MultiVertexArrayTestGroup (const MultiVertexArrayTestGroup& other); |
| MultiVertexArrayTestGroup& operator= (const MultiVertexArrayTestGroup& other); |
| }; |
| |
| MultiVertexArrayTestGroup::MultiVertexArrayTestGroup (Context& context) |
| : TestCaseGroup(context, "multiple_attributes", "Multiple vertex atributes") |
| { |
| } |
| |
| MultiVertexArrayTestGroup::~MultiVertexArrayTestGroup (void) |
| { |
| } |
| |
| void MultiVertexArrayTestGroup::init (void) |
| { |
| addChild(new MultiVertexArrayCountTests(m_context)); |
| addChild(new MultiVertexArrayStorageTests(m_context)); |
| addChild(new MultiVertexArrayStrideTests(m_context)); |
| addChild(new MultiVertexArrayOutputTests(m_context)); |
| } |
| |
| VertexArrayTestGroup::VertexArrayTestGroup (Context& context) |
| : TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests") |
| { |
| } |
| |
| VertexArrayTestGroup::~VertexArrayTestGroup (void) |
| { |
| } |
| |
| void VertexArrayTestGroup::init (void) |
| { |
| addChild(new SingleVertexArrayTestGroup(m_context)); |
| addChild(new MultiVertexArrayTestGroup(m_context)); |
| } |
| |
| } // Functional |
| } // gles3 |
| } // deqp |