1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2014-2016 The Khronos Group Inc. 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 22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "esextcTessellationShaderTriangles.hpp" 25e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 26e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 27e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 28e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 29e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_cinamespace glcts 32e5c31af7Sopenharmony_ci{ 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_ci/** Constructor 35e5c31af7Sopenharmony_ci * 36e5c31af7Sopenharmony_ci * @param context Test context 37e5c31af7Sopenharmony_ci **/ 38e5c31af7Sopenharmony_ciTessellationShaderTrianglesTests::TessellationShaderTrianglesTests(glcts::Context& context, 39e5c31af7Sopenharmony_ci const ExtParameters& extParams) 40e5c31af7Sopenharmony_ci : TestCaseGroupBase(context, extParams, "tessellation_shader_triangles_tessellation", 41e5c31af7Sopenharmony_ci "Verifies triangle tessellation functionality") 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_ci /* No implementation needed */ 44e5c31af7Sopenharmony_ci} 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ci/** 47e5c31af7Sopenharmony_ci * Initializes test groups for geometry shader tests 48e5c31af7Sopenharmony_ci **/ 49e5c31af7Sopenharmony_civoid TessellationShaderTrianglesTests::init(void) 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci addChild(new glcts::TessellationShaderTrianglesDegenerateTriangle(m_context, m_extParams)); 52e5c31af7Sopenharmony_ci addChild(new glcts::TessellationShaderTrianglesIdenticalTriangles(m_context, m_extParams)); 53e5c31af7Sopenharmony_ci addChild(new glcts::TessellationShaderTrianglesInnerTessellationLevelRounding(m_context, m_extParams)); 54e5c31af7Sopenharmony_ci} 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ci/** Constructor 57e5c31af7Sopenharmony_ci * 58e5c31af7Sopenharmony_ci * @param context Test context 59e5c31af7Sopenharmony_ci **/ 60e5c31af7Sopenharmony_ciTessellationShaderTrianglesDegenerateTriangle::TessellationShaderTrianglesDegenerateTriangle( 61e5c31af7Sopenharmony_ci Context& context, const ExtParameters& extParams) 62e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, "degenerate_triangle", 63e5c31af7Sopenharmony_ci "Verifies a degenerate triangle is generated by tessellator " 64e5c31af7Sopenharmony_ci "under a specific configuration of inner/outer tessellation " 65e5c31af7Sopenharmony_ci "levels & vertex spacing modes.") 66e5c31af7Sopenharmony_ci , m_bo_id(0) 67e5c31af7Sopenharmony_ci , m_fs_id(0) 68e5c31af7Sopenharmony_ci , m_tc_id(0) 69e5c31af7Sopenharmony_ci , m_vs_id(0) 70e5c31af7Sopenharmony_ci , m_vao_id(0) 71e5c31af7Sopenharmony_ci{ 72e5c31af7Sopenharmony_ci /* Left blank on purpose */ 73e5c31af7Sopenharmony_ci} 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ci/** Deinitializes ES objects created for the test. */ 76e5c31af7Sopenharmony_civoid TessellationShaderTrianglesDegenerateTriangle::deinit() 77e5c31af7Sopenharmony_ci{ 78e5c31af7Sopenharmony_ci /* Call base class' deinit() */ 79e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 82e5c31af7Sopenharmony_ci { 83e5c31af7Sopenharmony_ci return; 84e5c31af7Sopenharmony_ci } 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 87e5c31af7Sopenharmony_ci 88e5c31af7Sopenharmony_ci /* Deinitialize TF buffer object bindings */ 89e5c31af7Sopenharmony_ci gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* buffer */); 90e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 0 /* buffer */); 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_ci /* Reset GL_PATCH_VERTICES_EXT value */ 93e5c31af7Sopenharmony_ci gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 3); 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci /* Unbind vertex array object */ 96e5c31af7Sopenharmony_ci gl.bindVertexArray(0); 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ci /* Free all ES objects we allocated for the test */ 99e5c31af7Sopenharmony_ci if (m_bo_id != 0) 100e5c31af7Sopenharmony_ci { 101e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_bo_id); 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ci m_bo_id = 0; 104e5c31af7Sopenharmony_ci } 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ci if (m_fs_id != 0) 107e5c31af7Sopenharmony_ci { 108e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci m_fs_id = 0; 111e5c31af7Sopenharmony_ci } 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci if (m_tc_id != 0) 114e5c31af7Sopenharmony_ci { 115e5c31af7Sopenharmony_ci gl.deleteShader(m_tc_id); 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci m_tc_id = 0; 118e5c31af7Sopenharmony_ci } 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci if (m_vs_id != 0) 121e5c31af7Sopenharmony_ci { 122e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci m_vs_id = 0; 125e5c31af7Sopenharmony_ci } 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci if (m_vao_id != 0) 128e5c31af7Sopenharmony_ci { 129e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci m_vao_id = 0; 132e5c31af7Sopenharmony_ci } 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci /* Deinitialize all test descriptors */ 135e5c31af7Sopenharmony_ci for (_tests::iterator it = m_tests.begin(); it != m_tests.end(); ++it) 136e5c31af7Sopenharmony_ci { 137e5c31af7Sopenharmony_ci deinitTestDescriptor(*it); 138e5c31af7Sopenharmony_ci } 139e5c31af7Sopenharmony_ci m_tests.clear(); 140e5c31af7Sopenharmony_ci} 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci/** Deinitialize all test pass-specific ES objects. 143e5c31af7Sopenharmony_ci * 144e5c31af7Sopenharmony_ci * @param test Descriptor of a test pass to deinitialize. 145e5c31af7Sopenharmony_ci **/ 146e5c31af7Sopenharmony_civoid TessellationShaderTrianglesDegenerateTriangle::deinitTestDescriptor(_test_descriptor& test) 147e5c31af7Sopenharmony_ci{ 148e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci if (test.po_id != 0) 151e5c31af7Sopenharmony_ci { 152e5c31af7Sopenharmony_ci gl.deleteProgram(test.po_id); 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ci test.po_id = 0; 155e5c31af7Sopenharmony_ci } 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci if (test.te_id != 0) 158e5c31af7Sopenharmony_ci { 159e5c31af7Sopenharmony_ci gl.deleteShader(test.te_id); 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_ci test.te_id = 0; 162e5c31af7Sopenharmony_ci } 163e5c31af7Sopenharmony_ci} 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci/** Initializes ES objects necessary to run the test. */ 166e5c31af7Sopenharmony_civoid TessellationShaderTrianglesDegenerateTriangle::initTest() 167e5c31af7Sopenharmony_ci{ 168e5c31af7Sopenharmony_ci /* Skip if required extensions are not supported. */ 169e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 170e5c31af7Sopenharmony_ci { 171e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED); 172e5c31af7Sopenharmony_ci } 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci /* Generate all test-wide objects needed for test execution */ 175e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 178e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object"); 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 181e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!"); 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_bo_id); 184e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed"); 185e5c31af7Sopenharmony_ci 186e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 187e5c31af7Sopenharmony_ci m_tc_id = gl.createShader(m_glExtTokens.TESS_CONTROL_SHADER); 188e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 189e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() failed"); 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci /* Configure fragment shader body */ 192e5c31af7Sopenharmony_ci const char* fs_body = "${VERSION}\n" 193e5c31af7Sopenharmony_ci "\n" 194e5c31af7Sopenharmony_ci "void main()\n" 195e5c31af7Sopenharmony_ci "{\n" 196e5c31af7Sopenharmony_ci "}\n"; 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_ci shaderSourceSpecialized(m_fs_id, 1 /* count */, &fs_body); 199e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed for fragment shader"); 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ci /* Configure tessellation control shader body */ 202e5c31af7Sopenharmony_ci const char* tc_body = "${VERSION}\n" 203e5c31af7Sopenharmony_ci "\n" 204e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 205e5c31af7Sopenharmony_ci "\n" 206e5c31af7Sopenharmony_ci "layout (vertices=3) out;\n" 207e5c31af7Sopenharmony_ci "\n" 208e5c31af7Sopenharmony_ci "void main()\n" 209e5c31af7Sopenharmony_ci "{\n" 210e5c31af7Sopenharmony_ci " gl_out [gl_InvocationID].gl_Position = gl_in[0].gl_Position;\n" 211e5c31af7Sopenharmony_ci "\n" 212e5c31af7Sopenharmony_ci " gl_TessLevelInner[0] = 1.0;\n" 213e5c31af7Sopenharmony_ci " gl_TessLevelOuter[0] = 1.0;\n" 214e5c31af7Sopenharmony_ci " gl_TessLevelOuter[1] = 1.0;\n" 215e5c31af7Sopenharmony_ci " gl_TessLevelOuter[2] = 1.0;\n" 216e5c31af7Sopenharmony_ci "}\n"; 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci shaderSourceSpecialized(m_tc_id, 1 /* count */, &tc_body); 219e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed for tessellation control shader"); 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci /* Configure vertex shader body */ 222e5c31af7Sopenharmony_ci const char* vs_body = "${VERSION}\n" 223e5c31af7Sopenharmony_ci "\n" 224e5c31af7Sopenharmony_ci "void main()\n" 225e5c31af7Sopenharmony_ci "{\n" 226e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n" 227e5c31af7Sopenharmony_ci "}\n"; 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci shaderSourceSpecialized(m_vs_id, 1 /* count */, &vs_body); 230e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed for vertex shader"); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci /* Compile all the shaders */ 233e5c31af7Sopenharmony_ci const glw::GLuint shaders[] = { m_fs_id, m_tc_id, m_vs_id }; 234e5c31af7Sopenharmony_ci const unsigned int n_shaders = sizeof(shaders) / sizeof(shaders[0]); 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader) 237e5c31af7Sopenharmony_ci { 238e5c31af7Sopenharmony_ci glw::GLuint shader = shaders[n_shader]; 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ci if (shader != 0) 241e5c31af7Sopenharmony_ci { 242e5c31af7Sopenharmony_ci glw::GLint compile_status = GL_FALSE; 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci gl.compileShader(shader); 245e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed"); 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci gl.getShaderiv(shader, GL_COMPILE_STATUS, &compile_status); 248e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed"); 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci if (compile_status != GL_TRUE) 251e5c31af7Sopenharmony_ci { 252e5c31af7Sopenharmony_ci TCU_FAIL("Shader compilation failed"); 253e5c31af7Sopenharmony_ci } 254e5c31af7Sopenharmony_ci } 255e5c31af7Sopenharmony_ci } /* for (all shaders) */ 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci /* Initialize all test passes */ 258e5c31af7Sopenharmony_ci _test_descriptor test_equal_spacing; 259e5c31af7Sopenharmony_ci _test_descriptor test_fractional_odd_spacing; 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci initTestDescriptor(test_equal_spacing, TESSELLATION_SHADER_VERTEX_SPACING_EQUAL); 262e5c31af7Sopenharmony_ci initTestDescriptor(test_fractional_odd_spacing, TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD); 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_ci m_tests.push_back(test_equal_spacing); 265e5c31af7Sopenharmony_ci m_tests.push_back(test_fractional_odd_spacing); 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_ci /* Set up buffer object storage */ 268e5c31af7Sopenharmony_ci gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id); 269e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed"); 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 3 /* components */ * 3 /* UVW sets */, NULL, /* data */ 272e5c31af7Sopenharmony_ci GL_STATIC_DRAW); 273e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed"); 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_ci /* Bind the buffer object to indiced TF binding point */ 276e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id); 277e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed"); 278e5c31af7Sopenharmony_ci} 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci/** Initializes all ES objects necessary to run a specific test pass. 281e5c31af7Sopenharmony_ci * 282e5c31af7Sopenharmony_ci * @param test Test descriptor to fill with IDs of initialized objects. 283e5c31af7Sopenharmony_ci * @param vertex_spacing Vertex spacing mode to use for the run. 284e5c31af7Sopenharmony_ci **/ 285e5c31af7Sopenharmony_civoid TessellationShaderTrianglesDegenerateTriangle::initTestDescriptor( 286e5c31af7Sopenharmony_ci _test_descriptor& test, _tessellation_shader_vertex_spacing vertex_spacing) 287e5c31af7Sopenharmony_ci{ 288e5c31af7Sopenharmony_ci test.vertex_spacing = vertex_spacing; 289e5c31af7Sopenharmony_ci 290e5c31af7Sopenharmony_ci /* Set up a program object for the descriptor */ 291e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ci test.po_id = gl.createProgram(); 294e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() failed"); 295e5c31af7Sopenharmony_ci 296e5c31af7Sopenharmony_ci /* Set up a pass-specific tessellation evaluation shader object. */ 297e5c31af7Sopenharmony_ci test.te_id = gl.createShader(m_glExtTokens.TESS_EVALUATION_SHADER); 298e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() failed"); 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci /* Configure tessellation evaluation shader body */ 301e5c31af7Sopenharmony_ci const char* te_template = "${VERSION}\n" 302e5c31af7Sopenharmony_ci "\n" 303e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 304e5c31af7Sopenharmony_ci "\n" 305e5c31af7Sopenharmony_ci "layout (triangles, VERTEX_SPACING_MODE) in;\n" 306e5c31af7Sopenharmony_ci "\n" 307e5c31af7Sopenharmony_ci "out vec3 result_uvw;\n" 308e5c31af7Sopenharmony_ci "\n" 309e5c31af7Sopenharmony_ci "void main()\n" 310e5c31af7Sopenharmony_ci "{\n" 311e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 312e5c31af7Sopenharmony_ci " result_uvw = gl_TessCoord;\n" 313e5c31af7Sopenharmony_ci "}\n"; 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ci const char* te_body_raw_ptr = DE_NULL; 316e5c31af7Sopenharmony_ci std::string te_body_string = te_template; 317e5c31af7Sopenharmony_ci std::string vertex_spacing_mode_string; 318e5c31af7Sopenharmony_ci const char* vertex_spacing_token = "VERTEX_SPACING_MODE"; 319e5c31af7Sopenharmony_ci std::size_t vertex_spacing_token_index = std::string::npos; 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci switch (vertex_spacing) 322e5c31af7Sopenharmony_ci { 323e5c31af7Sopenharmony_ci case TESSELLATION_SHADER_VERTEX_SPACING_EQUAL: 324e5c31af7Sopenharmony_ci { 325e5c31af7Sopenharmony_ci vertex_spacing_mode_string = "equal_spacing"; 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci break; 328e5c31af7Sopenharmony_ci } 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ci case TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD: 331e5c31af7Sopenharmony_ci { 332e5c31af7Sopenharmony_ci vertex_spacing_mode_string = "fractional_odd_spacing"; 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ci break; 335e5c31af7Sopenharmony_ci } 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_ci default: 338e5c31af7Sopenharmony_ci { 339e5c31af7Sopenharmony_ci TCU_FAIL("Invalid vertex spacing mode requested"); 340e5c31af7Sopenharmony_ci } 341e5c31af7Sopenharmony_ci } 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci while ((vertex_spacing_token_index = te_body_string.find(vertex_spacing_token)) != std::string::npos) 344e5c31af7Sopenharmony_ci { 345e5c31af7Sopenharmony_ci te_body_string = te_body_string.replace(vertex_spacing_token_index, strlen(vertex_spacing_token), 346e5c31af7Sopenharmony_ci vertex_spacing_mode_string); 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci vertex_spacing_token_index = te_body_string.find(vertex_spacing_token); 349e5c31af7Sopenharmony_ci } 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci te_body_raw_ptr = te_body_string.c_str(); 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci shaderSourceSpecialized(test.te_id, 1 /* count */, &te_body_raw_ptr); 354e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed for tessellation evaluation shader"); 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ci /* Compile the tessellation evaluation shader */ 357e5c31af7Sopenharmony_ci glw::GLint compile_status = GL_FALSE; 358e5c31af7Sopenharmony_ci 359e5c31af7Sopenharmony_ci gl.compileShader(test.te_id); 360e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed for tessellation evaluation shader"); 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci gl.getShaderiv(test.te_id, GL_COMPILE_STATUS, &compile_status); 363e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed for tessellation evaluation shader"); 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci if (compile_status != GL_TRUE) 366e5c31af7Sopenharmony_ci { 367e5c31af7Sopenharmony_ci TCU_FAIL("Tessellation evaluation shader compilation failed"); 368e5c31af7Sopenharmony_ci } 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci /* Attach all shader to the program object */ 371e5c31af7Sopenharmony_ci gl.attachShader(test.po_id, m_fs_id); 372e5c31af7Sopenharmony_ci gl.attachShader(test.po_id, m_tc_id); 373e5c31af7Sopenharmony_ci gl.attachShader(test.po_id, test.te_id); 374e5c31af7Sopenharmony_ci gl.attachShader(test.po_id, m_vs_id); 375e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed"); 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci /* Set up XFB */ 378e5c31af7Sopenharmony_ci const char* varyings[] = { "result_uvw" }; 379e5c31af7Sopenharmony_ci const unsigned int n_varyings = sizeof(varyings) / sizeof(varyings[0]); 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci gl.transformFeedbackVaryings(test.po_id, n_varyings, varyings, GL_INTERLEAVED_ATTRIBS); 382e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() failed"); 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ci /* Link the program object */ 385e5c31af7Sopenharmony_ci glw::GLint link_status = GL_FALSE; 386e5c31af7Sopenharmony_ci 387e5c31af7Sopenharmony_ci gl.linkProgram(test.po_id); 388e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed"); 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci gl.getProgramiv(test.po_id, GL_LINK_STATUS, &link_status); 391e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed"); 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_ci if (link_status != GL_TRUE) 394e5c31af7Sopenharmony_ci { 395e5c31af7Sopenharmony_ci TCU_FAIL("Program linking failed"); 396e5c31af7Sopenharmony_ci } 397e5c31af7Sopenharmony_ci} 398e5c31af7Sopenharmony_ci 399e5c31af7Sopenharmony_ci/** Executes the test. 400e5c31af7Sopenharmony_ci * 401e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 402e5c31af7Sopenharmony_ci * 403e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 404e5c31af7Sopenharmony_ci * 405e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again. 406e5c31af7Sopenharmony_ci **/ 407e5c31af7Sopenharmony_citcu::TestNode::IterateResult TessellationShaderTrianglesDegenerateTriangle::iterate(void) 408e5c31af7Sopenharmony_ci{ 409e5c31af7Sopenharmony_ci /* Do not execute if required extensions are not supported. */ 410e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 411e5c31af7Sopenharmony_ci { 412e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED); 413e5c31af7Sopenharmony_ci } 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci /* Initialize ES test objects */ 416e5c31af7Sopenharmony_ci initTest(); 417e5c31af7Sopenharmony_ci 418e5c31af7Sopenharmony_ci /* We only need to use one vertex per so go for it */ 419e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 420e5c31af7Sopenharmony_ci 421e5c31af7Sopenharmony_ci gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1); 422e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteriEXT() failed for GL_PATCH_VERTICES_EXT pname"); 423e5c31af7Sopenharmony_ci 424e5c31af7Sopenharmony_ci /* Iterate through all tests configured */ 425e5c31af7Sopenharmony_ci for (_tests_const_iterator test_iterator = m_tests.begin(); test_iterator != m_tests.end(); test_iterator++) 426e5c31af7Sopenharmony_ci { 427e5c31af7Sopenharmony_ci const _test_descriptor& test = *test_iterator; 428e5c31af7Sopenharmony_ci 429e5c31af7Sopenharmony_ci /* Run the iteration */ 430e5c31af7Sopenharmony_ci gl.useProgram(test.po_id); 431e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed"); 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci /* Draw the test geometry */ 434e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_TRIANGLES); 435e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback(GL_TRIANGLES) failed."); 436e5c31af7Sopenharmony_ci 437e5c31af7Sopenharmony_ci gl.drawArrays(m_glExtTokens.PATCHES, 0 /* first */, 1 /* count */); 438e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed"); 439e5c31af7Sopenharmony_ci 440e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 441e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() failed"); 442e5c31af7Sopenharmony_ci 443e5c31af7Sopenharmony_ci /* Map the BO with result data into user space */ 444e5c31af7Sopenharmony_ci const float* triangle_vertex_data = 445e5c31af7Sopenharmony_ci (const float*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* offset */ 446e5c31af7Sopenharmony_ci sizeof(float) * 3 /* vec3 */ * 3 /* points */, GL_MAP_READ_BIT); 447e5c31af7Sopenharmony_ci 448e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed"); 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ci /* Make sure the triangle data is correct. Since we cannot rely on any specific order 451e5c31af7Sopenharmony_ci * of the result vertices, raise corresponding flag for each of the expected vertices. 452e5c31af7Sopenharmony_ci */ 453e5c31af7Sopenharmony_ci const float epsilon = 1e-5f; 454e5c31af7Sopenharmony_ci bool is_zero_zero_one_present = false; 455e5c31af7Sopenharmony_ci bool is_zero_one_zero_present = false; 456e5c31af7Sopenharmony_ci bool is_one_zero_zero_present = false; 457e5c31af7Sopenharmony_ci 458e5c31af7Sopenharmony_ci for (unsigned int n_vertex = 0; n_vertex < 3 /* vertices */; ++n_vertex) 459e5c31af7Sopenharmony_ci { 460e5c31af7Sopenharmony_ci const float* triangle_ptr = triangle_vertex_data + 3 * n_vertex; 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_ci if (de::abs(triangle_ptr[0]) < epsilon && de::abs(triangle_ptr[1]) < epsilon && 463e5c31af7Sopenharmony_ci de::abs(triangle_ptr[2] - 1.0f) < epsilon) 464e5c31af7Sopenharmony_ci { 465e5c31af7Sopenharmony_ci if (!is_zero_zero_one_present) 466e5c31af7Sopenharmony_ci { 467e5c31af7Sopenharmony_ci is_zero_zero_one_present = true; 468e5c31af7Sopenharmony_ci } 469e5c31af7Sopenharmony_ci else 470e5c31af7Sopenharmony_ci { 471e5c31af7Sopenharmony_ci TCU_FAIL("(0, 0, 1) vertex outputted more than once"); 472e5c31af7Sopenharmony_ci } 473e5c31af7Sopenharmony_ci } 474e5c31af7Sopenharmony_ci else if (de::abs(triangle_ptr[0]) < epsilon && de::abs(triangle_ptr[1] - 1.0f) < epsilon && 475e5c31af7Sopenharmony_ci de::abs(triangle_ptr[2]) < epsilon) 476e5c31af7Sopenharmony_ci { 477e5c31af7Sopenharmony_ci if (!is_zero_one_zero_present) 478e5c31af7Sopenharmony_ci { 479e5c31af7Sopenharmony_ci is_zero_one_zero_present = true; 480e5c31af7Sopenharmony_ci } 481e5c31af7Sopenharmony_ci else 482e5c31af7Sopenharmony_ci { 483e5c31af7Sopenharmony_ci TCU_FAIL("(0, 1, 0) vertex outputted more than once"); 484e5c31af7Sopenharmony_ci } 485e5c31af7Sopenharmony_ci } 486e5c31af7Sopenharmony_ci else if (de::abs(triangle_ptr[0] - 1.0f) < epsilon && de::abs(triangle_ptr[1]) < epsilon && 487e5c31af7Sopenharmony_ci de::abs(triangle_ptr[2]) < epsilon) 488e5c31af7Sopenharmony_ci { 489e5c31af7Sopenharmony_ci if (!is_one_zero_zero_present) 490e5c31af7Sopenharmony_ci { 491e5c31af7Sopenharmony_ci is_one_zero_zero_present = true; 492e5c31af7Sopenharmony_ci } 493e5c31af7Sopenharmony_ci else 494e5c31af7Sopenharmony_ci { 495e5c31af7Sopenharmony_ci TCU_FAIL("(1, 0, 0) vertex outputted more than once"); 496e5c31af7Sopenharmony_ci } 497e5c31af7Sopenharmony_ci } 498e5c31af7Sopenharmony_ci else 499e5c31af7Sopenharmony_ci { 500e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected vertex" 501e5c31af7Sopenharmony_ci << " (" << triangle_vertex_data[0] << ", " << triangle_vertex_data[1] << ", " 502e5c31af7Sopenharmony_ci << triangle_vertex_data[2] << ")" 503e5c31af7Sopenharmony_ci << " encountered for a degenerate triangle." << tcu::TestLog::EndMessage; 504e5c31af7Sopenharmony_ci 505e5c31af7Sopenharmony_ci TCU_FAIL("Invalid vertex was generated by the tessellator"); 506e5c31af7Sopenharmony_ci } 507e5c31af7Sopenharmony_ci } /* for (all vertices) */ 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci /* Unmap the BO */ 510e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 511e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed"); 512e5c31af7Sopenharmony_ci } 513e5c31af7Sopenharmony_ci 514e5c31af7Sopenharmony_ci /* All done */ 515e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 516e5c31af7Sopenharmony_ci return STOP; 517e5c31af7Sopenharmony_ci} 518e5c31af7Sopenharmony_ci 519e5c31af7Sopenharmony_ci/** Constructor 520e5c31af7Sopenharmony_ci * 521e5c31af7Sopenharmony_ci * @param context Test context 522e5c31af7Sopenharmony_ci **/ 523e5c31af7Sopenharmony_ciTessellationShaderTrianglesIdenticalTriangles::TessellationShaderTrianglesIdenticalTriangles( 524e5c31af7Sopenharmony_ci Context& context, const ExtParameters& extParams) 525e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, "identical_triangles", 526e5c31af7Sopenharmony_ci "Verifies that tessellation coordinates generated by the tessellator " 527e5c31af7Sopenharmony_ci "running in triangles mode do not change if second inner or fourth " 528e5c31af7Sopenharmony_ci "outer tessellation level is changed") 529e5c31af7Sopenharmony_ci , m_vao_id(0) 530e5c31af7Sopenharmony_ci , m_utils(DE_NULL) 531e5c31af7Sopenharmony_ci{ 532e5c31af7Sopenharmony_ci /* Left blank on purpose */ 533e5c31af7Sopenharmony_ci} 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci/** Deinitializes ES objects created for the test. */ 536e5c31af7Sopenharmony_civoid TessellationShaderTrianglesIdenticalTriangles::deinit() 537e5c31af7Sopenharmony_ci{ 538e5c31af7Sopenharmony_ci /* Call base class' deinit() */ 539e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 542e5c31af7Sopenharmony_ci { 543e5c31af7Sopenharmony_ci return; 544e5c31af7Sopenharmony_ci } 545e5c31af7Sopenharmony_ci 546e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci /* Unbind vertex array object */ 549e5c31af7Sopenharmony_ci gl.bindVertexArray(0); 550e5c31af7Sopenharmony_ci 551e5c31af7Sopenharmony_ci /* Deallocate test variables */ 552e5c31af7Sopenharmony_ci if (m_vao_id != 0) 553e5c31af7Sopenharmony_ci { 554e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 555e5c31af7Sopenharmony_ci 556e5c31af7Sopenharmony_ci m_vao_id = 0; 557e5c31af7Sopenharmony_ci } 558e5c31af7Sopenharmony_ci 559e5c31af7Sopenharmony_ci /* Deinitialize utils instance */ 560e5c31af7Sopenharmony_ci if (m_utils != DE_NULL) 561e5c31af7Sopenharmony_ci { 562e5c31af7Sopenharmony_ci delete m_utils; 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ci m_utils = DE_NULL; 565e5c31af7Sopenharmony_ci } 566e5c31af7Sopenharmony_ci} 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_ci/** Initializes ES objects necessary to run the test. */ 569e5c31af7Sopenharmony_civoid TessellationShaderTrianglesIdenticalTriangles::initTest() 570e5c31af7Sopenharmony_ci{ 571e5c31af7Sopenharmony_ci /* Skip if required extensions are not supported. */ 572e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 573e5c31af7Sopenharmony_ci { 574e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED); 575e5c31af7Sopenharmony_ci } 576e5c31af7Sopenharmony_ci 577e5c31af7Sopenharmony_ci /* Initialize Utils instance */ 578e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci m_utils = new TessellationShaderUtils(gl, this); 581e5c31af7Sopenharmony_ci 582e5c31af7Sopenharmony_ci /* Initialize vertex array object */ 583e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 584e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object"); 585e5c31af7Sopenharmony_ci 586e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 587e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!"); 588e5c31af7Sopenharmony_ci 589e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_TESS_GEN_LEVEL_EXT value */ 590e5c31af7Sopenharmony_ci glw::GLint gl_max_tess_gen_level_value = 0; 591e5c31af7Sopenharmony_ci 592e5c31af7Sopenharmony_ci gl.getIntegerv(m_glExtTokens.MAX_TESS_GEN_LEVEL, &gl_max_tess_gen_level_value); 593e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_TESS_GEN_LEVEL_EXT pname"); 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci /* Initialize all test runs */ 596e5c31af7Sopenharmony_ci _tessellation_level_set_filter filter = 597e5c31af7Sopenharmony_ci (_tessellation_level_set_filter)((int)TESSELLATION_LEVEL_SET_FILTER_ALL_COMBINATIONS | 598e5c31af7Sopenharmony_ci (int)TESSELLATION_LEVEL_SET_FILTER_EXCLUDE_NEGATIVE_BASE_VALUE); 599e5c31af7Sopenharmony_ci 600e5c31af7Sopenharmony_ci _tessellation_levels_set levels_sets = TessellationShaderUtils::getTessellationLevelSetForPrimitiveMode( 601e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, gl_max_tess_gen_level_value, filter); 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_ci for (_tessellation_levels_set_const_iterator set_iterator = levels_sets.begin(); set_iterator != levels_sets.end(); 604e5c31af7Sopenharmony_ci set_iterator++) 605e5c31af7Sopenharmony_ci { 606e5c31af7Sopenharmony_ci _run run; 607e5c31af7Sopenharmony_ci const _tessellation_levels& set = *set_iterator; 608e5c31af7Sopenharmony_ci 609e5c31af7Sopenharmony_ci memcpy(run.base_inner, set.inner, sizeof(run.base_inner)); 610e5c31af7Sopenharmony_ci memcpy(run.base_outer, set.outer, sizeof(run.base_outer)); 611e5c31af7Sopenharmony_ci 612e5c31af7Sopenharmony_ci run.reference_inner[0] = run.base_inner[0]; 613e5c31af7Sopenharmony_ci run.reference_inner[1] = run.base_inner[1] * 0.25f; 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ci run.reference_outer[0] = run.base_outer[0]; 616e5c31af7Sopenharmony_ci run.reference_outer[1] = run.base_outer[1]; 617e5c31af7Sopenharmony_ci run.reference_outer[2] = run.base_outer[2]; 618e5c31af7Sopenharmony_ci run.reference_outer[3] = run.base_outer[3] * 0.25f; 619e5c31af7Sopenharmony_ci 620e5c31af7Sopenharmony_ci /* Retrieve vertex data for both passes */ 621e5c31af7Sopenharmony_ci glw::GLint n_base_vertices = 0; 622e5c31af7Sopenharmony_ci glw::GLint n_reference_vertices = 0; 623e5c31af7Sopenharmony_ci 624e5c31af7Sopenharmony_ci n_base_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator( 625e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, run.base_inner, run.base_outer, 626e5c31af7Sopenharmony_ci TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, false); 627e5c31af7Sopenharmony_ci n_reference_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator( 628e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, run.reference_inner, run.reference_outer, 629e5c31af7Sopenharmony_ci TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, false); /* is_point_mode_enabled */ 630e5c31af7Sopenharmony_ci 631e5c31af7Sopenharmony_ci if (n_base_vertices == 0) 632e5c31af7Sopenharmony_ci { 633e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No vertices were generated by tessellator for: " 634e5c31af7Sopenharmony_ci "inner tess levels:" 635e5c31af7Sopenharmony_ci "[" 636e5c31af7Sopenharmony_ci << run.base_inner[0] << ", " << run.base_inner[1] << "]" 637e5c31af7Sopenharmony_ci ", outer tess levels:" 638e5c31af7Sopenharmony_ci "[" 639e5c31af7Sopenharmony_ci << run.base_outer[0] << ", " << run.base_outer[1] << ", " << run.base_outer[2] << ", " 640e5c31af7Sopenharmony_ci << run.base_outer[3] << "]" 641e5c31af7Sopenharmony_ci ", primitive mode: triangles, vertex spacing: equal." 642e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ci TCU_FAIL("Zero vertices were generated by tessellator for base test pass"); 645e5c31af7Sopenharmony_ci } 646e5c31af7Sopenharmony_ci 647e5c31af7Sopenharmony_ci if (n_reference_vertices == 0) 648e5c31af7Sopenharmony_ci { 649e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No vertices were generated by tessellator for: " 650e5c31af7Sopenharmony_ci "inner tess levels:" 651e5c31af7Sopenharmony_ci "[" 652e5c31af7Sopenharmony_ci << run.reference_inner[0] << ", " << run.reference_inner[1] << "]" 653e5c31af7Sopenharmony_ci ", outer tess levels:" 654e5c31af7Sopenharmony_ci "[" 655e5c31af7Sopenharmony_ci << run.reference_outer[0] << ", " << run.reference_outer[1] << ", " 656e5c31af7Sopenharmony_ci << run.reference_outer[2] << ", " << run.reference_outer[3] 657e5c31af7Sopenharmony_ci << "]" 658e5c31af7Sopenharmony_ci ", primitive mode: triangles, vertex spacing: equal." 659e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 660e5c31af7Sopenharmony_ci 661e5c31af7Sopenharmony_ci TCU_FAIL("Zero vertices were generated by tessellator for reference test pass"); 662e5c31af7Sopenharmony_ci } 663e5c31af7Sopenharmony_ci 664e5c31af7Sopenharmony_ci if (n_base_vertices != n_reference_vertices) 665e5c31af7Sopenharmony_ci { 666e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Amount of vertices generated by the tessellator differs" 667e5c31af7Sopenharmony_ci " for the following inner/outer configs: " 668e5c31af7Sopenharmony_ci "inner tess levels:" 669e5c31af7Sopenharmony_ci "[" 670e5c31af7Sopenharmony_ci << run.base_inner[0] << ", " << run.base_inner[1] << "]" 671e5c31af7Sopenharmony_ci ", outer tess levels:" 672e5c31af7Sopenharmony_ci "[" 673e5c31af7Sopenharmony_ci << run.base_outer[0] << ", " << run.base_outer[1] << ", " << run.base_outer[2] << ", " 674e5c31af7Sopenharmony_ci << run.base_outer[3] << "]" 675e5c31af7Sopenharmony_ci " and inner tess levels:" 676e5c31af7Sopenharmony_ci "[" 677e5c31af7Sopenharmony_ci << run.reference_inner[0] << ", " << run.reference_inner[1] << "]" 678e5c31af7Sopenharmony_ci ", outer tess levels:" 679e5c31af7Sopenharmony_ci "[" 680e5c31af7Sopenharmony_ci << run.reference_outer[0] << ", " << run.reference_outer[1] << ", " 681e5c31af7Sopenharmony_ci << run.reference_outer[2] << ", " << run.reference_outer[3] 682e5c31af7Sopenharmony_ci << "]" 683e5c31af7Sopenharmony_ci ", primitive mode: triangles, vertex spacing: equal." 684e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci TCU_FAIL("Amount of vertices generated by tessellator differs between base and references passes"); 687e5c31af7Sopenharmony_ci } 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_ci run.n_vertices = n_base_vertices; 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci run.base_data = m_utils->getDataGeneratedByTessellator( 692e5c31af7Sopenharmony_ci run.base_inner, false, /* is_point_mode_enabled */ 693e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, TESSELLATION_SHADER_VERTEX_ORDERING_CCW, 694e5c31af7Sopenharmony_ci TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, run.base_outer); 695e5c31af7Sopenharmony_ci run.reference_data = m_utils->getDataGeneratedByTessellator( 696e5c31af7Sopenharmony_ci run.reference_inner, false, /* is_point_mode_enabled */ 697e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, TESSELLATION_SHADER_VERTEX_ORDERING_CCW, 698e5c31af7Sopenharmony_ci TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, run.reference_outer); 699e5c31af7Sopenharmony_ci 700e5c31af7Sopenharmony_ci /* Store the run data */ 701e5c31af7Sopenharmony_ci m_runs.push_back(run); 702e5c31af7Sopenharmony_ci } /* for (all sets) */ 703e5c31af7Sopenharmony_ci} 704e5c31af7Sopenharmony_ci 705e5c31af7Sopenharmony_ci/** Executes the test. 706e5c31af7Sopenharmony_ci * 707e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 708e5c31af7Sopenharmony_ci * 709e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 710e5c31af7Sopenharmony_ci * 711e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again. 712e5c31af7Sopenharmony_ci **/ 713e5c31af7Sopenharmony_citcu::TestNode::IterateResult TessellationShaderTrianglesIdenticalTriangles::iterate(void) 714e5c31af7Sopenharmony_ci{ 715e5c31af7Sopenharmony_ci /* Do not execute if required extensions are not supported. */ 716e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 717e5c31af7Sopenharmony_ci { 718e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED); 719e5c31af7Sopenharmony_ci } 720e5c31af7Sopenharmony_ci 721e5c31af7Sopenharmony_ci /* Initialize the test */ 722e5c31af7Sopenharmony_ci initTest(); 723e5c31af7Sopenharmony_ci 724e5c31af7Sopenharmony_ci /* Iterate through all runs */ 725e5c31af7Sopenharmony_ci 726e5c31af7Sopenharmony_ci for (_runs_const_iterator run_iterator = m_runs.begin(); run_iterator != m_runs.end(); run_iterator++) 727e5c31af7Sopenharmony_ci { 728e5c31af7Sopenharmony_ci const _run& run = *run_iterator; 729e5c31af7Sopenharmony_ci 730e5c31af7Sopenharmony_ci /* Make sure the vertex data generated for two passes matches */ 731e5c31af7Sopenharmony_ci const glw::GLint n_triangles = run.n_vertices / 3 /* vertices per triangle */; 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_ci for (int n_triangle = 0; n_triangle < n_triangles; ++n_triangle) 734e5c31af7Sopenharmony_ci { 735e5c31af7Sopenharmony_ci const float* triangle_a = (const float*)(&run.base_data[0]) + 736e5c31af7Sopenharmony_ci n_triangle * 3 /* vertices */ 737e5c31af7Sopenharmony_ci * 3; /* components */ 738e5c31af7Sopenharmony_ci const float* triangle_b = (const float*)(&run.reference_data[0]) + 739e5c31af7Sopenharmony_ci n_triangle * 3 /* vertices */ 740e5c31af7Sopenharmony_ci * 3; /* components */ 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci if (!TessellationShaderUtils::isTriangleDefined(triangle_a, triangle_b)) 743e5c31af7Sopenharmony_ci { 744e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 745e5c31af7Sopenharmony_ci << "The following triangle, generated in the first pass, was not " 746e5c31af7Sopenharmony_ci "generated in the other. " 747e5c31af7Sopenharmony_ci "First pass' configuration: inner tess levels:" 748e5c31af7Sopenharmony_ci "[" 749e5c31af7Sopenharmony_ci << run.base_inner[0] << ", " << run.base_inner[1] << "]" 750e5c31af7Sopenharmony_ci ", outer tess levels:" 751e5c31af7Sopenharmony_ci "[" 752e5c31af7Sopenharmony_ci << run.base_outer[0] << ", " << run.base_outer[1] << ", " << run.base_outer[2] 753e5c31af7Sopenharmony_ci << ", " << run.base_outer[3] << "]" 754e5c31af7Sopenharmony_ci "; second pass' configuration: inner tess levels:" 755e5c31af7Sopenharmony_ci "[" 756e5c31af7Sopenharmony_ci << run.reference_inner[0] << ", " << run.reference_inner[1] << "]" 757e5c31af7Sopenharmony_ci ", outer tess levels:" 758e5c31af7Sopenharmony_ci "[" 759e5c31af7Sopenharmony_ci << run.reference_outer[0] << ", " << run.reference_outer[1] << ", " 760e5c31af7Sopenharmony_ci << run.reference_outer[2] << ", " << run.reference_outer[3] 761e5c31af7Sopenharmony_ci << "]" 762e5c31af7Sopenharmony_ci ", primitive mode: triangles, vertex spacing: equal." 763e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_ci TCU_FAIL("A triangle from base vertex data set was not found in reference vertex data set."); 766e5c31af7Sopenharmony_ci } 767e5c31af7Sopenharmony_ci } /* for (all vertices) */ 768e5c31af7Sopenharmony_ci } /* for (all runs) */ 769e5c31af7Sopenharmony_ci 770e5c31af7Sopenharmony_ci /* All done */ 771e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 772e5c31af7Sopenharmony_ci return STOP; 773e5c31af7Sopenharmony_ci} 774e5c31af7Sopenharmony_ci 775e5c31af7Sopenharmony_ci/** Constructor 776e5c31af7Sopenharmony_ci * 777e5c31af7Sopenharmony_ci * @param context Test context 778e5c31af7Sopenharmony_ci **/ 779e5c31af7Sopenharmony_ciTessellationShaderTrianglesInnerTessellationLevelRounding::TessellationShaderTrianglesInnerTessellationLevelRounding( 780e5c31af7Sopenharmony_ci Context& context, const ExtParameters& extParams) 781e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, "inner_tessellation_level_rounding", 782e5c31af7Sopenharmony_ci "Verifies that inner tessellation level is rounded to 1 or 2," 783e5c31af7Sopenharmony_ci " when the tessellator is run in triangles primitive mode and " 784e5c31af7Sopenharmony_ci "inner tessellation level is set to 1 and any of the outer " 785e5c31af7Sopenharmony_ci "tessellation levels is greater than one.") 786e5c31af7Sopenharmony_ci , m_vao_id(0) 787e5c31af7Sopenharmony_ci , m_utils(DE_NULL) 788e5c31af7Sopenharmony_ci{ 789e5c31af7Sopenharmony_ci /* Left blank on purpose */ 790e5c31af7Sopenharmony_ci} 791e5c31af7Sopenharmony_ci 792e5c31af7Sopenharmony_ci/** Deinitializes ES objects created for the test. */ 793e5c31af7Sopenharmony_civoid TessellationShaderTrianglesInnerTessellationLevelRounding::deinit() 794e5c31af7Sopenharmony_ci{ 795e5c31af7Sopenharmony_ci /* Call base class' deinit() */ 796e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 799e5c31af7Sopenharmony_ci { 800e5c31af7Sopenharmony_ci return; 801e5c31af7Sopenharmony_ci } 802e5c31af7Sopenharmony_ci 803e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 804e5c31af7Sopenharmony_ci 805e5c31af7Sopenharmony_ci /* Unbind vertex array object */ 806e5c31af7Sopenharmony_ci gl.bindVertexArray(0); 807e5c31af7Sopenharmony_ci 808e5c31af7Sopenharmony_ci /* Deallocate test variables */ 809e5c31af7Sopenharmony_ci if (m_vao_id != 0) 810e5c31af7Sopenharmony_ci { 811e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 812e5c31af7Sopenharmony_ci 813e5c31af7Sopenharmony_ci m_vao_id = 0; 814e5c31af7Sopenharmony_ci } 815e5c31af7Sopenharmony_ci 816e5c31af7Sopenharmony_ci /* Deinitialize utils instance */ 817e5c31af7Sopenharmony_ci if (m_utils != DE_NULL) 818e5c31af7Sopenharmony_ci { 819e5c31af7Sopenharmony_ci delete m_utils; 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ci m_utils = DE_NULL; 822e5c31af7Sopenharmony_ci } 823e5c31af7Sopenharmony_ci} 824e5c31af7Sopenharmony_ci 825e5c31af7Sopenharmony_ci/** Executes the test. 826e5c31af7Sopenharmony_ci * 827e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 828e5c31af7Sopenharmony_ci * 829e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 830e5c31af7Sopenharmony_ci * 831e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again. 832e5c31af7Sopenharmony_ci **/ 833e5c31af7Sopenharmony_citcu::TestNode::IterateResult TessellationShaderTrianglesInnerTessellationLevelRounding::iterate(void) 834e5c31af7Sopenharmony_ci{ 835e5c31af7Sopenharmony_ci /* Do not execute if required extensions are not supported. */ 836e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 837e5c31af7Sopenharmony_ci { 838e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED); 839e5c31af7Sopenharmony_ci } 840e5c31af7Sopenharmony_ci 841e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 842e5c31af7Sopenharmony_ci 843e5c31af7Sopenharmony_ci /* Initialize vertex array object */ 844e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 845e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object"); 846e5c31af7Sopenharmony_ci 847e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 848e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!"); 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_ci /* Initialize and run test iterations. In later part, we will verify the generated data. */ 851e5c31af7Sopenharmony_ci runTestIterations(); 852e5c31af7Sopenharmony_ci 853e5c31af7Sopenharmony_ci /* Iterate through all runs */ 854e5c31af7Sopenharmony_ci 855e5c31af7Sopenharmony_ci for (_runs_const_iterator run_iterator = m_runs.begin(); run_iterator != m_runs.end(); run_iterator++) 856e5c31af7Sopenharmony_ci { 857e5c31af7Sopenharmony_ci const _run& run = *run_iterator; 858e5c31af7Sopenharmony_ci 859e5c31af7Sopenharmony_ci if (run.vertex_spacing == TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD && 860e5c31af7Sopenharmony_ci de::abs(run.set1_inner[0] - run.set2_inner[0]) > 1e-5f && 861e5c31af7Sopenharmony_ci de::min(run.set1_inner[0], run.set2_inner[0]) >= 1.0f) 862e5c31af7Sopenharmony_ci { 863e5c31af7Sopenharmony_ci /* In fractional_odd_spacing mode with inner level <f> >= 1.0f, the clamped 864e5c31af7Sopenharmony_ci and rounded integer level <n> is at least 3. 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci These results in inner subdivision into at least <n>-2=1 segment and 867e5c31af7Sopenharmony_ci two additional, typically shorter segments. 868e5c31af7Sopenharmony_ci 869e5c31af7Sopenharmony_ci The length of these two additional segments relative to the others will 870e5c31af7Sopenharmony_ci decrease monotonically with the value of <n>-<f>, so if different <f> levels 871e5c31af7Sopenharmony_ci were used, we cannot proceed with matching the exact vertex data. */ 872e5c31af7Sopenharmony_ci 873e5c31af7Sopenharmony_ci continue; 874e5c31af7Sopenharmony_ci } 875e5c31af7Sopenharmony_ci 876e5c31af7Sopenharmony_ci /* Make sure the vertex data generated for two passes matches */ 877e5c31af7Sopenharmony_ci const glw::GLint n_triangles = run.n_vertices / 3 /* vertices per triangle */; 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci for (int n_triangle = 0; n_triangle < n_triangles; ++n_triangle) 880e5c31af7Sopenharmony_ci { 881e5c31af7Sopenharmony_ci const float* triangle_a = (const float*)(&run.set1_data[0]) + 882e5c31af7Sopenharmony_ci n_triangle * 3 /* vertices */ 883e5c31af7Sopenharmony_ci * 3; /* components */ 884e5c31af7Sopenharmony_ci const float* triangle_b = (const float*)(&run.set2_data[0]) + 885e5c31af7Sopenharmony_ci n_triangle * 3 /* vertices */ 886e5c31af7Sopenharmony_ci * 3; /* components */ 887e5c31af7Sopenharmony_ci 888e5c31af7Sopenharmony_ci if (!TessellationShaderUtils::isTriangleDefined(triangle_a, triangle_b)) 889e5c31af7Sopenharmony_ci { 890e5c31af7Sopenharmony_ci std::string vs_mode_string = 891e5c31af7Sopenharmony_ci TessellationShaderUtils::getESTokenForVertexSpacingMode(run.vertex_spacing); 892e5c31af7Sopenharmony_ci 893e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 894e5c31af7Sopenharmony_ci << "The following triangle, generated in the first pass, was not " 895e5c31af7Sopenharmony_ci "generated in the second one. " 896e5c31af7Sopenharmony_ci "First pass' configuration: inner tess levels:" 897e5c31af7Sopenharmony_ci "[" 898e5c31af7Sopenharmony_ci << run.set1_inner[0] << ", " << run.set1_inner[1] << "]" 899e5c31af7Sopenharmony_ci ", outer tess levels:" 900e5c31af7Sopenharmony_ci "[" 901e5c31af7Sopenharmony_ci << run.set1_outer[0] << ", " << run.set1_outer[1] << ", " << run.set1_outer[2] 902e5c31af7Sopenharmony_ci << ", " << run.set1_outer[3] << "]" 903e5c31af7Sopenharmony_ci "; second pass' configuration: inner tess levels:" 904e5c31af7Sopenharmony_ci "[" 905e5c31af7Sopenharmony_ci << run.set2_inner[0] << ", " << run.set2_inner[1] << "]" 906e5c31af7Sopenharmony_ci ", outer tess levels:" 907e5c31af7Sopenharmony_ci "[" 908e5c31af7Sopenharmony_ci << run.set2_outer[0] << ", " << run.set2_outer[1] << ", " << run.set2_outer[2] 909e5c31af7Sopenharmony_ci << ", " << run.set2_outer[3] << "]" 910e5c31af7Sopenharmony_ci ", primitive mode: triangles, vertex spacing: " 911e5c31af7Sopenharmony_ci << vs_mode_string << tcu::TestLog::EndMessage; 912e5c31af7Sopenharmony_ci 913e5c31af7Sopenharmony_ci TCU_FAIL("A triangle from first pass' data set was not found in second pass' data set."); 914e5c31af7Sopenharmony_ci } 915e5c31af7Sopenharmony_ci } /* for (all vertices) */ 916e5c31af7Sopenharmony_ci } /* for (all runs) */ 917e5c31af7Sopenharmony_ci 918e5c31af7Sopenharmony_ci /* All done */ 919e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 920e5c31af7Sopenharmony_ci return STOP; 921e5c31af7Sopenharmony_ci} 922e5c31af7Sopenharmony_ci 923e5c31af7Sopenharmony_ci/** Runs all test iterations needed to generate data for later verification. */ 924e5c31af7Sopenharmony_civoid TessellationShaderTrianglesInnerTessellationLevelRounding::runTestIterations() 925e5c31af7Sopenharmony_ci{ 926e5c31af7Sopenharmony_ci /* Skip if required extensions are not supported. */ 927e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 928e5c31af7Sopenharmony_ci { 929e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED); 930e5c31af7Sopenharmony_ci } 931e5c31af7Sopenharmony_ci 932e5c31af7Sopenharmony_ci /* Initialize Utils instance */ 933e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 934e5c31af7Sopenharmony_ci 935e5c31af7Sopenharmony_ci m_utils = new TessellationShaderUtils(gl, this); 936e5c31af7Sopenharmony_ci 937e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_TESS_GEN_LEVEL_EXT value */ 938e5c31af7Sopenharmony_ci glw::GLint gl_max_tess_gen_level_value = 0; 939e5c31af7Sopenharmony_ci 940e5c31af7Sopenharmony_ci gl.getIntegerv(m_glExtTokens.MAX_TESS_GEN_LEVEL, &gl_max_tess_gen_level_value); 941e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_TESS_GEN_LEVEL_EXT pname"); 942e5c31af7Sopenharmony_ci 943e5c31af7Sopenharmony_ci /* Initialize all test runs */ 944e5c31af7Sopenharmony_ci const glw::GLint tess_levels[] = { 2, gl_max_tess_gen_level_value / 2, gl_max_tess_gen_level_value }; 945e5c31af7Sopenharmony_ci const unsigned int n_tess_levels = sizeof(tess_levels) / sizeof(tess_levels[0]); 946e5c31af7Sopenharmony_ci 947e5c31af7Sopenharmony_ci const _tessellation_shader_vertex_spacing vs_modes[] = { TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, 948e5c31af7Sopenharmony_ci TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_EVEN, 949e5c31af7Sopenharmony_ci TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD }; 950e5c31af7Sopenharmony_ci const unsigned int n_vs_modes = sizeof(vs_modes) / sizeof(vs_modes[0]); 951e5c31af7Sopenharmony_ci 952e5c31af7Sopenharmony_ci for (unsigned int n_vs_mode = 0; n_vs_mode < n_vs_modes; ++n_vs_mode) 953e5c31af7Sopenharmony_ci { 954e5c31af7Sopenharmony_ci _tessellation_shader_vertex_spacing vs_mode = vs_modes[n_vs_mode]; 955e5c31af7Sopenharmony_ci 956e5c31af7Sopenharmony_ci for (unsigned int n_tess_level = 0; n_tess_level < n_tess_levels; ++n_tess_level) 957e5c31af7Sopenharmony_ci { 958e5c31af7Sopenharmony_ci /* Set up the run descriptor */ 959e5c31af7Sopenharmony_ci glw::GLint tess_level = tess_levels[n_tess_level]; 960e5c31af7Sopenharmony_ci _run run; 961e5c31af7Sopenharmony_ci 962e5c31af7Sopenharmony_ci run.set1_inner[0] = 1.0f; 963e5c31af7Sopenharmony_ci run.set1_inner[1] = 0.0f; 964e5c31af7Sopenharmony_ci run.set2_inner[1] = 0.0f; 965e5c31af7Sopenharmony_ci 966e5c31af7Sopenharmony_ci TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(vs_mode, 1.5f, gl_max_tess_gen_level_value, 967e5c31af7Sopenharmony_ci DE_NULL, /* out_clamped */ 968e5c31af7Sopenharmony_ci run.set2_inner); 969e5c31af7Sopenharmony_ci run.set1_outer[0] = (glw::GLfloat)tess_level; 970e5c31af7Sopenharmony_ci run.set2_outer[0] = (glw::GLfloat)tess_level; 971e5c31af7Sopenharmony_ci run.set1_outer[1] = (glw::GLfloat)tess_level; 972e5c31af7Sopenharmony_ci run.set2_outer[1] = (glw::GLfloat)tess_level; 973e5c31af7Sopenharmony_ci run.set1_outer[2] = (glw::GLfloat)tess_level; 974e5c31af7Sopenharmony_ci run.set2_outer[2] = (glw::GLfloat)tess_level; 975e5c31af7Sopenharmony_ci run.set1_outer[3] = (glw::GLfloat)tess_level; 976e5c31af7Sopenharmony_ci run.set2_outer[3] = (glw::GLfloat)tess_level; 977e5c31af7Sopenharmony_ci 978e5c31af7Sopenharmony_ci run.vertex_spacing = vs_mode; 979e5c31af7Sopenharmony_ci 980e5c31af7Sopenharmony_ci /* Retrieve vertex data for both passes */ 981e5c31af7Sopenharmony_ci glw::GLint n_set1_vertices = 0; 982e5c31af7Sopenharmony_ci glw::GLint n_set2_vertices = 0; 983e5c31af7Sopenharmony_ci 984e5c31af7Sopenharmony_ci n_set1_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator( 985e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, run.set1_inner, run.set1_outer, run.vertex_spacing, 986e5c31af7Sopenharmony_ci false); /* is_point_mode_enabled */ 987e5c31af7Sopenharmony_ci n_set2_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator( 988e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, run.set2_inner, run.set2_outer, run.vertex_spacing, 989e5c31af7Sopenharmony_ci false); /* is_point_mode_enabled */ 990e5c31af7Sopenharmony_ci 991e5c31af7Sopenharmony_ci if (n_set1_vertices == 0) 992e5c31af7Sopenharmony_ci { 993e5c31af7Sopenharmony_ci std::string vs_mode_string = TessellationShaderUtils::getESTokenForVertexSpacingMode(vs_mode); 994e5c31af7Sopenharmony_ci 995e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No vertices were generated by tessellator for: " 996e5c31af7Sopenharmony_ci "inner tess levels:" 997e5c31af7Sopenharmony_ci "[" 998e5c31af7Sopenharmony_ci << run.set1_inner[0] << ", " << run.set1_inner[1] << "]" 999e5c31af7Sopenharmony_ci ", outer tess levels:" 1000e5c31af7Sopenharmony_ci "[" 1001e5c31af7Sopenharmony_ci << run.set1_outer[0] << ", " << run.set1_outer[1] << ", " << run.set1_outer[2] 1002e5c31af7Sopenharmony_ci << ", " << run.set1_outer[3] << "]" 1003e5c31af7Sopenharmony_ci ", primitive mode: triangles, " 1004e5c31af7Sopenharmony_ci "vertex spacing: " 1005e5c31af7Sopenharmony_ci << vs_mode_string << tcu::TestLog::EndMessage; 1006e5c31af7Sopenharmony_ci 1007e5c31af7Sopenharmony_ci TCU_FAIL("Zero vertices were generated by tessellator for first test pass"); 1008e5c31af7Sopenharmony_ci } 1009e5c31af7Sopenharmony_ci 1010e5c31af7Sopenharmony_ci if (n_set2_vertices == 0) 1011e5c31af7Sopenharmony_ci { 1012e5c31af7Sopenharmony_ci std::string vs_mode_string = TessellationShaderUtils::getESTokenForVertexSpacingMode(vs_mode); 1013e5c31af7Sopenharmony_ci 1014e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No vertices were generated by tessellator for: " 1015e5c31af7Sopenharmony_ci "inner tess levels:" 1016e5c31af7Sopenharmony_ci "[" 1017e5c31af7Sopenharmony_ci << run.set2_inner[0] << ", " << run.set2_inner[1] << "]" 1018e5c31af7Sopenharmony_ci ", outer tess levels:" 1019e5c31af7Sopenharmony_ci "[" 1020e5c31af7Sopenharmony_ci << run.set2_outer[0] << ", " << run.set2_outer[1] << ", " << run.set2_outer[2] 1021e5c31af7Sopenharmony_ci << ", " << run.set2_outer[3] << "]" 1022e5c31af7Sopenharmony_ci ", primitive mode: triangles, " 1023e5c31af7Sopenharmony_ci "vertex spacing: " 1024e5c31af7Sopenharmony_ci << vs_mode_string << tcu::TestLog::EndMessage; 1025e5c31af7Sopenharmony_ci 1026e5c31af7Sopenharmony_ci TCU_FAIL("Zero vertices were generated by tessellator for second test pass"); 1027e5c31af7Sopenharmony_ci } 1028e5c31af7Sopenharmony_ci 1029e5c31af7Sopenharmony_ci if (n_set1_vertices != n_set2_vertices) 1030e5c31af7Sopenharmony_ci { 1031e5c31af7Sopenharmony_ci std::string vs_mode_string = TessellationShaderUtils::getESTokenForVertexSpacingMode(vs_mode); 1032e5c31af7Sopenharmony_ci 1033e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Amount of vertices generated by the tessellator differs" 1034e5c31af7Sopenharmony_ci " for the following inner/outer configs: " 1035e5c31af7Sopenharmony_ci "inner tess levels:" 1036e5c31af7Sopenharmony_ci "[" 1037e5c31af7Sopenharmony_ci << run.set1_inner[0] << ", " << run.set1_inner[1] << "]" 1038e5c31af7Sopenharmony_ci ", outer tess levels:" 1039e5c31af7Sopenharmony_ci "[" 1040e5c31af7Sopenharmony_ci << run.set1_outer[0] << ", " << run.set1_outer[1] << ", " << run.set1_outer[2] 1041e5c31af7Sopenharmony_ci << ", " << run.set1_outer[3] << "]" 1042e5c31af7Sopenharmony_ci " and inner tess levels:" 1043e5c31af7Sopenharmony_ci "[" 1044e5c31af7Sopenharmony_ci << run.set2_inner[0] << ", " << run.set2_inner[1] << "]" 1045e5c31af7Sopenharmony_ci ", outer tess levels:" 1046e5c31af7Sopenharmony_ci "[" 1047e5c31af7Sopenharmony_ci << run.set2_outer[0] << ", " << run.set2_outer[1] << ", " << run.set2_outer[2] 1048e5c31af7Sopenharmony_ci << ", " << run.set2_outer[3] << "]" 1049e5c31af7Sopenharmony_ci ", primitive mode: triangles, vertex spacing: " 1050e5c31af7Sopenharmony_ci << vs_mode_string << tcu::TestLog::EndMessage; 1051e5c31af7Sopenharmony_ci 1052e5c31af7Sopenharmony_ci TCU_FAIL("Amount of vertices generated by tessellator differs between base and references passes"); 1053e5c31af7Sopenharmony_ci } 1054e5c31af7Sopenharmony_ci 1055e5c31af7Sopenharmony_ci run.n_vertices = n_set1_vertices; 1056e5c31af7Sopenharmony_ci 1057e5c31af7Sopenharmony_ci run.set1_data = m_utils->getDataGeneratedByTessellator(run.set1_inner, false, /* is_point_mode_enabled */ 1058e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, 1059e5c31af7Sopenharmony_ci TESSELLATION_SHADER_VERTEX_ORDERING_CCW, 1060e5c31af7Sopenharmony_ci run.vertex_spacing, run.set1_outer); 1061e5c31af7Sopenharmony_ci run.set2_data = m_utils->getDataGeneratedByTessellator(run.set2_inner, false, /* is_point_mode_enabled */ 1062e5c31af7Sopenharmony_ci TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, 1063e5c31af7Sopenharmony_ci TESSELLATION_SHADER_VERTEX_ORDERING_CCW, 1064e5c31af7Sopenharmony_ci run.vertex_spacing, run.set2_outer); 1065e5c31af7Sopenharmony_ci 1066e5c31af7Sopenharmony_ci /* Store the run data */ 1067e5c31af7Sopenharmony_ci m_runs.push_back(run); 1068e5c31af7Sopenharmony_ci } /* for (all sets) */ 1069e5c31af7Sopenharmony_ci } /* for (all vertex spacing modes) */ 1070e5c31af7Sopenharmony_ci} 1071e5c31af7Sopenharmony_ci 1072e5c31af7Sopenharmony_ci} /* namespace glcts */ 1073