1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.0 Module 3e5c31af7Sopenharmony_ci * ------------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Primitive restart tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es3fPrimitiveRestartTests.hpp" 25e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 26e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 27e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 28e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 29e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 30e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 31e5c31af7Sopenharmony_ci#include "deRandom.hpp" 32e5c31af7Sopenharmony_ci#include "deMath.h" 33e5c31af7Sopenharmony_ci#include "deString.h" 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci#include "glw.h" 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ciusing tcu::Vec4; 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_cinamespace deqp 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_cinamespace gles3 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_cinamespace Functional 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_cistatic const int MAX_RENDER_WIDTH = 256; 47e5c31af7Sopenharmony_cistatic const int MAX_RENDER_HEIGHT = 256; 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cistatic const deUint32 MAX_UNSIGNED_BYTE = (1<<8) - 1; 50e5c31af7Sopenharmony_cistatic const deUint32 MAX_UNSIGNED_SHORT = (1<<16) - 1; 51e5c31af7Sopenharmony_cistatic const deUint32 MAX_UNSIGNED_INT = (deUint32)((1ULL << 32) - 1); 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_cistatic const deUint8 RESTART_INDEX_UNSIGNED_BYTE = (deUint8)MAX_UNSIGNED_BYTE; 54e5c31af7Sopenharmony_cistatic const deUint16 RESTART_INDEX_UNSIGNED_SHORT = (deUint16)MAX_UNSIGNED_SHORT; 55e5c31af7Sopenharmony_cistatic const deUint32 RESTART_INDEX_UNSIGNED_INT = MAX_UNSIGNED_INT; 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_ciclass PrimitiveRestartCase : public TestCase 58e5c31af7Sopenharmony_ci{ 59e5c31af7Sopenharmony_cipublic: 60e5c31af7Sopenharmony_ci enum PrimitiveType 61e5c31af7Sopenharmony_ci { 62e5c31af7Sopenharmony_ci PRIMITIVE_POINTS = 0, 63e5c31af7Sopenharmony_ci PRIMITIVE_LINE_STRIP, 64e5c31af7Sopenharmony_ci PRIMITIVE_LINE_LOOP, 65e5c31af7Sopenharmony_ci PRIMITIVE_LINES, 66e5c31af7Sopenharmony_ci PRIMITIVE_TRIANGLE_STRIP, 67e5c31af7Sopenharmony_ci PRIMITIVE_TRIANGLE_FAN, 68e5c31af7Sopenharmony_ci PRIMITIVE_TRIANGLES, 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci PRIMITIVE_LAST 71e5c31af7Sopenharmony_ci }; 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ci enum IndexType 74e5c31af7Sopenharmony_ci { 75e5c31af7Sopenharmony_ci INDEX_UNSIGNED_BYTE = 0, 76e5c31af7Sopenharmony_ci INDEX_UNSIGNED_SHORT, 77e5c31af7Sopenharmony_ci INDEX_UNSIGNED_INT, 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_ci INDEX_LAST 80e5c31af7Sopenharmony_ci }; 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ci enum Function 83e5c31af7Sopenharmony_ci { 84e5c31af7Sopenharmony_ci FUNCTION_DRAW_ELEMENTS = 0, 85e5c31af7Sopenharmony_ci FUNCTION_DRAW_ELEMENTS_INSTANCED, 86e5c31af7Sopenharmony_ci FUNCTION_DRAW_RANGE_ELEMENTS, 87e5c31af7Sopenharmony_ci 88e5c31af7Sopenharmony_ci FUNCTION_LAST 89e5c31af7Sopenharmony_ci }; 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci PrimitiveRestartCase (Context& context, const char* name, const char* description, PrimitiveType primType, IndexType indexType, Function function, bool beginWithRestart, bool endWithRestart, bool duplicateRestarts); 92e5c31af7Sopenharmony_ci ~PrimitiveRestartCase (void); 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ci void init (void); 95e5c31af7Sopenharmony_ci void deinit (void); 96e5c31af7Sopenharmony_ci IterateResult iterate (void); 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ciprivate: 99e5c31af7Sopenharmony_ci PrimitiveRestartCase (const PrimitiveRestartCase& other); 100e5c31af7Sopenharmony_ci PrimitiveRestartCase& operator= (const PrimitiveRestartCase& other); 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci void draw (int startNdx, int count); 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci void renderWithRestart (void); 105e5c31af7Sopenharmony_ci void renderWithoutRestart (void); 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci // Helper functions for handling the appropriate index vector (according to m_indexType). 108e5c31af7Sopenharmony_ci void addIndex (deUint32 index); 109e5c31af7Sopenharmony_ci deUint32 getIndex (int indexNdx); 110e5c31af7Sopenharmony_ci int getNumIndices (void); 111e5c31af7Sopenharmony_ci void* getIndexPtr (int indexNdx); 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci // \note Only one of the following index vectors is used (according to m_indexType). 114e5c31af7Sopenharmony_ci std::vector<deUint8> m_indicesUB; 115e5c31af7Sopenharmony_ci std::vector<deUint16> m_indicesUS; 116e5c31af7Sopenharmony_ci std::vector<deUint32> m_indicesUI; 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci std::vector<float> m_positions; 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci PrimitiveType m_primType; 121e5c31af7Sopenharmony_ci IndexType m_indexType; 122e5c31af7Sopenharmony_ci Function m_function; 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci bool m_beginWithRestart; // Whether there will be restart indices at the beginning of the index array. 125e5c31af7Sopenharmony_ci bool m_endWithRestart; // Whether there will be restart indices at the end of the index array. 126e5c31af7Sopenharmony_ci bool m_duplicateRestarts; // Whether two consecutive restarts are used instead of one. 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci glu::ShaderProgram* m_program; 129e5c31af7Sopenharmony_ci}; 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ciPrimitiveRestartCase::PrimitiveRestartCase (Context& context, const char* name, const char* description, PrimitiveType primType, IndexType indexType, Function function, bool beginWithRestart, bool endWithRestart, bool duplicateRestarts) 132e5c31af7Sopenharmony_ci : TestCase (context, name, description) 133e5c31af7Sopenharmony_ci , m_primType (primType) 134e5c31af7Sopenharmony_ci , m_indexType (indexType) 135e5c31af7Sopenharmony_ci , m_function (function) 136e5c31af7Sopenharmony_ci , m_beginWithRestart (beginWithRestart) 137e5c31af7Sopenharmony_ci , m_endWithRestart (endWithRestart) 138e5c31af7Sopenharmony_ci , m_duplicateRestarts (duplicateRestarts) 139e5c31af7Sopenharmony_ci , m_program (DE_NULL) 140e5c31af7Sopenharmony_ci{ 141e5c31af7Sopenharmony_ci} 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ciPrimitiveRestartCase::~PrimitiveRestartCase (void) 144e5c31af7Sopenharmony_ci{ 145e5c31af7Sopenharmony_ci PrimitiveRestartCase::deinit(); 146e5c31af7Sopenharmony_ci} 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_civoid PrimitiveRestartCase::deinit (void) 149e5c31af7Sopenharmony_ci{ 150e5c31af7Sopenharmony_ci delete m_program; 151e5c31af7Sopenharmony_ci m_program = DE_NULL; 152e5c31af7Sopenharmony_ci} 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_civoid PrimitiveRestartCase::addIndex (deUint32 index) 155e5c31af7Sopenharmony_ci{ 156e5c31af7Sopenharmony_ci if (m_indexType == INDEX_UNSIGNED_BYTE) 157e5c31af7Sopenharmony_ci { 158e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(index, (deUint32)0, MAX_UNSIGNED_BYTE)); 159e5c31af7Sopenharmony_ci m_indicesUB.push_back((deUint8)index); 160e5c31af7Sopenharmony_ci } 161e5c31af7Sopenharmony_ci else if (m_indexType == INDEX_UNSIGNED_SHORT) 162e5c31af7Sopenharmony_ci { 163e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(index, (deUint32)0, MAX_UNSIGNED_SHORT)); 164e5c31af7Sopenharmony_ci m_indicesUS.push_back((deUint16)index); 165e5c31af7Sopenharmony_ci } 166e5c31af7Sopenharmony_ci else if (m_indexType == INDEX_UNSIGNED_INT) 167e5c31af7Sopenharmony_ci { 168e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(index, (deUint32)0, MAX_UNSIGNED_INT)); 169e5c31af7Sopenharmony_ci m_indicesUI.push_back((deUint32)index); 170e5c31af7Sopenharmony_ci } 171e5c31af7Sopenharmony_ci else 172e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 173e5c31af7Sopenharmony_ci} 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_cideUint32 PrimitiveRestartCase::getIndex (int indexNdx) 176e5c31af7Sopenharmony_ci{ 177e5c31af7Sopenharmony_ci switch (m_indexType) 178e5c31af7Sopenharmony_ci { 179e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_BYTE: return (deUint32)m_indicesUB[indexNdx]; 180e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_SHORT: return (deUint32)m_indicesUS[indexNdx]; 181e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_INT: return m_indicesUI[indexNdx]; 182e5c31af7Sopenharmony_ci default: 183e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 184e5c31af7Sopenharmony_ci return 0; 185e5c31af7Sopenharmony_ci } 186e5c31af7Sopenharmony_ci} 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ciint PrimitiveRestartCase::getNumIndices (void) 189e5c31af7Sopenharmony_ci{ 190e5c31af7Sopenharmony_ci switch (m_indexType) 191e5c31af7Sopenharmony_ci { 192e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_BYTE: return (int)m_indicesUB.size(); 193e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_SHORT: return (int)m_indicesUS.size(); 194e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_INT: return (int)m_indicesUI.size(); 195e5c31af7Sopenharmony_ci default: 196e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 197e5c31af7Sopenharmony_ci return 0; 198e5c31af7Sopenharmony_ci } 199e5c31af7Sopenharmony_ci} 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ci// Pointer to the index value at index indexNdx. 202e5c31af7Sopenharmony_civoid* PrimitiveRestartCase::getIndexPtr (int indexNdx) 203e5c31af7Sopenharmony_ci{ 204e5c31af7Sopenharmony_ci switch (m_indexType) 205e5c31af7Sopenharmony_ci { 206e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_BYTE: return (void*)&m_indicesUB[indexNdx]; 207e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_SHORT: return (void*)&m_indicesUS[indexNdx]; 208e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_INT: return (void*)&m_indicesUI[indexNdx]; 209e5c31af7Sopenharmony_ci default: 210e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 211e5c31af7Sopenharmony_ci return DE_NULL; 212e5c31af7Sopenharmony_ci } 213e5c31af7Sopenharmony_ci} 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_civoid PrimitiveRestartCase::init (void) 216e5c31af7Sopenharmony_ci{ 217e5c31af7Sopenharmony_ci // Create shader program. 218e5c31af7Sopenharmony_ci std::string vertShaderSource; 219e5c31af7Sopenharmony_ci if (m_primType == PRIMITIVE_POINTS) 220e5c31af7Sopenharmony_ci { 221e5c31af7Sopenharmony_ci vertShaderSource = 222e5c31af7Sopenharmony_ci "#version 300 es\n" 223e5c31af7Sopenharmony_ci "in highp vec4 a_position;\n" 224e5c31af7Sopenharmony_ci "\n" 225e5c31af7Sopenharmony_ci "void main()\n" 226e5c31af7Sopenharmony_ci "{\n" 227e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 228e5c31af7Sopenharmony_ci " gl_PointSize = 1.0f;\n" 229e5c31af7Sopenharmony_ci "}\n"; 230e5c31af7Sopenharmony_ci } 231e5c31af7Sopenharmony_ci else 232e5c31af7Sopenharmony_ci { 233e5c31af7Sopenharmony_ci vertShaderSource = 234e5c31af7Sopenharmony_ci "#version 300 es\n" 235e5c31af7Sopenharmony_ci "in highp vec4 a_position;\n" 236e5c31af7Sopenharmony_ci "\n" 237e5c31af7Sopenharmony_ci "void main()\n" 238e5c31af7Sopenharmony_ci "{\n" 239e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 240e5c31af7Sopenharmony_ci "}\n"; 241e5c31af7Sopenharmony_ci } 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ci static const char* fragShaderSource = 244e5c31af7Sopenharmony_ci "#version 300 es\n" 245e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 o_color;\n" 246e5c31af7Sopenharmony_ci "\n" 247e5c31af7Sopenharmony_ci "void main()\n" 248e5c31af7Sopenharmony_ci "{\n" 249e5c31af7Sopenharmony_ci " o_color = vec4(1.0f);\n" 250e5c31af7Sopenharmony_ci "}\n"; 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci DE_ASSERT(!m_program); 253e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource)); 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_ci if(!m_program->isOk()) 256e5c31af7Sopenharmony_ci { 257e5c31af7Sopenharmony_ci m_testCtx.getLog() << *m_program; 258e5c31af7Sopenharmony_ci TCU_FAIL("Failed to compile shader"); 259e5c31af7Sopenharmony_ci } 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci deUint32 restartIndex = m_indexType == INDEX_UNSIGNED_BYTE ? RESTART_INDEX_UNSIGNED_BYTE 262e5c31af7Sopenharmony_ci : m_indexType == INDEX_UNSIGNED_SHORT ? RESTART_INDEX_UNSIGNED_SHORT 263e5c31af7Sopenharmony_ci : m_indexType == INDEX_UNSIGNED_INT ? RESTART_INDEX_UNSIGNED_INT 264e5c31af7Sopenharmony_ci : 0; 265e5c31af7Sopenharmony_ci 266e5c31af7Sopenharmony_ci DE_ASSERT(restartIndex != 0); 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci DE_ASSERT(getNumIndices() == 0); 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_ci // If testing a case with restart at beginning, add it there. 271e5c31af7Sopenharmony_ci if (m_beginWithRestart) 272e5c31af7Sopenharmony_ci { 273e5c31af7Sopenharmony_ci addIndex(restartIndex); 274e5c31af7Sopenharmony_ci if (m_duplicateRestarts) 275e5c31af7Sopenharmony_ci addIndex(restartIndex); 276e5c31af7Sopenharmony_ci } 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci // Generate vertex positions and indices depending on primitive type. 279e5c31af7Sopenharmony_ci // \note At this point, restarts shall not be added to the start or the end of the index vector. Those are special cases, and are done above and after the following if-else chain, respectively. 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_ci if (m_primType == PRIMITIVE_POINTS) 282e5c31af7Sopenharmony_ci { 283e5c31af7Sopenharmony_ci // Generate rows with different numbers of points. 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ci deUint32 curIndex = 0; 286e5c31af7Sopenharmony_ci const int numRows = 20; 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci for (int row = 0; row < numRows; row++) 289e5c31af7Sopenharmony_ci { 290e5c31af7Sopenharmony_ci for (int col = 0; col < row + 1; col++) 291e5c31af7Sopenharmony_ci { 292e5c31af7Sopenharmony_ci float fx = -1.0f + 2.0f * ((float)col + 0.5f) / (float)numRows; 293e5c31af7Sopenharmony_ci float fy = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows; 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_ci m_positions.push_back(fx); 296e5c31af7Sopenharmony_ci m_positions.push_back(fy); 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci addIndex(curIndex++); 299e5c31af7Sopenharmony_ci } 300e5c31af7Sopenharmony_ci 301e5c31af7Sopenharmony_ci if (row < numRows - 1) // Add a restart after all but last row. 302e5c31af7Sopenharmony_ci { 303e5c31af7Sopenharmony_ci addIndex(restartIndex); 304e5c31af7Sopenharmony_ci if (m_duplicateRestarts) 305e5c31af7Sopenharmony_ci addIndex(restartIndex); 306e5c31af7Sopenharmony_ci } 307e5c31af7Sopenharmony_ci } 308e5c31af7Sopenharmony_ci } 309e5c31af7Sopenharmony_ci else if (m_primType == PRIMITIVE_LINE_STRIP || m_primType == PRIMITIVE_LINE_LOOP || m_primType == PRIMITIVE_LINES) 310e5c31af7Sopenharmony_ci { 311e5c31af7Sopenharmony_ci // Generate a numRows x numCols arrangement of line polygons of different vertex counts. 312e5c31af7Sopenharmony_ci 313e5c31af7Sopenharmony_ci deUint32 curIndex = 0; 314e5c31af7Sopenharmony_ci const int numRows = 4; 315e5c31af7Sopenharmony_ci const int numCols = 4; 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_ci for (int row = 0; row < numRows; row++) 318e5c31af7Sopenharmony_ci { 319e5c31af7Sopenharmony_ci float centerY = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows; 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci for (int col = 0; col < numCols; col++) 322e5c31af7Sopenharmony_ci { 323e5c31af7Sopenharmony_ci float centerX = -1.0f + 2.0f * ((float)col + 0.5f) / (float)numCols; 324e5c31af7Sopenharmony_ci int numVertices = row*numCols + col + 1; 325e5c31af7Sopenharmony_ci 326e5c31af7Sopenharmony_ci for (int i = 0; i < numVertices; i++) 327e5c31af7Sopenharmony_ci { 328e5c31af7Sopenharmony_ci float fx = centerX + 0.9f * deFloatCos((float)i*2.0f*DE_PI / (float)numVertices) / (float)numCols; 329e5c31af7Sopenharmony_ci float fy = centerY + 0.9f * deFloatSin((float)i*2.0f*DE_PI / (float)numVertices) / (float)numRows; 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci m_positions.push_back(fx); 332e5c31af7Sopenharmony_ci m_positions.push_back(fy); 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ci addIndex(curIndex++); 335e5c31af7Sopenharmony_ci } 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_ci if (col < numCols - 1 || row < numRows - 1) // Add a restart after all but last polygon. 338e5c31af7Sopenharmony_ci { 339e5c31af7Sopenharmony_ci addIndex(restartIndex); 340e5c31af7Sopenharmony_ci if (m_duplicateRestarts) 341e5c31af7Sopenharmony_ci addIndex(restartIndex); 342e5c31af7Sopenharmony_ci } 343e5c31af7Sopenharmony_ci } 344e5c31af7Sopenharmony_ci } 345e5c31af7Sopenharmony_ci } 346e5c31af7Sopenharmony_ci else if (m_primType == PRIMITIVE_TRIANGLE_STRIP) 347e5c31af7Sopenharmony_ci { 348e5c31af7Sopenharmony_ci // Generate a number of horizontal triangle strips of different lengths. 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci deUint32 curIndex = 0; 351e5c31af7Sopenharmony_ci const int numStrips = 20; 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci for (int stripNdx = 0; stripNdx < numStrips; stripNdx++) 354e5c31af7Sopenharmony_ci { 355e5c31af7Sopenharmony_ci int numVertices = stripNdx + 1; 356e5c31af7Sopenharmony_ci 357e5c31af7Sopenharmony_ci for (int i = 0; i < numVertices; i++) 358e5c31af7Sopenharmony_ci { 359e5c31af7Sopenharmony_ci float fx = -0.9f + 1.8f * (float)(i/2*2) / numStrips; 360e5c31af7Sopenharmony_ci float fy = -0.9f + 1.8f * ((float)stripNdx + (i%2 == 0 ? 0.0f : 0.8f)) / numStrips; 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci m_positions.push_back(fx); 363e5c31af7Sopenharmony_ci m_positions.push_back(fy); 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci addIndex(curIndex++); 366e5c31af7Sopenharmony_ci } 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ci if (stripNdx < numStrips - 1) // Add a restart after all but last strip. 369e5c31af7Sopenharmony_ci { 370e5c31af7Sopenharmony_ci addIndex(restartIndex); 371e5c31af7Sopenharmony_ci if (m_duplicateRestarts) 372e5c31af7Sopenharmony_ci addIndex(restartIndex); 373e5c31af7Sopenharmony_ci } 374e5c31af7Sopenharmony_ci } 375e5c31af7Sopenharmony_ci } 376e5c31af7Sopenharmony_ci else if (m_primType == PRIMITIVE_TRIANGLE_FAN) 377e5c31af7Sopenharmony_ci { 378e5c31af7Sopenharmony_ci // Generate a numRows x numCols arrangement of triangle fan polygons of different vertex counts. 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_ci deUint32 curIndex = 0; 381e5c31af7Sopenharmony_ci const int numRows = 4; 382e5c31af7Sopenharmony_ci const int numCols = 4; 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ci for (int row = 0; row < numRows; row++) 385e5c31af7Sopenharmony_ci { 386e5c31af7Sopenharmony_ci float centerY = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows; 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci for (int col = 0; col < numCols; col++) 389e5c31af7Sopenharmony_ci { 390e5c31af7Sopenharmony_ci float centerX = -1.0f + 2.0f * ((float)col + 0.5f) / (float)numCols; 391e5c31af7Sopenharmony_ci int numArcVertices = row*numCols + col; 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_ci m_positions.push_back(centerX); 394e5c31af7Sopenharmony_ci m_positions.push_back(centerY); 395e5c31af7Sopenharmony_ci 396e5c31af7Sopenharmony_ci addIndex(curIndex++); 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ci for (int i = 0; i < numArcVertices; i++) 399e5c31af7Sopenharmony_ci { 400e5c31af7Sopenharmony_ci float fx = centerX + 0.9f * deFloatCos((float)i*2.0f*DE_PI / (float)numArcVertices) / (float)numCols; 401e5c31af7Sopenharmony_ci float fy = centerY + 0.9f * deFloatSin((float)i*2.0f*DE_PI / (float)numArcVertices) / (float)numRows; 402e5c31af7Sopenharmony_ci 403e5c31af7Sopenharmony_ci m_positions.push_back(fx); 404e5c31af7Sopenharmony_ci m_positions.push_back(fy); 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci addIndex(curIndex++); 407e5c31af7Sopenharmony_ci } 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ci if (col < numCols - 1 || row < numRows - 1) // Add a restart after all but last polygon. 410e5c31af7Sopenharmony_ci { 411e5c31af7Sopenharmony_ci addIndex(restartIndex); 412e5c31af7Sopenharmony_ci if (m_duplicateRestarts) 413e5c31af7Sopenharmony_ci addIndex(restartIndex); 414e5c31af7Sopenharmony_ci } 415e5c31af7Sopenharmony_ci } 416e5c31af7Sopenharmony_ci } 417e5c31af7Sopenharmony_ci } 418e5c31af7Sopenharmony_ci else if (m_primType == PRIMITIVE_TRIANGLES) 419e5c31af7Sopenharmony_ci { 420e5c31af7Sopenharmony_ci // Generate a number of rows with (potentially incomplete) triangles. 421e5c31af7Sopenharmony_ci 422e5c31af7Sopenharmony_ci deUint32 curIndex = 0; 423e5c31af7Sopenharmony_ci const int numRows = 3*7; 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_ci for (int rowNdx = 0; rowNdx < numRows; rowNdx++) 426e5c31af7Sopenharmony_ci { 427e5c31af7Sopenharmony_ci int numVertices = rowNdx + 1; 428e5c31af7Sopenharmony_ci 429e5c31af7Sopenharmony_ci for (int i = 0; i < numVertices; i++) 430e5c31af7Sopenharmony_ci { 431e5c31af7Sopenharmony_ci float fx = -0.9f + 1.8f * ((float)(i/3) + (i%3 == 2 ? 0.8f : 0.0f)) * 3 / numRows; 432e5c31af7Sopenharmony_ci float fy = -0.9f + 1.8f * ((float)rowNdx + (i%3 == 0 ? 0.0f : 0.8f)) / numRows; 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_ci m_positions.push_back(fx); 435e5c31af7Sopenharmony_ci m_positions.push_back(fy); 436e5c31af7Sopenharmony_ci 437e5c31af7Sopenharmony_ci addIndex(curIndex++); 438e5c31af7Sopenharmony_ci } 439e5c31af7Sopenharmony_ci 440e5c31af7Sopenharmony_ci if (rowNdx < numRows - 1) // Add a restart after all but last row. 441e5c31af7Sopenharmony_ci { 442e5c31af7Sopenharmony_ci addIndex(restartIndex); 443e5c31af7Sopenharmony_ci if (m_duplicateRestarts) 444e5c31af7Sopenharmony_ci addIndex(restartIndex); 445e5c31af7Sopenharmony_ci } 446e5c31af7Sopenharmony_ci } 447e5c31af7Sopenharmony_ci } 448e5c31af7Sopenharmony_ci else 449e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 450e5c31af7Sopenharmony_ci 451e5c31af7Sopenharmony_ci // If testing a case with restart at end, add it there. 452e5c31af7Sopenharmony_ci if (m_endWithRestart) 453e5c31af7Sopenharmony_ci { 454e5c31af7Sopenharmony_ci addIndex(restartIndex); 455e5c31af7Sopenharmony_ci if (m_duplicateRestarts) 456e5c31af7Sopenharmony_ci addIndex(restartIndex); 457e5c31af7Sopenharmony_ci } 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_ci // Special case assertions. 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci int numIndices = getNumIndices(); 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci DE_ASSERT(numIndices > 0); 464e5c31af7Sopenharmony_ci DE_ASSERT(m_beginWithRestart || getIndex(0) != restartIndex); // We don't want restarts at beginning unless the case is a special case. 465e5c31af7Sopenharmony_ci DE_ASSERT(m_endWithRestart || getIndex(numIndices-1) != restartIndex); // We don't want restarts at end unless the case is a special case. 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ci if (!m_duplicateRestarts) 468e5c31af7Sopenharmony_ci for (int i = 1; i < numIndices; i++) 469e5c31af7Sopenharmony_ci DE_ASSERT(getIndex(i) != restartIndex || getIndex(i-1) != restartIndex); // We don't want duplicate restarts unless the case is a special case. 470e5c31af7Sopenharmony_ci} 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_ciPrimitiveRestartCase::IterateResult PrimitiveRestartCase::iterate (void) 473e5c31af7Sopenharmony_ci{ 474e5c31af7Sopenharmony_ci int width = deMin32(m_context.getRenderTarget().getWidth(), MAX_RENDER_WIDTH); 475e5c31af7Sopenharmony_ci int height = deMin32(m_context.getRenderTarget().getHeight(), MAX_RENDER_HEIGHT); 476e5c31af7Sopenharmony_ci 477e5c31af7Sopenharmony_ci int xOffsetMax = m_context.getRenderTarget().getWidth() - width; 478e5c31af7Sopenharmony_ci int yOffsetMax = m_context.getRenderTarget().getHeight() - height; 479e5c31af7Sopenharmony_ci 480e5c31af7Sopenharmony_ci de::Random rnd (deStringHash(getName())); 481e5c31af7Sopenharmony_ci 482e5c31af7Sopenharmony_ci int xOffset = rnd.getInt(0, xOffsetMax); 483e5c31af7Sopenharmony_ci int yOffset = rnd.getInt(0, yOffsetMax); 484e5c31af7Sopenharmony_ci tcu::Surface referenceImg (width, height); 485e5c31af7Sopenharmony_ci tcu::Surface resultImg (width, height); 486e5c31af7Sopenharmony_ci 487e5c31af7Sopenharmony_ci glViewport(xOffset, yOffset, width, height); 488e5c31af7Sopenharmony_ci glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 489e5c31af7Sopenharmony_ci 490e5c31af7Sopenharmony_ci deUint32 program = m_program->getProgram(); 491e5c31af7Sopenharmony_ci glUseProgram(program); 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci // Setup position attribute. 494e5c31af7Sopenharmony_ci 495e5c31af7Sopenharmony_ci int loc = glGetAttribLocation(program, "a_position"); 496e5c31af7Sopenharmony_ci glEnableVertexAttribArray(loc); 497e5c31af7Sopenharmony_ci glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, &m_positions[0]); 498e5c31af7Sopenharmony_ci 499e5c31af7Sopenharmony_ci // Render result. 500e5c31af7Sopenharmony_ci 501e5c31af7Sopenharmony_ci renderWithRestart(); 502e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), xOffset, yOffset, resultImg.getAccess()); 503e5c31af7Sopenharmony_ci 504e5c31af7Sopenharmony_ci // Render reference (same scene as the real deal, but emulate primitive restart without actually using it). 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci renderWithoutRestart(); 507e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), xOffset, yOffset, referenceImg.getAccess()); 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci // Compare. 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci bool testOk = tcu::pixelThresholdCompare(m_testCtx.getLog(), "ComparisonResult", "Image comparison result", referenceImg, resultImg, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT); 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci m_testCtx.setTestResult(testOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 514e5c31af7Sopenharmony_ci testOk ? "Pass" : "Fail"); 515e5c31af7Sopenharmony_ci 516e5c31af7Sopenharmony_ci glUseProgram(0); 517e5c31af7Sopenharmony_ci 518e5c31af7Sopenharmony_ci return STOP; 519e5c31af7Sopenharmony_ci} 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_ci// Draw with the appropriate GLES3 draw function. 522e5c31af7Sopenharmony_civoid PrimitiveRestartCase::draw (int startNdx, int count) 523e5c31af7Sopenharmony_ci{ 524e5c31af7Sopenharmony_ci GLenum primTypeGL; 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci switch (m_primType) 527e5c31af7Sopenharmony_ci { 528e5c31af7Sopenharmony_ci case PRIMITIVE_POINTS: primTypeGL = GL_POINTS; break; 529e5c31af7Sopenharmony_ci case PRIMITIVE_LINE_STRIP: primTypeGL = GL_LINE_STRIP; break; 530e5c31af7Sopenharmony_ci case PRIMITIVE_LINE_LOOP: primTypeGL = GL_LINE_LOOP; break; 531e5c31af7Sopenharmony_ci case PRIMITIVE_LINES: primTypeGL = GL_LINES; break; 532e5c31af7Sopenharmony_ci case PRIMITIVE_TRIANGLE_STRIP: primTypeGL = GL_TRIANGLE_STRIP; break; 533e5c31af7Sopenharmony_ci case PRIMITIVE_TRIANGLE_FAN: primTypeGL = GL_TRIANGLE_FAN; break; 534e5c31af7Sopenharmony_ci case PRIMITIVE_TRIANGLES: primTypeGL = GL_TRIANGLES; break; 535e5c31af7Sopenharmony_ci default: 536e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 537e5c31af7Sopenharmony_ci primTypeGL = 0; 538e5c31af7Sopenharmony_ci } 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_ci GLenum indexTypeGL; 541e5c31af7Sopenharmony_ci 542e5c31af7Sopenharmony_ci switch (m_indexType) 543e5c31af7Sopenharmony_ci { 544e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_BYTE: indexTypeGL = GL_UNSIGNED_BYTE; break; 545e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_SHORT: indexTypeGL = GL_UNSIGNED_SHORT; break; 546e5c31af7Sopenharmony_ci case INDEX_UNSIGNED_INT: indexTypeGL = GL_UNSIGNED_INT; break; 547e5c31af7Sopenharmony_ci default: 548e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 549e5c31af7Sopenharmony_ci indexTypeGL = 0; 550e5c31af7Sopenharmony_ci } 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci deUint32 restartIndex = m_indexType == INDEX_UNSIGNED_BYTE ? RESTART_INDEX_UNSIGNED_BYTE 553e5c31af7Sopenharmony_ci : m_indexType == INDEX_UNSIGNED_SHORT ? RESTART_INDEX_UNSIGNED_SHORT 554e5c31af7Sopenharmony_ci : m_indexType == INDEX_UNSIGNED_INT ? RESTART_INDEX_UNSIGNED_INT 555e5c31af7Sopenharmony_ci : 0; 556e5c31af7Sopenharmony_ci 557e5c31af7Sopenharmony_ci DE_ASSERT(restartIndex != 0); 558e5c31af7Sopenharmony_ci 559e5c31af7Sopenharmony_ci if (m_function == FUNCTION_DRAW_ELEMENTS) 560e5c31af7Sopenharmony_ci glDrawElements(primTypeGL, (GLsizei)count, indexTypeGL, (GLvoid*)getIndexPtr(startNdx)); 561e5c31af7Sopenharmony_ci else if (m_function == FUNCTION_DRAW_ELEMENTS_INSTANCED) 562e5c31af7Sopenharmony_ci glDrawElementsInstanced(primTypeGL, (GLsizei)count, indexTypeGL, (GLvoid*)getIndexPtr(startNdx), 1); 563e5c31af7Sopenharmony_ci else 564e5c31af7Sopenharmony_ci { 565e5c31af7Sopenharmony_ci DE_ASSERT(m_function == FUNCTION_DRAW_RANGE_ELEMENTS); 566e5c31af7Sopenharmony_ci 567e5c31af7Sopenharmony_ci // Find the largest non-restart index in the index array (for glDrawRangeElements() end parameter). 568e5c31af7Sopenharmony_ci 569e5c31af7Sopenharmony_ci deUint32 max = 0; 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ci int numIndices = getNumIndices(); 572e5c31af7Sopenharmony_ci for (int i = 0; i < numIndices; i++) 573e5c31af7Sopenharmony_ci { 574e5c31af7Sopenharmony_ci deUint32 index = getIndex(i); 575e5c31af7Sopenharmony_ci if (index != restartIndex && index > max) 576e5c31af7Sopenharmony_ci max = index; 577e5c31af7Sopenharmony_ci } 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_ci glDrawRangeElements(primTypeGL, 0, (GLuint)max, (GLsizei)count, indexTypeGL, (GLvoid*)getIndexPtr(startNdx)); 580e5c31af7Sopenharmony_ci } 581e5c31af7Sopenharmony_ci} 582e5c31af7Sopenharmony_ci 583e5c31af7Sopenharmony_civoid PrimitiveRestartCase::renderWithRestart (void) 584e5c31af7Sopenharmony_ci{ 585e5c31af7Sopenharmony_ci GLU_CHECK_MSG("PrimitiveRestartCase::renderWithRestart() begin"); 586e5c31af7Sopenharmony_ci 587e5c31af7Sopenharmony_ci glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); 588e5c31af7Sopenharmony_ci GLU_CHECK_MSG("Enable primitive restart"); 589e5c31af7Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 590e5c31af7Sopenharmony_ci GLU_CHECK_MSG("Clear in PrimitiveRestartCase::renderWithRestart()"); 591e5c31af7Sopenharmony_ci 592e5c31af7Sopenharmony_ci draw(0, getNumIndices()); 593e5c31af7Sopenharmony_ci 594e5c31af7Sopenharmony_ci GLU_CHECK_MSG("Draw in PrimitiveRestartCase::renderWithRestart()"); 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_ci GLU_CHECK_MSG("PrimitiveRestartCase::renderWithRestart() end"); 597e5c31af7Sopenharmony_ci} 598e5c31af7Sopenharmony_ci 599e5c31af7Sopenharmony_civoid PrimitiveRestartCase::renderWithoutRestart (void) 600e5c31af7Sopenharmony_ci{ 601e5c31af7Sopenharmony_ci GLU_CHECK_MSG("PrimitiveRestartCase::renderWithoutRestart() begin"); 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_ci deUint32 restartIndex = m_indexType == INDEX_UNSIGNED_BYTE ? RESTART_INDEX_UNSIGNED_BYTE 604e5c31af7Sopenharmony_ci : m_indexType == INDEX_UNSIGNED_SHORT ? RESTART_INDEX_UNSIGNED_SHORT 605e5c31af7Sopenharmony_ci : m_indexType == INDEX_UNSIGNED_INT ? RESTART_INDEX_UNSIGNED_INT 606e5c31af7Sopenharmony_ci : 0; 607e5c31af7Sopenharmony_ci 608e5c31af7Sopenharmony_ci DE_ASSERT(restartIndex != 0); 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_ci glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX); 611e5c31af7Sopenharmony_ci GLU_CHECK_MSG("Disable primitive restart"); 612e5c31af7Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 613e5c31af7Sopenharmony_ci GLU_CHECK_MSG("Clear in PrimitiveRestartCase::renderWithoutRestart()"); 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ci // Draw, emulating primitive restart. 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ci int numIndices = getNumIndices(); 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_ci DE_ASSERT(numIndices >= 0); 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci int indexArrayStartNdx = 0; // Keep track of the draw start index - first index after a primitive restart, or initially the first index altogether. 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci for (int indexArrayNdx = 0; indexArrayNdx <= numIndices; indexArrayNdx++) // \note Goes one "too far" in order to detect end of array as well. 624e5c31af7Sopenharmony_ci { 625e5c31af7Sopenharmony_ci if (indexArrayNdx >= numIndices || getIndex(indexArrayNdx) == restartIndex) // \note Handle end of array the same way as a restart index encounter. 626e5c31af7Sopenharmony_ci { 627e5c31af7Sopenharmony_ci if (indexArrayStartNdx < numIndices) 628e5c31af7Sopenharmony_ci { 629e5c31af7Sopenharmony_ci // Draw from index indexArrayStartNdx to index indexArrayNdx-1 . 630e5c31af7Sopenharmony_ci 631e5c31af7Sopenharmony_ci draw(indexArrayStartNdx, indexArrayNdx - indexArrayStartNdx); 632e5c31af7Sopenharmony_ci GLU_CHECK_MSG("Draw in PrimitiveRestartCase::renderWithoutRestart()"); 633e5c31af7Sopenharmony_ci } 634e5c31af7Sopenharmony_ci 635e5c31af7Sopenharmony_ci indexArrayStartNdx = indexArrayNdx + 1; // Next draw starts just after this restart index. 636e5c31af7Sopenharmony_ci } 637e5c31af7Sopenharmony_ci } 638e5c31af7Sopenharmony_ci 639e5c31af7Sopenharmony_ci GLU_CHECK_MSG("PrimitiveRestartCase::renderWithoutRestart() end"); 640e5c31af7Sopenharmony_ci} 641e5c31af7Sopenharmony_ci 642e5c31af7Sopenharmony_ciPrimitiveRestartTests::PrimitiveRestartTests (Context& context) 643e5c31af7Sopenharmony_ci : TestCaseGroup(context, "primitive_restart", "Primitive restart tests") 644e5c31af7Sopenharmony_ci{ 645e5c31af7Sopenharmony_ci} 646e5c31af7Sopenharmony_ci 647e5c31af7Sopenharmony_ciPrimitiveRestartTests::~PrimitiveRestartTests (void) 648e5c31af7Sopenharmony_ci{ 649e5c31af7Sopenharmony_ci} 650e5c31af7Sopenharmony_ci 651e5c31af7Sopenharmony_civoid PrimitiveRestartTests::init (void) 652e5c31af7Sopenharmony_ci{ 653e5c31af7Sopenharmony_ci for (int isRestartBeginCaseI = 0; isRestartBeginCaseI <= 1; isRestartBeginCaseI++) 654e5c31af7Sopenharmony_ci for (int isRestartEndCaseI = 0; isRestartEndCaseI <= 1; isRestartEndCaseI++) 655e5c31af7Sopenharmony_ci for (int isDuplicateRestartCaseI = 0; isDuplicateRestartCaseI <= 1; isDuplicateRestartCaseI++) 656e5c31af7Sopenharmony_ci { 657e5c31af7Sopenharmony_ci bool isRestartBeginCase = isRestartBeginCaseI != 0; 658e5c31af7Sopenharmony_ci bool isRestartEndCase = isRestartEndCaseI != 0; 659e5c31af7Sopenharmony_ci bool isDuplicateRestartCase = isDuplicateRestartCaseI != 0; 660e5c31af7Sopenharmony_ci 661e5c31af7Sopenharmony_ci std::string specialCaseGroupName; 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_ci if (isRestartBeginCase) specialCaseGroupName = "begin_restart"; 664e5c31af7Sopenharmony_ci if (isRestartEndCase) specialCaseGroupName += std::string(specialCaseGroupName.empty() ? "" : "_") + "end_restart"; 665e5c31af7Sopenharmony_ci if (isDuplicateRestartCase) specialCaseGroupName += std::string(specialCaseGroupName.empty() ? "" : "_") + "duplicate_restarts"; 666e5c31af7Sopenharmony_ci 667e5c31af7Sopenharmony_ci if (specialCaseGroupName.empty()) 668e5c31af7Sopenharmony_ci specialCaseGroupName = "basic"; 669e5c31af7Sopenharmony_ci 670e5c31af7Sopenharmony_ci TestCaseGroup* specialCaseGroup = new TestCaseGroup(m_context, specialCaseGroupName.c_str(), ""); 671e5c31af7Sopenharmony_ci addChild(specialCaseGroup); 672e5c31af7Sopenharmony_ci 673e5c31af7Sopenharmony_ci for (int primType = 0; primType < (int)PrimitiveRestartCase::PRIMITIVE_LAST; primType++) 674e5c31af7Sopenharmony_ci { 675e5c31af7Sopenharmony_ci const char* primTypeName = primType == (int)PrimitiveRestartCase::PRIMITIVE_POINTS ? "points" 676e5c31af7Sopenharmony_ci : primType == (int)PrimitiveRestartCase::PRIMITIVE_LINE_STRIP ? "line_strip" 677e5c31af7Sopenharmony_ci : primType == (int)PrimitiveRestartCase::PRIMITIVE_LINE_LOOP ? "line_loop" 678e5c31af7Sopenharmony_ci : primType == (int)PrimitiveRestartCase::PRIMITIVE_LINES ? "lines" 679e5c31af7Sopenharmony_ci : primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLE_STRIP ? "triangle_strip" 680e5c31af7Sopenharmony_ci : primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLE_FAN ? "triangle_fan" 681e5c31af7Sopenharmony_ci : primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLES ? "triangles" 682e5c31af7Sopenharmony_ci : DE_NULL; 683e5c31af7Sopenharmony_ci 684e5c31af7Sopenharmony_ci DE_ASSERT(primTypeName != DE_NULL); 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci TestCaseGroup* primTypeGroup = new TestCaseGroup(m_context, primTypeName, ""); 687e5c31af7Sopenharmony_ci specialCaseGroup->addChild(primTypeGroup); 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_ci for (int indexType = 0; indexType < (int)PrimitiveRestartCase::INDEX_LAST; indexType++) 690e5c31af7Sopenharmony_ci { 691e5c31af7Sopenharmony_ci const char *indexTypeName = indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_BYTE ? "unsigned_byte" 692e5c31af7Sopenharmony_ci : indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_SHORT ? "unsigned_short" 693e5c31af7Sopenharmony_ci : indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_INT ? "unsigned_int" 694e5c31af7Sopenharmony_ci : DE_NULL; 695e5c31af7Sopenharmony_ci 696e5c31af7Sopenharmony_ci DE_ASSERT(indexTypeName != DE_NULL); 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci TestCaseGroup* indexTypeGroup = new TestCaseGroup(m_context, indexTypeName, ""); 699e5c31af7Sopenharmony_ci primTypeGroup->addChild(indexTypeGroup); 700e5c31af7Sopenharmony_ci 701e5c31af7Sopenharmony_ci for (int function = 0; function < (int)PrimitiveRestartCase::FUNCTION_LAST; function++) 702e5c31af7Sopenharmony_ci { 703e5c31af7Sopenharmony_ci const char* functionName = function == (int)PrimitiveRestartCase::FUNCTION_DRAW_ELEMENTS ? "draw_elements" 704e5c31af7Sopenharmony_ci : function == (int)PrimitiveRestartCase::FUNCTION_DRAW_ELEMENTS_INSTANCED ? "draw_elements_instanced" 705e5c31af7Sopenharmony_ci : function == (int)PrimitiveRestartCase::FUNCTION_DRAW_RANGE_ELEMENTS ? "draw_range_elements" 706e5c31af7Sopenharmony_ci : DE_NULL; 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci DE_ASSERT(functionName != DE_NULL); 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ci indexTypeGroup->addChild(new PrimitiveRestartCase(m_context, 711e5c31af7Sopenharmony_ci functionName, 712e5c31af7Sopenharmony_ci "", 713e5c31af7Sopenharmony_ci (PrimitiveRestartCase::PrimitiveType)primType, 714e5c31af7Sopenharmony_ci (PrimitiveRestartCase::IndexType)indexType, 715e5c31af7Sopenharmony_ci (PrimitiveRestartCase::Function)function, 716e5c31af7Sopenharmony_ci isRestartBeginCase, 717e5c31af7Sopenharmony_ci isRestartEndCase, 718e5c31af7Sopenharmony_ci isDuplicateRestartCase)); 719e5c31af7Sopenharmony_ci } 720e5c31af7Sopenharmony_ci } 721e5c31af7Sopenharmony_ci } 722e5c31af7Sopenharmony_ci } 723e5c31af7Sopenharmony_ci} 724e5c31af7Sopenharmony_ci 725e5c31af7Sopenharmony_ci} // Functional 726e5c31af7Sopenharmony_ci} // gles3 727e5c31af7Sopenharmony_ci} // deqp 728