1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 2.0 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Vertex array and buffer unaligned access stress tests 22 *//*--------------------------------------------------------------------*/ 23 24#include "es2sVertexArrayTests.hpp" 25#include "glsVertexArrayTests.hpp" 26 27#include "glwEnums.hpp" 28 29using namespace deqp::gls; 30 31namespace deqp 32{ 33namespace gles2 34{ 35namespace Stress 36{ 37namespace 38{ 39 40template<class T> 41static std::string typeToString (T t) 42{ 43 std::stringstream strm; 44 strm << t; 45 return strm.str(); 46} 47 48class SingleVertexArrayUsageTests : public TestCaseGroup 49{ 50public: 51 SingleVertexArrayUsageTests (Context& context); 52 virtual ~SingleVertexArrayUsageTests (void); 53 54 virtual void init (void); 55 56private: 57 SingleVertexArrayUsageTests (const SingleVertexArrayUsageTests& other); 58 SingleVertexArrayUsageTests& operator= (const SingleVertexArrayUsageTests& other); 59}; 60 61SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context) 62 : TestCaseGroup(context, "usages", "Single vertex atribute, usage") 63{ 64} 65 66SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void) 67{ 68} 69 70void SingleVertexArrayUsageTests::init (void) 71{ 72 // Test usage 73 Array::Usage usages[] = {Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW}; 74 int counts[] = {1, 256}; 75 int strides[] = {17}; 76 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE}; 77 78 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 79 { 80 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 81 { 82 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 83 { 84 for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++) 85 { 86 const int componentCount = 2; 87 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount : strides[strideNdx]); 88 const bool aligned = (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0; 89 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], 90 Array::OUTPUTTYPE_VEC2, 91 Array::STORAGE_BUFFER, 92 usages[usageNdx], 93 componentCount, 94 0, 95 stride, 96 false, 97 GLValue::getMinValue(inputTypes[inputTypeNdx]), 98 GLValue::getMaxValue(inputTypes[inputTypeNdx])); 99 100 MultiVertexArrayTest::Spec spec; 101 spec.primitive = Array::PRIMITIVE_TRIANGLES; 102 spec.drawCount = counts[countNdx]; 103 spec.first = 0; 104 spec.arrays.push_back(arraySpec); 105 106 std::string name = spec.getName(); 107 108 if (!aligned) 109 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 110 } 111 } 112 } 113 } 114} 115 116class SingleVertexArrayStrideTests : public TestCaseGroup 117{ 118public: 119 SingleVertexArrayStrideTests (Context& context); 120 virtual ~SingleVertexArrayStrideTests (void); 121 122 virtual void init (void); 123 124private: 125 SingleVertexArrayStrideTests (const SingleVertexArrayStrideTests& other); 126 SingleVertexArrayStrideTests& operator= (const SingleVertexArrayStrideTests& other); 127}; 128 129SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context) 130 : TestCaseGroup(context, "strides", "Single stride vertex atribute") 131{ 132} 133 134SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void) 135{ 136} 137 138void SingleVertexArrayStrideTests::init (void) 139{ 140 // Test strides with different input types, component counts and storage, Usage(?) 141 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED}; 142 Array::Storage storages[] = {Array::STORAGE_BUFFER}; 143 int counts[] = {1, 256}; 144 int strides[] = {17}; 145 146 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 147 { 148 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++) 149 { 150 for (int componentCount = 2; componentCount < 5; componentCount++) 151 { 152 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 153 { 154 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 155 { 156 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount : strides[strideNdx]); 157 const bool bufferUnaligned = (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) != 0; 158 159 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], 160 Array::OUTPUTTYPE_VEC4, 161 storages[storageNdx], 162 Array::USAGE_DYNAMIC_DRAW, 163 componentCount, 164 0, 165 stride, 166 false, 167 GLValue::getMinValue(inputTypes[inputTypeNdx]), 168 GLValue::getMaxValue(inputTypes[inputTypeNdx])); 169 170 MultiVertexArrayTest::Spec spec; 171 spec.primitive = Array::PRIMITIVE_TRIANGLES; 172 spec.drawCount = counts[countNdx]; 173 spec.first = 0; 174 spec.arrays.push_back(arraySpec); 175 176 std::string name = spec.getName(); 177 if (bufferUnaligned) 178 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 179 } 180 } 181 } 182 } 183 } 184} 185 186class SingleVertexArrayFirstTests : public TestCaseGroup 187{ 188public: 189 SingleVertexArrayFirstTests (Context& context); 190 virtual ~SingleVertexArrayFirstTests (void); 191 192 virtual void init (void); 193 194private: 195 SingleVertexArrayFirstTests (const SingleVertexArrayFirstTests& other); 196 SingleVertexArrayFirstTests& operator= (const SingleVertexArrayFirstTests& other); 197}; 198 199SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context) 200 : TestCaseGroup(context, "first", "Single vertex atribute different first values") 201{ 202} 203 204SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void) 205{ 206} 207 208void SingleVertexArrayFirstTests::init (void) 209{ 210 // Test strides with different input types, component counts and storage, Usage(?) 211 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED}; 212 int counts[] = {5, 256}; 213 int firsts[] = {6, 24}; 214 int offsets[] = {1, 17}; 215 int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL. 216 217 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 218 { 219 for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++) 220 { 221 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 222 { 223 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 224 { 225 for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++) 226 { 227 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]); 228 const bool aligned = ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) && (offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx]) == 0); 229 230 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], 231 Array::OUTPUTTYPE_VEC2, 232 Array::STORAGE_BUFFER, 233 Array::USAGE_DYNAMIC_DRAW, 234 2, 235 offsets[offsetNdx], 236 stride, 237 false, 238 GLValue::getMinValue(inputTypes[inputTypeNdx]), 239 GLValue::getMaxValue(inputTypes[inputTypeNdx])); 240 241 MultiVertexArrayTest::Spec spec; 242 spec.primitive = Array::PRIMITIVE_TRIANGLES; 243 spec.drawCount = counts[countNdx]; 244 spec.first = firsts[firstNdx]; 245 spec.arrays.push_back(arraySpec); 246 247 std::string name = Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]); 248 if (!aligned) 249 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 250 } 251 } 252 } 253 } 254 } 255} 256 257class SingleVertexArrayOffsetTests : public TestCaseGroup 258{ 259public: 260 SingleVertexArrayOffsetTests (Context& context); 261 virtual ~SingleVertexArrayOffsetTests (void); 262 263 virtual void init (void); 264 265private: 266 SingleVertexArrayOffsetTests (const SingleVertexArrayOffsetTests& other); 267 SingleVertexArrayOffsetTests& operator= (const SingleVertexArrayOffsetTests& other); 268}; 269 270SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context) 271 : TestCaseGroup(context, "offset", "Single vertex atribute offset element") 272{ 273} 274 275SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void) 276{ 277} 278 279void SingleVertexArrayOffsetTests::init (void) 280{ 281 // Test strides with different input types, component counts and storage, Usage(?) 282 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED}; 283 int counts[] = {1, 256}; 284 int offsets[] = {1, 4, 17, 32}; 285 int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL. 286 287 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 288 { 289 for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++) 290 { 291 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 292 { 293 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 294 { 295 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]); 296 const bool aligned = ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) && ((offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0); 297 298 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], 299 Array::OUTPUTTYPE_VEC2, 300 Array::STORAGE_BUFFER, 301 Array::USAGE_DYNAMIC_DRAW, 302 2, 303 offsets[offsetNdx], 304 stride, 305 false, 306 GLValue::getMinValue(inputTypes[inputTypeNdx]), 307 GLValue::getMaxValue(inputTypes[inputTypeNdx])); 308 309 MultiVertexArrayTest::Spec spec; 310 spec.primitive = Array::PRIMITIVE_TRIANGLES; 311 spec.drawCount = counts[countNdx]; 312 spec.first = 0; 313 spec.arrays.push_back(arraySpec); 314 315 std::string name = spec.getName(); 316 if (!aligned) 317 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 318 } 319 } 320 } 321 } 322} 323 324} // anonymous 325 326VertexArrayTests::VertexArrayTests (Context& context) 327 : TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests") 328{ 329} 330 331VertexArrayTests::~VertexArrayTests (void) 332{ 333} 334 335void VertexArrayTests::init (void) 336{ 337 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "single_attribute", "Single attribute"); 338 addChild(group); 339 340 // .single_attribute 341 { 342 group->addChild(new SingleVertexArrayStrideTests(m_context)); 343 group->addChild(new SingleVertexArrayUsageTests(m_context)); 344 group->addChild(new SingleVertexArrayOffsetTests(m_context)); 345 group->addChild(new SingleVertexArrayFirstTests(m_context)); 346 } 347} 348 349} // Stress 350} // gles2 351} // deqp 352