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 "esextcTessellationShaderProperties.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#include <cmath> 31e5c31af7Sopenharmony_ci#include <cstring> 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_cinamespace glcts 34e5c31af7Sopenharmony_ci{ 35e5c31af7Sopenharmony_ci/** Constructor 36e5c31af7Sopenharmony_ci * 37e5c31af7Sopenharmony_ci * @param context Test context 38e5c31af7Sopenharmony_ci **/ 39e5c31af7Sopenharmony_ciTessellationShaderPropertiesDefaultContextWideValues::TessellationShaderPropertiesDefaultContextWideValues( 40e5c31af7Sopenharmony_ci Context& context, const ExtParameters& extParams) 41e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, "default_values_of_context_wide_properties", 42e5c31af7Sopenharmony_ci "Verifies default values of context-wide tessellation stage properties") 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_ci /* Left blank on purpose */ 45e5c31af7Sopenharmony_ci} 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ci/** Executes the test. 48e5c31af7Sopenharmony_ci * 49e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 50e5c31af7Sopenharmony_ci * 51e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 52e5c31af7Sopenharmony_ci * 53e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again. 54e5c31af7Sopenharmony_ci **/ 55e5c31af7Sopenharmony_citcu::TestNode::IterateResult TessellationShaderPropertiesDefaultContextWideValues::iterate(void) 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_ci /* Do not execute if required extensions are not supported. */ 58e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 59e5c31af7Sopenharmony_ci { 60e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED); 61e5c31af7Sopenharmony_ci } 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ci /* Iterate through all context-wide properties and compare expected values 64e5c31af7Sopenharmony_ci * against the reference ones 65e5c31af7Sopenharmony_ci */ 66e5c31af7Sopenharmony_ci const float epsilon = (float)1e-5; 67e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ci const glw::GLint property_value_data[] = { /* pname */ /* n components */ /* default value */ 70e5c31af7Sopenharmony_ci static_cast<glw::GLint>(m_glExtTokens.PATCH_VERTICES), 1, 3, 71e5c31af7Sopenharmony_ci /* The following values are only applicable to Desktop OpenGL. */ 72e5c31af7Sopenharmony_ci GL_PATCH_DEFAULT_OUTER_LEVEL, 4, 1, GL_PATCH_DEFAULT_INNER_LEVEL, 2, 1 }; 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_ci const unsigned int n_properties = (glu::isContextTypeES(m_context.getRenderContext().getType())) ? 1 : 3; 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ci for (unsigned int n_property = 0; n_property < n_properties; ++n_property) 77e5c31af7Sopenharmony_ci { 78e5c31af7Sopenharmony_ci glw::GLboolean bool_value[4] = { GL_FALSE }; 79e5c31af7Sopenharmony_ci glw::GLfloat float_value[4] = { 0.0f }; 80e5c31af7Sopenharmony_ci glw::GLint int_value[4] = { 0 }; 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ci glw::GLenum pname = property_value_data[n_property * 3 + 0]; 83e5c31af7Sopenharmony_ci glw::GLint n_components = property_value_data[n_property * 3 + 1]; 84e5c31af7Sopenharmony_ci glw::GLint expected_value = property_value_data[n_property * 3 + 2]; 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ci /* Call all relevant getters */ 87e5c31af7Sopenharmony_ci gl.getBooleanv(pname, bool_value); 88e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv() failed."); 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ci gl.getFloatv(pname, float_value); 91e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() failed."); 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci gl.getIntegerv(pname, int_value); 94e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed."); 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ci /* Compare retrieved vector value components against expected value */ 97e5c31af7Sopenharmony_ci glw::GLboolean expected_bool_value[4] = { 98e5c31af7Sopenharmony_ci (expected_value != 0) ? (glw::GLboolean)GL_TRUE : (glw::GLboolean)GL_FALSE, 99e5c31af7Sopenharmony_ci (expected_value != 0) ? (glw::GLboolean)GL_TRUE : (glw::GLboolean)GL_FALSE, 100e5c31af7Sopenharmony_ci (expected_value != 0) ? (glw::GLboolean)GL_TRUE : (glw::GLboolean)GL_FALSE, 101e5c31af7Sopenharmony_ci (expected_value != 0) ? (glw::GLboolean)GL_TRUE : (glw::GLboolean)GL_FALSE 102e5c31af7Sopenharmony_ci }; 103e5c31af7Sopenharmony_ci glw::GLint expected_int_value[4] = { expected_value, expected_value, expected_value, expected_value }; 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_ci if (memcmp(expected_bool_value, bool_value, sizeof(bool) * n_components) != 0) 106e5c31af7Sopenharmony_ci { 107e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "glGetBooleanv() called for pname " << pname 108e5c31af7Sopenharmony_ci << " reported invalid value." << tcu::TestLog::EndMessage; 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci TCU_FAIL("Invalid value reported by glGetBooleanv()"); 111e5c31af7Sopenharmony_ci } 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci if (memcmp(expected_int_value, int_value, sizeof(int) * n_components) != 0) 114e5c31af7Sopenharmony_ci { 115e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv() called for pname " << pname 116e5c31af7Sopenharmony_ci << " reported invalid value." << tcu::TestLog::EndMessage; 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci TCU_FAIL("Invalid value reported by glGetIntegerv()"); 119e5c31af7Sopenharmony_ci } 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci if ((n_components >= 1 && de::abs(float_value[0] - (float)expected_value) > epsilon) || 122e5c31af7Sopenharmony_ci (n_components >= 2 && de::abs(float_value[1] - (float)expected_value) > epsilon) || 123e5c31af7Sopenharmony_ci (n_components >= 3 && de::abs(float_value[2] - (float)expected_value) > epsilon) || 124e5c31af7Sopenharmony_ci (n_components >= 4 && de::abs(float_value[3] - (float)expected_value) > epsilon)) 125e5c31af7Sopenharmony_ci { 126e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "glGetFloatv() called for pname " << pname 127e5c31af7Sopenharmony_ci << " reported invalid value." << tcu::TestLog::EndMessage; 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_ci TCU_FAIL("Invalid value reported by glGetFloatv()"); 130e5c31af7Sopenharmony_ci } 131e5c31af7Sopenharmony_ci } /* for (all properties) */ 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ci /* All done */ 134e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 135e5c31af7Sopenharmony_ci return STOP; 136e5c31af7Sopenharmony_ci} 137e5c31af7Sopenharmony_ci 138e5c31af7Sopenharmony_ci/** Constructor 139e5c31af7Sopenharmony_ci * 140e5c31af7Sopenharmony_ci * @param context Test context 141e5c31af7Sopenharmony_ci **/ 142e5c31af7Sopenharmony_ciTessellationShaderPropertiesProgramObject::TessellationShaderPropertiesProgramObject(Context& context, 143e5c31af7Sopenharmony_ci const ExtParameters& extParams) 144e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, "program_object_properties", 145e5c31af7Sopenharmony_ci "Verifies tessellation-specific properties of program objects are reported correctly.") 146e5c31af7Sopenharmony_ci , m_fs_id(0) 147e5c31af7Sopenharmony_ci , m_po_id(0) 148e5c31af7Sopenharmony_ci , m_tc_id(0) 149e5c31af7Sopenharmony_ci , m_te_id(0) 150e5c31af7Sopenharmony_ci , m_vs_id(0) 151e5c31af7Sopenharmony_ci{ 152e5c31af7Sopenharmony_ci /* Left blank on purpose */ 153e5c31af7Sopenharmony_ci} 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci/** Deinitializes ES objects created for the test */ 156e5c31af7Sopenharmony_civoid TessellationShaderPropertiesProgramObject::deinit(void) 157e5c31af7Sopenharmony_ci{ 158e5c31af7Sopenharmony_ci /* Call base class' deinit() */ 159e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_ci /* Release any ES objects created */ 162e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 163e5c31af7Sopenharmony_ci 164e5c31af7Sopenharmony_ci if (m_fs_id != 0) 165e5c31af7Sopenharmony_ci { 166e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_ci m_fs_id = 0; 169e5c31af7Sopenharmony_ci } 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci if (m_po_id != 0) 172e5c31af7Sopenharmony_ci { 173e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ci m_po_id = 0; 176e5c31af7Sopenharmony_ci } 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci if (m_tc_id != 0) 179e5c31af7Sopenharmony_ci { 180e5c31af7Sopenharmony_ci gl.deleteShader(m_tc_id); 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci m_tc_id = 0; 183e5c31af7Sopenharmony_ci } 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci if (m_te_id != 0) 186e5c31af7Sopenharmony_ci { 187e5c31af7Sopenharmony_ci gl.deleteShader(m_te_id); 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci m_te_id = 0; 190e5c31af7Sopenharmony_ci } 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci if (m_vs_id != 0) 193e5c31af7Sopenharmony_ci { 194e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci m_vs_id = 0; 197e5c31af7Sopenharmony_ci } 198e5c31af7Sopenharmony_ci} 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci/** Initializes ES objects necessary to execute the test */ 201e5c31af7Sopenharmony_civoid TessellationShaderPropertiesProgramObject::initTest(void) 202e5c31af7Sopenharmony_ci{ 203e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci /* Do not execute if required extension is not supported */ 206e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 207e5c31af7Sopenharmony_ci { 208e5c31af7Sopenharmony_ci return; 209e5c31af7Sopenharmony_ci } 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ci /* Generate all objects */ 212e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 213e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() failed"); 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 216e5c31af7Sopenharmony_ci m_tc_id = gl.createShader(m_glExtTokens.TESS_CONTROL_SHADER); 217e5c31af7Sopenharmony_ci m_te_id = gl.createShader(m_glExtTokens.TESS_EVALUATION_SHADER); 218e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 219e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() failed"); 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci /* Attach the shader to the program object */ 222e5c31af7Sopenharmony_ci gl.attachShader(m_po_id, m_fs_id); 223e5c31af7Sopenharmony_ci gl.attachShader(m_po_id, m_tc_id); 224e5c31af7Sopenharmony_ci gl.attachShader(m_po_id, m_te_id); 225e5c31af7Sopenharmony_ci gl.attachShader(m_po_id, m_vs_id); 226e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed"); 227e5c31af7Sopenharmony_ci 228e5c31af7Sopenharmony_ci /* Since this test does not care much about fragment & vertex shaders, set 229e5c31af7Sopenharmony_ci * their bodies and compile these shaders now */ 230e5c31af7Sopenharmony_ci const char* fs_body = "${VERSION}\n" 231e5c31af7Sopenharmony_ci "\n" 232e5c31af7Sopenharmony_ci "void main()\n" 233e5c31af7Sopenharmony_ci "{\n" 234e5c31af7Sopenharmony_ci "}\n"; 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci const char* vs_body = "${VERSION}\n" 237e5c31af7Sopenharmony_ci "\n" 238e5c31af7Sopenharmony_ci "void main()\n" 239e5c31af7Sopenharmony_ci "{\n" 240e5c31af7Sopenharmony_ci "}\n"; 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ci glw::GLint fs_compile_status = GL_FALSE; 243e5c31af7Sopenharmony_ci glw::GLint vs_compile_status = GL_FALSE; 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ci shaderSourceSpecialized(m_fs_id, 1 /* count */, &fs_body); 246e5c31af7Sopenharmony_ci shaderSourceSpecialized(m_vs_id, 1 /* count */, &vs_body); 247e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed"); 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ci gl.compileShader(m_fs_id); 250e5c31af7Sopenharmony_ci gl.compileShader(m_vs_id); 251e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed"); 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci gl.getShaderiv(m_fs_id, GL_COMPILE_STATUS, &fs_compile_status); 254e5c31af7Sopenharmony_ci gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &vs_compile_status); 255e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed"); 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci if (fs_compile_status != GL_TRUE) 258e5c31af7Sopenharmony_ci { 259e5c31af7Sopenharmony_ci TCU_FAIL("Could not compile fragment shader"); 260e5c31af7Sopenharmony_ci } 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_ci if (vs_compile_status != GL_TRUE) 263e5c31af7Sopenharmony_ci { 264e5c31af7Sopenharmony_ci TCU_FAIL("Could not compile vertex shader"); 265e5c31af7Sopenharmony_ci } 266e5c31af7Sopenharmony_ci} 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci/** Executes the test. 269e5c31af7Sopenharmony_ci * 270e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 271e5c31af7Sopenharmony_ci * 272e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 273e5c31af7Sopenharmony_ci * 274e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again. 275e5c31af7Sopenharmony_ci **/ 276e5c31af7Sopenharmony_citcu::TestNode::IterateResult TessellationShaderPropertiesProgramObject::iterate(void) 277e5c31af7Sopenharmony_ci{ 278e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci /* Do not execute if required extensions are not supported. */ 281e5c31af7Sopenharmony_ci if (!m_is_tessellation_shader_supported) 282e5c31af7Sopenharmony_ci { 283e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED); 284e5c31af7Sopenharmony_ci } 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ci /* Initialize ES test objects */ 287e5c31af7Sopenharmony_ci initTest(); 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci /* Test 1: Default values. Values as per spec, define as little qualifiers as possible */ 290e5c31af7Sopenharmony_ci _test_descriptor test_1; 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_ci test_1.expected_control_output_vertices_value = 4; 293e5c31af7Sopenharmony_ci test_1.expected_gen_mode_value = m_glExtTokens.QUADS; 294e5c31af7Sopenharmony_ci test_1.expected_gen_point_mode_value = GL_FALSE; 295e5c31af7Sopenharmony_ci test_1.expected_gen_spacing_value = GL_EQUAL; 296e5c31af7Sopenharmony_ci test_1.expected_gen_vertex_order_value = GL_CCW; 297e5c31af7Sopenharmony_ci test_1.tc_body = "${VERSION}\n" 298e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 299e5c31af7Sopenharmony_ci "\n" 300e5c31af7Sopenharmony_ci "layout(vertices=4) out;\n" 301e5c31af7Sopenharmony_ci "\n" 302e5c31af7Sopenharmony_ci "void main()\n" 303e5c31af7Sopenharmony_ci "{\n" 304e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 305e5c31af7Sopenharmony_ci "}\n"; 306e5c31af7Sopenharmony_ci test_1.te_body = "${VERSION}\n" 307e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 308e5c31af7Sopenharmony_ci "\n" 309e5c31af7Sopenharmony_ci "layout(quads) in;\n" 310e5c31af7Sopenharmony_ci "\n" 311e5c31af7Sopenharmony_ci "void main()\n" 312e5c31af7Sopenharmony_ci "{\n" 313e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 314e5c31af7Sopenharmony_ci "}\n"; 315e5c31af7Sopenharmony_ci 316e5c31af7Sopenharmony_ci /* Test 2: 16 vertices per patch + isolines + fractional_even_spacing + cw combination */ 317e5c31af7Sopenharmony_ci _test_descriptor test_2; 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci test_2.expected_control_output_vertices_value = 16; 320e5c31af7Sopenharmony_ci test_2.expected_gen_mode_value = m_glExtTokens.ISOLINES; 321e5c31af7Sopenharmony_ci test_2.expected_gen_point_mode_value = GL_FALSE; 322e5c31af7Sopenharmony_ci test_2.expected_gen_spacing_value = m_glExtTokens.FRACTIONAL_EVEN; 323e5c31af7Sopenharmony_ci test_2.expected_gen_vertex_order_value = GL_CW; 324e5c31af7Sopenharmony_ci test_2.tc_body = "${VERSION}\n" 325e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 326e5c31af7Sopenharmony_ci "\n" 327e5c31af7Sopenharmony_ci "layout(vertices=16) out;\n" 328e5c31af7Sopenharmony_ci "\n" 329e5c31af7Sopenharmony_ci "void main()\n" 330e5c31af7Sopenharmony_ci "{\n" 331e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 332e5c31af7Sopenharmony_ci "}\n"; 333e5c31af7Sopenharmony_ci test_2.te_body = "${VERSION}\n" 334e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 335e5c31af7Sopenharmony_ci "\n" 336e5c31af7Sopenharmony_ci "layout(isolines, fractional_even_spacing, cw) in;\n" 337e5c31af7Sopenharmony_ci "\n" 338e5c31af7Sopenharmony_ci "void main()\n" 339e5c31af7Sopenharmony_ci "{\n" 340e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 341e5c31af7Sopenharmony_ci "}\n"; 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci /* Test 3: 32 vertices per patch + triangles + fractional_odd_spacing + ccw combination + point mode*/ 344e5c31af7Sopenharmony_ci _test_descriptor test_3; 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci test_3.expected_control_output_vertices_value = 32; 347e5c31af7Sopenharmony_ci test_3.expected_gen_mode_value = GL_TRIANGLES; 348e5c31af7Sopenharmony_ci test_3.expected_gen_point_mode_value = GL_TRUE; 349e5c31af7Sopenharmony_ci test_3.expected_gen_spacing_value = m_glExtTokens.FRACTIONAL_ODD; 350e5c31af7Sopenharmony_ci test_3.expected_gen_vertex_order_value = GL_CCW; 351e5c31af7Sopenharmony_ci test_3.tc_body = "${VERSION}\n" 352e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 353e5c31af7Sopenharmony_ci "\n" 354e5c31af7Sopenharmony_ci "layout(vertices=32) out;\n" 355e5c31af7Sopenharmony_ci "\n" 356e5c31af7Sopenharmony_ci "void main()\n" 357e5c31af7Sopenharmony_ci "{\n" 358e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 359e5c31af7Sopenharmony_ci "}\n"; 360e5c31af7Sopenharmony_ci test_3.te_body = "${VERSION}\n" 361e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 362e5c31af7Sopenharmony_ci "\n" 363e5c31af7Sopenharmony_ci "layout(triangles, fractional_odd_spacing, ccw, point_mode) in;\n" 364e5c31af7Sopenharmony_ci "\n" 365e5c31af7Sopenharmony_ci "void main()\n" 366e5c31af7Sopenharmony_ci "{\n" 367e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 368e5c31af7Sopenharmony_ci "}\n"; 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci /* Test 4: 8 vertices per patch + quads + equal_spacing + ccw combination + point mode*/ 371e5c31af7Sopenharmony_ci _test_descriptor test_4; 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci test_4.expected_control_output_vertices_value = 8; 374e5c31af7Sopenharmony_ci test_4.expected_gen_mode_value = m_glExtTokens.QUADS; 375e5c31af7Sopenharmony_ci test_4.expected_gen_point_mode_value = GL_TRUE; 376e5c31af7Sopenharmony_ci test_4.expected_gen_spacing_value = GL_EQUAL; 377e5c31af7Sopenharmony_ci test_4.expected_gen_vertex_order_value = GL_CCW; 378e5c31af7Sopenharmony_ci test_4.tc_body = "${VERSION}\n" 379e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 380e5c31af7Sopenharmony_ci "\n" 381e5c31af7Sopenharmony_ci "layout(vertices=8) out;\n" 382e5c31af7Sopenharmony_ci "\n" 383e5c31af7Sopenharmony_ci "void main()\n" 384e5c31af7Sopenharmony_ci "{\n" 385e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 386e5c31af7Sopenharmony_ci "}\n"; 387e5c31af7Sopenharmony_ci test_4.te_body = "${VERSION}\n" 388e5c31af7Sopenharmony_ci "${TESSELLATION_SHADER_REQUIRE}\n" 389e5c31af7Sopenharmony_ci "\n" 390e5c31af7Sopenharmony_ci "layout(quads, equal_spacing, ccw, point_mode) in;\n" 391e5c31af7Sopenharmony_ci "\n" 392e5c31af7Sopenharmony_ci "void main()\n" 393e5c31af7Sopenharmony_ci "{\n" 394e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 395e5c31af7Sopenharmony_ci "}\n"; 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci /* Store all tests in a single vector */ 398e5c31af7Sopenharmony_ci _tests tests; 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci tests.push_back(test_1); 401e5c31af7Sopenharmony_ci tests.push_back(test_2); 402e5c31af7Sopenharmony_ci tests.push_back(test_3); 403e5c31af7Sopenharmony_ci tests.push_back(test_4); 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_ci /* Iterate through all the tests and verify the values reported */ 406e5c31af7Sopenharmony_ci for (_tests_const_iterator test_iterator = tests.begin(); test_iterator != tests.end(); test_iterator++) 407e5c31af7Sopenharmony_ci { 408e5c31af7Sopenharmony_ci const _test_descriptor& test = *test_iterator; 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci /* Set tessellation control & evaluation shader bodies. */ 411e5c31af7Sopenharmony_ci shaderSourceSpecialized(m_tc_id, 1 /* count */, &test.tc_body); 412e5c31af7Sopenharmony_ci shaderSourceSpecialized(m_te_id, 1 /* count */, &test.te_body); 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed"); 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_ci /* Compile the shaders */ 417e5c31af7Sopenharmony_ci gl.compileShader(m_tc_id); 418e5c31af7Sopenharmony_ci gl.compileShader(m_te_id); 419e5c31af7Sopenharmony_ci 420e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed"); 421e5c31af7Sopenharmony_ci 422e5c31af7Sopenharmony_ci /* Make sure the shaders compiled */ 423e5c31af7Sopenharmony_ci glw::GLint tc_compile_status = GL_FALSE; 424e5c31af7Sopenharmony_ci glw::GLint te_compile_status = GL_FALSE; 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ci gl.getShaderiv(m_tc_id, GL_COMPILE_STATUS, &tc_compile_status); 427e5c31af7Sopenharmony_ci gl.getShaderiv(m_te_id, GL_COMPILE_STATUS, &te_compile_status); 428e5c31af7Sopenharmony_ci 429e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed"); 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci if (tc_compile_status != GL_TRUE) 432e5c31af7Sopenharmony_ci { 433e5c31af7Sopenharmony_ci TCU_FAIL("Could not compile tessellation control shader"); 434e5c31af7Sopenharmony_ci } 435e5c31af7Sopenharmony_ci 436e5c31af7Sopenharmony_ci if (te_compile_status != GL_TRUE) 437e5c31af7Sopenharmony_ci { 438e5c31af7Sopenharmony_ci TCU_FAIL("Could not compile tessellation evaluation shader"); 439e5c31af7Sopenharmony_ci } 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ci /* Try to link the program object */ 442e5c31af7Sopenharmony_ci glw::GLint link_status = GL_FALSE; 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci gl.linkProgram(m_po_id); 445e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed"); 446e5c31af7Sopenharmony_ci 447e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 448e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed"); 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ci if (link_status != GL_TRUE) 451e5c31af7Sopenharmony_ci { 452e5c31af7Sopenharmony_ci TCU_FAIL("Program linking failed"); 453e5c31af7Sopenharmony_ci } 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci /* Query the tessellation properties of the program object and make sure 456e5c31af7Sopenharmony_ci * the values reported are valid */ 457e5c31af7Sopenharmony_ci glw::GLint control_output_vertices_value = 0; 458e5c31af7Sopenharmony_ci glw::GLint gen_mode_value = GL_NONE; 459e5c31af7Sopenharmony_ci glw::GLint gen_spacing_value = GL_NONE; 460e5c31af7Sopenharmony_ci glw::GLint gen_vertex_order_value = GL_NONE; 461e5c31af7Sopenharmony_ci glw::GLint gen_point_mode_value = GL_NONE; 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, m_glExtTokens.TESS_CONTROL_OUTPUT_VERTICES, &control_output_vertices_value); 464e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, m_glExtTokens.TESS_GEN_MODE, &gen_mode_value); 465e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, m_glExtTokens.TESS_GEN_SPACING, &gen_spacing_value); 466e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, m_glExtTokens.TESS_GEN_POINT_MODE, &gen_point_mode_value); 467e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, m_glExtTokens.TESS_GEN_VERTEX_ORDER, &gen_vertex_order_value); 468e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() for tessellation-specific properties failed."); 469e5c31af7Sopenharmony_ci 470e5c31af7Sopenharmony_ci if (control_output_vertices_value != test.expected_control_output_vertices_value) 471e5c31af7Sopenharmony_ci { 472e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 473e5c31af7Sopenharmony_ci << "Invalid value reported for GL_TESS_CONTROL_OUTPUT_VERTICES_EXT property; " 474e5c31af7Sopenharmony_ci << " expected: " << test.expected_control_output_vertices_value 475e5c31af7Sopenharmony_ci << ", retrieved: " << control_output_vertices_value << tcu::TestLog::EndMessage; 476e5c31af7Sopenharmony_ci 477e5c31af7Sopenharmony_ci TCU_FAIL("Invalid value reported for GL_TESS_CONTROL_OUTPUT_VERTICES_EXT property."); 478e5c31af7Sopenharmony_ci } 479e5c31af7Sopenharmony_ci 480e5c31af7Sopenharmony_ci if ((glw::GLuint)gen_mode_value != test.expected_gen_mode_value) 481e5c31af7Sopenharmony_ci { 482e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported for GL_TESS_GEN_MODE_EXT property; " 483e5c31af7Sopenharmony_ci << " expected: " << test.expected_gen_mode_value << ", retrieved: " << gen_mode_value 484e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci TCU_FAIL("Invalid value reported for GL_TESS_GEN_MODE_EXT property."); 487e5c31af7Sopenharmony_ci } 488e5c31af7Sopenharmony_ci 489e5c31af7Sopenharmony_ci if ((glw::GLuint)gen_spacing_value != test.expected_gen_spacing_value) 490e5c31af7Sopenharmony_ci { 491e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 492e5c31af7Sopenharmony_ci << "Invalid value reported for GL_TESS_GEN_SPACING_EXT property; " 493e5c31af7Sopenharmony_ci << " expected: " << test.expected_gen_spacing_value 494e5c31af7Sopenharmony_ci << ", retrieved: " << gen_spacing_value << tcu::TestLog::EndMessage; 495e5c31af7Sopenharmony_ci 496e5c31af7Sopenharmony_ci TCU_FAIL("Invalid value reported for GL_TESS_GEN_SPACING_EXT property."); 497e5c31af7Sopenharmony_ci } 498e5c31af7Sopenharmony_ci 499e5c31af7Sopenharmony_ci if ((glw::GLuint)gen_point_mode_value != test.expected_gen_point_mode_value) 500e5c31af7Sopenharmony_ci { 501e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 502e5c31af7Sopenharmony_ci << "Invalid value reported for GL_TESS_GEN_POINT_MODE_EXT property; " 503e5c31af7Sopenharmony_ci << " expected: " << test.expected_gen_point_mode_value 504e5c31af7Sopenharmony_ci << ", retrieved: " << gen_point_mode_value << tcu::TestLog::EndMessage; 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci TCU_FAIL("Invalid value reported for GL_TESS_GEN_POINT_MODE_EXT property."); 507e5c31af7Sopenharmony_ci } 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci if ((glw::GLuint)gen_vertex_order_value != test.expected_gen_vertex_order_value) 510e5c31af7Sopenharmony_ci { 511e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 512e5c31af7Sopenharmony_ci << "Invalid value reported for GL_TESS_GEN_VERTEX_ORDER_EXT property; " 513e5c31af7Sopenharmony_ci << " expected: " << test.expected_gen_vertex_order_value 514e5c31af7Sopenharmony_ci << ", retrieved: " << gen_vertex_order_value << tcu::TestLog::EndMessage; 515e5c31af7Sopenharmony_ci 516e5c31af7Sopenharmony_ci TCU_FAIL("Invalid value reported for GL_TESS_GEN_VERTEX_ORDER_EXT property."); 517e5c31af7Sopenharmony_ci } 518e5c31af7Sopenharmony_ci } /* for (all test descriptors) */ 519e5c31af7Sopenharmony_ci 520e5c31af7Sopenharmony_ci /* All done */ 521e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 522e5c31af7Sopenharmony_ci return STOP; 523e5c31af7Sopenharmony_ci} 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ci} /* namespace glcts */ 526