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 29 using namespace deqp::gls; 30 31 namespace deqp 32 { 33 namespace gles2 34 { 35 namespace Stress 36 { 37 namespace 38 { 39 40 template<class T> 41 static std::string typeToString (T t) 42 { 43 std::stringstream strm; 44 strm << t; 45 return strm.str(); 46 } 47 48 class SingleVertexArrayUsageTests : public TestCaseGroup 49 { 50 public: 51 SingleVertexArrayUsageTests (Context& context); 52 virtual ~SingleVertexArrayUsageTests (void); 53 54 virtual void init (void); 55 56 private: 57 SingleVertexArrayUsageTests (const SingleVertexArrayUsageTests& other); 58 SingleVertexArrayUsageTests& operator= (const SingleVertexArrayUsageTests& other); 59 }; 60 61 SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context) 62 : TestCaseGroup(context, "usages", "Single vertex atribute, usage") 63 { 64 } 65 66 SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void) 67 { 68 } 69 70 void 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 116 class SingleVertexArrayStrideTests : public TestCaseGroup 117 { 118 public: 119 SingleVertexArrayStrideTests (Context& context); 120 virtual ~SingleVertexArrayStrideTests (void); 121 122 virtual void init (void); 123 124 private: 125 SingleVertexArrayStrideTests (const SingleVertexArrayStrideTests& other); 126 SingleVertexArrayStrideTests& operator= (const SingleVertexArrayStrideTests& other); 127 }; 128 129 SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context) 130 : TestCaseGroup(context, "strides", "Single stride vertex atribute") 131 { 132 } 133 134 SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void) 135 { 136 } 137 138 void 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 186 class SingleVertexArrayFirstTests : public TestCaseGroup 187 { 188 public: 189 SingleVertexArrayFirstTests (Context& context); 190 virtual ~SingleVertexArrayFirstTests (void); 191 192 virtual void init (void); 193 194 private: 195 SingleVertexArrayFirstTests (const SingleVertexArrayFirstTests& other); 196 SingleVertexArrayFirstTests& operator= (const SingleVertexArrayFirstTests& other); 197 }; 198 199 SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context) 200 : TestCaseGroup(context, "first", "Single vertex atribute different first values") 201 { 202 } 203 204 SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void) 205 { 206 } 207 208 void 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 257 class SingleVertexArrayOffsetTests : public TestCaseGroup 258 { 259 public: 260 SingleVertexArrayOffsetTests (Context& context); 261 virtual ~SingleVertexArrayOffsetTests (void); 262 263 virtual void init (void); 264 265 private: 266 SingleVertexArrayOffsetTests (const SingleVertexArrayOffsetTests& other); 267 SingleVertexArrayOffsetTests& operator= (const SingleVertexArrayOffsetTests& other); 268 }; 269 270 SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context) 271 : TestCaseGroup(context, "offset", "Single vertex atribute offset element") 272 { 273 } 274 275 SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void) 276 { 277 } 278 279 void 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 326 VertexArrayTests::VertexArrayTests (Context& context) 327 : TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests") 328 { 329 } 330 331 VertexArrayTests::~VertexArrayTests (void) 332 { 333 } 334 335 void 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