1/*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2014-2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ /*! 20 * \file 21 * \brief 22 */ /*-------------------------------------------------------------------*/ 23 24#include "esextcGeometryShaderInput.hpp" 25 26#include "gluContextInfo.hpp" 27#include "glwEnums.hpp" 28#include "glwFunctions.hpp" 29#include "tcuTestLog.hpp" 30#include <cstring> 31 32namespace glcts 33{ 34/* Vertex shader for GeometryShader_gl_in_ArrayContents */ 35const char* const GeometryShader_gl_in_ArrayContentsTest::m_vertex_shader_code = 36 "${VERSION}\n" 37 "\n" 38 " out vec2 vs_gs_a;\n" 39 "flat out ivec4 vs_gs_b;\n" 40 "\n" 41 "void main()\n" 42 "{\n" 43 " vs_gs_a = vec2 (gl_VertexID, 0);\n" 44 " vs_gs_b = ivec4(0, gl_VertexID, 0, 1);\n" 45 "}\n"; 46 47/* Geometry shader for GeometryShader_gl_in_ArrayContents */ 48const char* const GeometryShader_gl_in_ArrayContentsTest::m_geometry_shader_preamble_code = 49 "${VERSION}\n" 50 "\n" 51 "${GEOMETRY_SHADER_REQUIRE}\n" 52 "\n" 53 "layout(triangles) in;\n" 54 "layout(triangle_strip, max_vertices=3) out;\n" 55 "\n"; 56 57const char* const GeometryShader_gl_in_ArrayContentsTest::m_geometry_shader_code = 58 "#ifdef USE_UNSIZED_ARRAYS\n" 59 " in vec2 vs_gs_a[];\n" 60 " flat in ivec4 vs_gs_b[];\n" 61 "#else\n" 62 " in vec2 vs_gs_a[3];\n" 63 " flat in ivec4 vs_gs_b[3];\n" 64 "#endif\n" 65 "\n" 66 " out vec2 gs_fs_a;\n" 67 "flat out ivec4 gs_fs_b;\n" 68 "\n" 69 "void main()\n" 70 "{\n" 71 " gl_Position = vec4(-1, -1, 0, 1);\n" 72 " gs_fs_a = vs_gs_a[0];\n" 73 " gs_fs_b = vs_gs_b[0];\n" 74 " EmitVertex();\n" 75 " \n" 76 " gl_Position = vec4(-1, 1, 0, 1);\n" 77 " gs_fs_a = vs_gs_a[1];\n" 78 " gs_fs_b = vs_gs_b[1];\n" 79 " EmitVertex();\n" 80 " \n" 81 " gl_Position = vec4(1, 1, 0, 1);\n" 82 " gs_fs_a = vs_gs_a[2];\n" 83 " gs_fs_b = vs_gs_b[2];\n" 84 " EmitVertex();\n" 85 " \n" 86 " EndPrimitive();\n" 87 "}\n"; 88 89/* Fragment shader for GeometryShader_gl_in_ArrayContents */ 90const char* const GeometryShader_gl_in_ArrayContentsTest::m_fragment_shader_code = 91 "${VERSION}\n" 92 "\n" 93 "precision highp float;\n" 94 "\n" 95 "layout(location = 0) out vec4 fs_out_color;\n" 96 "\n" 97 "void main()\n" 98 "{\n" 99 " fs_out_color = vec4(1, 1, 1, 1);\n" 100 "}\n"; 101 102/* Vertex Shader for GeometryShader_gl_in_ArrayLengthTest*/ 103const char* const GeometryShader_gl_in_ArrayLengthTest::m_vertex_shader_code = 104 "${VERSION}\n" 105 "\n" 106 "void main()\n" 107 "{\n" 108 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n" 109 "}\n"; 110 111/* Geometry shader body parts for GeometryShader_gl_in_ArrayLengthTest */ 112const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_preamble = "${VERSION}\n" 113 "\n" 114 "${GEOMETRY_SHADER_REQUIRE}\n" 115 "\n"; 116 117const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_points = 118 "layout(points) in;\n"; 119 120const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_lines = 121 "layout(lines) in;\n"; 122 123const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_lines_with_adjacency = 124 "layout(lines_adjacency) in;\n"; 125 126const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_triangles = 127 "layout(triangles) in;\n"; 128 129const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_triangles_with_adjacency = 130 "layout(triangles_adjacency) in;\n"; 131 132const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_points = 133 "layout(points, max_vertices=1) out;\n" 134 "\n" 135 "#define N_OUT_VERTICES (1)\n"; 136 137const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_line_strip = 138 "layout(line_strip, max_vertices=2) out;\n" 139 "\n" 140 "#define N_OUT_VERTICES (2)\n"; 141 142const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_triangle_strip = 143 "layout(triangle_strip, max_vertices=3) out;\n" 144 "\n" 145 "#define N_OUT_VERTICES (3)\n"; 146 147const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_main = 148 "\n" 149 "flat out int in_array_size;\n" 150 "\n" 151 "void main()\n" 152 "{\n" 153 " for (int n = 0; n < N_OUT_VERTICES; n++)\n" 154 " {\n" 155 " in_array_size = gl_in.length();\n" 156 " EmitVertex();\n" 157 " }\n" 158 "\n" 159 " EndPrimitive();\n" 160 "}\n"; 161 162/* Fragment Shader for GeometryShader_gl_in_ArrayLengthTest */ 163const char* const GeometryShader_gl_in_ArrayLengthTest::m_fragment_shader_code = "${VERSION}\n" 164 "\n" 165 "precision highp float;\n" 166 "\n" 167 "void main()\n" 168 "{\n" 169 "}\n"; 170 171/* Vertex Shader for GeometryShader_gl_PointSize_ValueTest */ 172const char* const GeometryShader_gl_PointSize_ValueTest::m_vertex_shader_code = 173 "${VERSION}\n" 174 "\n" 175 "void main()\n" 176 "{\n" 177 " // See test description for explanation of magic numbers\n" 178 " switch (gl_VertexID)\n" 179 " {\n" 180 " case 0:\n" 181 " {\n" 182 " gl_Position = vec4(-7.0/8.0, 0, 0, 1);\n" 183 "\n" 184 " break;\n" 185 " }\n" 186 "\n" 187 " case 1:\n" 188 " {\n" 189 " gl_Position = vec4(6.0/8.0, 0, 0, 1);\n" 190 "\n" 191 " break;\n" 192 " }\n" 193 " }\n" 194 "\n" 195 " gl_PointSize = float(2 * (gl_VertexID + 1));\n" 196 "}\n"; 197 198/* Geometry Shader for GeometryShader_gl_PointSize_ValueTest */ 199const char* const GeometryShader_gl_PointSize_ValueTest::m_geometry_shader_code = 200 "${VERSION}\n" 201 "\n" 202 "${GEOMETRY_SHADER_REQUIRE}\n" 203 "${GEOMETRY_POINT_SIZE_REQUIRE}\n" 204 "\n" 205 "layout(points) in;\n" 206 "layout(points, max_vertices=1) out;\n" 207 "\n" 208 "void main()\n" 209 "{\n" 210 " gl_Position = gl_in[0].gl_Position;\n" 211 " gl_PointSize = gl_in[0].gl_PointSize * 2.0;\n" 212 " EmitVertex();\n" 213 " \n" 214 " EndPrimitive();\n" 215 "}\n"; 216 217/* Fragment Shader for GeometryShader_gl_PointSize_ValueTest */ 218const char* const GeometryShader_gl_PointSize_ValueTest::m_fragment_shader_code = 219 "${VERSION}\n" 220 "\n" 221 "precision highp float;\n" 222 "\n" 223 "layout(location = 0) out vec4 fs_out_color;\n" 224 "\n" 225 "void main()\n" 226 "{\n" 227 " fs_out_color = vec4(1, 1, 1, 1);\n" 228 "}\n"; 229 230/* Vertex Shader for GeometryShader_gl_Position_ValueTest */ 231const char* const GeometryShader_gl_Position_ValueTest::m_vertex_shader_code = 232 "${VERSION}\n" 233 "\n" 234 "void main()\n" 235 "{\n" 236 " gl_Position = vec4(gl_VertexID, gl_VertexID, 0, 1);\n" 237 "\n" 238 "}\n"; 239 240/* Geometry Shader for GeometryShader_gl_Position_ValueTest */ 241const char* const GeometryShader_gl_Position_ValueTest::m_geometry_shader_code = 242 "${VERSION}\n" 243 "\n" 244 "${GEOMETRY_SHADER_REQUIRE}\n" 245 "${GEOMETRY_POINT_SIZE_REQUIRE}\n" 246 "\n" 247 "layout(points) in;\n" 248 "layout(points, max_vertices=1) out;\n" 249 "\n" 250 "void main()\n" 251 "{\n" 252 " // See test description for discussion on the magic numbers\n" 253 " gl_Position = vec4(-1.0 + 4.0/32.0 + gl_in[0].gl_Position.x / 4.0, 0, 0, 1);\n" 254 " gl_PointSize = 8.0;\n" 255 " EmitVertex();\n" 256 "\n" 257 " EndPrimitive();\n" 258 "}\n"; 259 260/* Fragment Shader for GeometryShader_gl_Position_ValueTest */ 261const char* const GeometryShader_gl_Position_ValueTest::m_fragment_shader_code = 262 "${VERSION}\n" 263 "\n" 264 "precision highp float;\n" 265 "\n" 266 "layout(location = 0) out vec4 fs_out_color;\n" 267 "\n" 268 "void main()\n" 269 "{\n" 270 " fs_out_color = vec4(1, 1, 1, 1);\n" 271 "}\n"; 272 273/* Constants for GeometryShader_gl_in_ArrayContentsTest */ 274const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_bytes_emitted_per_vertex = 275 2 * sizeof(glw::GLfloat) + 4 * sizeof(glw::GLint); 276const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_emitted_primitives = 1; 277const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_vertices_emitted_per_primitive = 3; 278 279const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_buffer_size = 280 GeometryShader_gl_in_ArrayContentsTest::m_n_bytes_emitted_per_vertex * 281 GeometryShader_gl_in_ArrayContentsTest::m_n_vertices_emitted_per_primitive * 282 GeometryShader_gl_in_ArrayContentsTest::m_n_emitted_primitives; 283 284/* Constants for GeometryShader_gl_in_ArrayLengthTest */ 285const glw::GLuint GeometryShader_gl_in_ArrayLengthTest::m_max_primitive_emitted = 6; 286const glw::GLuint GeometryShader_gl_in_ArrayLengthTest::m_buffer_size = sizeof(glw::GLint) * m_max_primitive_emitted; 287 288/* Constants for GeometryShader_gl_PointSize_ValueTest */ 289const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_height = 16; 290const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_pixel_size = 4; 291const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_width = 16; 292 293/* Constants for GeometryShader_gl_Position_ValueTest */ 294const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_height = 64; 295const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_pixel_size = 4; 296const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_width = 64; 297 298/** Constructor 299 * 300 * @param context Test context 301 * @param name Test case's name 302 * @param description Test case's desricption 303 **/ 304GeometryShader_gl_in_ArrayContentsTest::GeometryShader_gl_in_ArrayContentsTest(Context& context, 305 const ExtParameters& extParams, 306 const char* name, 307 const char* description) 308 : TestCaseBase(context, extParams, name, description) 309 , m_fragment_shader_id(0) 310 , m_geometry_shader_sized_arrays_id(0) 311 , m_geometry_shader_unsized_arrays_id(0) 312 , m_program_object_sized_arrays_id(0) 313 , m_program_object_unsized_arrays_id(0) 314 , m_vertex_shader_id(0) 315 , m_buffer_object_id(0) 316 , m_vertex_array_object_id(0) 317{ 318 /* Nothing to be done here */ 319} 320 321/** Initializes GLES objects used during the test. 322 * 323 **/ 324void GeometryShader_gl_in_ArrayContentsTest::initTest() 325{ 326 /* Varing names */ 327 const glw::GLchar* const captured_varyings[] = { 328 "gs_fs_a", "gs_fs_b", 329 }; 330 331 /* Number of varings */ 332 const glw::GLuint n_captured_varyings_size = sizeof(captured_varyings) / sizeof(captured_varyings[0]); 333 334 /* GL */ 335 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 336 337 /* Create program and shaders */ 338 m_program_object_sized_arrays_id = gl.createProgram(); 339 m_program_object_unsized_arrays_id = gl.createProgram(); 340 341 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 342 m_geometry_shader_unsized_arrays_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 343 m_geometry_shader_sized_arrays_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 344 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 345 346 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program"); 347 348 /* Set up transform feedback */ 349 gl.transformFeedbackVaryings(m_program_object_sized_arrays_id, n_captured_varyings_size, captured_varyings, 350 GL_INTERLEAVED_ATTRIBS); 351 gl.transformFeedbackVaryings(m_program_object_unsized_arrays_id, n_captured_varyings_size, captured_varyings, 352 GL_INTERLEAVED_ATTRIBS); 353 354 /* Build programs */ 355 const char* geometry_shader_unsized_arrays_code[] = { m_geometry_shader_preamble_code, 356 "#define USE_UNSIZED_ARRAYS\n", m_geometry_shader_code }; 357 const char* geometry_shader_sized_arrays_code[] = { m_geometry_shader_preamble_code, m_geometry_shader_code }; 358 359 if (false == 360 buildProgram(m_program_object_unsized_arrays_id, m_fragment_shader_id, 1 /* number of fragment shader parts */, 361 &m_fragment_shader_code, m_geometry_shader_unsized_arrays_id, 362 DE_LENGTH_OF_ARRAY(geometry_shader_unsized_arrays_code), geometry_shader_unsized_arrays_code, 363 m_vertex_shader_id, 1 /* number of vertex shader parts */, &m_vertex_shader_code)) 364 { 365 TCU_FAIL("Could not create a program from valid vertex/geometry (unsized arrays version)/fragment shaders"); 366 } 367 368 if (false == buildProgram(m_program_object_sized_arrays_id, m_fragment_shader_id, 369 1 /* number of fragment shader parts */, &m_fragment_shader_code, 370 m_geometry_shader_sized_arrays_id, DE_LENGTH_OF_ARRAY(geometry_shader_sized_arrays_code), 371 geometry_shader_sized_arrays_code, m_vertex_shader_id, 372 1 /* number of vertex shader parts */, &m_vertex_shader_code)) 373 { 374 TCU_FAIL("Could not create a program from valid vertex/geometry (sized arrays version)/fragment shaders"); 375 } 376 377 /* Generate, bind and allocate buffer */ 378 gl.genBuffers(1, &m_buffer_object_id); 379 gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id); 380 gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_DRAW); 381 382 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object"); 383 384 /* Generate and bind VAO */ 385 gl.genVertexArrays(1, &m_vertex_array_object_id); 386 gl.bindVertexArray(m_vertex_array_object_id); 387 388 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object"); 389} 390 391/** Executes the test. 392 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 393 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 394 * Note the function throws exception should an error occur! 395 **/ 396tcu::TestCase::IterateResult GeometryShader_gl_in_ArrayContentsTest::iterate() 397{ 398 /* This test should only run if EXT_geometry_shader is supported */ 399 if (true != m_is_geometry_shader_extension_supported) 400 { 401 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 402 } 403 404 initTest(); 405 406 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 407 unsigned char reference_data[m_buffer_size] = { 0 }; 408 bool result = true; 409 410 /* Prepare reference data */ 411 { 412 glw::GLint* ivec4_data_ptr; 413 glw::GLfloat* vec2_data_ptr; 414 415 const unsigned int ivec4_offset_from_vertex = 2 * sizeof(glw::GLfloat); 416 const unsigned int vec2_offset_from_vertex = 0; 417 418 /* Expected data for vertex: 419 * vec2 = {VertexID, 0.0f} 420 * ivec4 = {0, VertexID, 0, 1} 421 */ 422 for (unsigned int vertex_id = 0; vertex_id < m_n_vertices_emitted_per_primitive * m_n_emitted_primitives; 423 ++vertex_id) 424 { 425 const unsigned int vertex_offset = vertex_id * m_n_bytes_emitted_per_vertex; 426 const unsigned int ivec4_offset = vertex_offset + ivec4_offset_from_vertex; 427 const unsigned int vec2_offset = vertex_offset + vec2_offset_from_vertex; 428 429 ivec4_data_ptr = (glw::GLint*)(reference_data + ivec4_offset); 430 vec2_data_ptr = (glw::GLfloat*)(reference_data + vec2_offset); 431 432 ivec4_data_ptr[0] = 0; 433 ivec4_data_ptr[1] = vertex_id; 434 ivec4_data_ptr[2] = 0; 435 ivec4_data_ptr[3] = 1; 436 437 vec2_data_ptr[0] = (float)vertex_id; 438 vec2_data_ptr[1] = 0.0f; 439 } 440 } 441 442 /* Setup transform feedback */ 443 gl.enable(GL_RASTERIZER_DISCARD); 444 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id); 445 446 /* Draw the geometry */ 447 for (int n_case = 0; n_case < 2 /* unsized/sized array cases */; ++n_case) 448 { 449 glw::GLuint po_id = (n_case == 0) ? m_program_object_unsized_arrays_id : m_program_object_sized_arrays_id; 450 451 gl.useProgram(po_id); 452 gl.beginTransformFeedback(GL_TRIANGLES); 453 { 454 gl.drawArrays(GL_TRIANGLES, 0 /* first */, 3 /* one triangle */); 455 } 456 gl.endTransformFeedback(); 457 458 GLU_EXPECT_NO_ERROR(gl.getError(), "Error doing a draw call"); 459 460 /* Map buffer object storage holding XFB result into process space. */ 461 glw::GLchar* transform_feedback_data = (glw::GLchar*)gl.mapBufferRange( 462 GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, m_buffer_size, GL_MAP_READ_BIT); 463 464 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space"); 465 466 /* Verify data extracted from transform feedback */ 467 if (0 != memcmp(transform_feedback_data, reference_data, m_buffer_size)) 468 { 469 m_testCtx.getLog() << tcu::TestLog::Message << "Data extracted from transform feedback is invalid." 470 << tcu::TestLog::EndMessage; 471 472 result = false; 473 } 474 475 /* Unmap the buffer object. */ 476 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 477 478 GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object"); 479 480 /* Verify results */ 481 if (true != result) 482 { 483 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 484 return STOP; 485 } 486 } 487 488 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 489 return STOP; 490} 491 492/** Deinitializes GLES objects created during the test. 493 * 494 */ 495void GeometryShader_gl_in_ArrayContentsTest::deinit() 496{ 497 /* GL */ 498 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 499 500 /* Bind default values */ 501 gl.useProgram(0); 502 gl.bindVertexArray(0); 503 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */); 504 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 505 506 /* Delete everything */ 507 if (0 != m_vertex_array_object_id) 508 { 509 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 510 } 511 512 if (0 != m_buffer_object_id) 513 { 514 gl.deleteBuffers(1, &m_buffer_object_id); 515 } 516 517 if (0 != m_program_object_sized_arrays_id) 518 { 519 gl.deleteProgram(m_program_object_sized_arrays_id); 520 } 521 522 if (0 != m_program_object_unsized_arrays_id) 523 { 524 gl.deleteProgram(m_program_object_unsized_arrays_id); 525 } 526 527 if (0 != m_fragment_shader_id) 528 { 529 gl.deleteShader(m_fragment_shader_id); 530 } 531 532 if (0 != m_geometry_shader_sized_arrays_id) 533 { 534 gl.deleteShader(m_geometry_shader_sized_arrays_id); 535 } 536 537 if (0 != m_geometry_shader_unsized_arrays_id) 538 { 539 gl.deleteShader(m_geometry_shader_unsized_arrays_id); 540 } 541 542 if (0 != m_vertex_shader_id) 543 { 544 gl.deleteShader(m_vertex_shader_id); 545 } 546 547 /* Deinitialize Base */ 548 TestCaseBase::deinit(); 549} 550 551/** Constructor 552 * 553 * @param context Test context 554 * @param name Test case's name 555 * @param description Test case's desricption 556 **/ 557GeometryShader_gl_in_ArrayLengthTest::GeometryShader_gl_in_ArrayLengthTest(Context& context, 558 const ExtParameters& extParams, 559 const char* name, const char* description) 560 : TestCaseBase(context, extParams, name, description), m_buffer_object_id(0), m_vertex_array_object_id(0) 561{ 562 /* Nothing to be done here */ 563} 564 565/** Initialize test case 566 * 567 **/ 568void GeometryShader_gl_in_ArrayLengthTest::init() 569{ 570 /* Initialize Base */ 571 TestCaseBase::init(); 572 573 /* Captured variables */ 574 const char* captured_varyings[] = { "in_array_size" }; 575 576 /* This test should only run if EXT_geometry_shader is supported */ 577 if (true != m_is_geometry_shader_extension_supported) 578 { 579 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 580 } 581 582 /* GL */ 583 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 584 585 /* Set up test descriptors */ 586 initCase(m_test_lines, GL_LINES, 2, /* number of vertices */ 587 2, /* as per spec */ 588 GL_POINTS, m_geometry_shader_code_input_lines, m_geometry_shader_code_output_points); 589 590 m_tests.push_back(&m_test_lines); 591 592 initCase(m_test_lines_adjacency, m_glExtTokens.LINES_ADJACENCY, 4, /* number of vertices */ 593 4, /* as per spec */ 594 GL_POINTS, m_geometry_shader_code_input_lines_with_adjacency, m_geometry_shader_code_output_points); 595 596 m_tests.push_back(&m_test_lines_adjacency); 597 598 initCase(m_test_points, GL_POINTS, 1, /* number of vertices */ 599 1, /* as per spec */ 600 GL_POINTS, m_geometry_shader_code_input_points, m_geometry_shader_code_output_points); 601 602 m_tests.push_back(&m_test_points); 603 604 initCase(m_test_triangles, GL_TRIANGLES, 3, /* number of vertices */ 605 3, /* as per spec */ 606 GL_POINTS, m_geometry_shader_code_input_triangles, m_geometry_shader_code_output_points); 607 608 m_tests.push_back(&m_test_triangles); 609 610 initCase(m_test_triangles_adjacency, m_glExtTokens.TRIANGLE_STRIP_ADJACENCY, 6, /* number of vertices */ 611 6, /* as per spec */ 612 GL_POINTS, m_geometry_shader_code_input_triangles_with_adjacency, m_geometry_shader_code_output_points); 613 614 m_tests.push_back(&m_test_triangles_adjacency); 615 616 initCase(m_test_lines_adjacency_to_line_strip, m_glExtTokens.LINES_ADJACENCY, 4 /* number of vertices */, 617 4 /* expected array length */, GL_LINES, m_geometry_shader_code_input_lines_with_adjacency, 618 m_geometry_shader_code_output_line_strip); 619 620 m_tests.push_back(&m_test_lines_adjacency_to_line_strip); 621 622 initCase(m_test_triangles_adjacency_to_triangle_strip, m_glExtTokens.TRIANGLE_STRIP_ADJACENCY, 623 6 /* number of vertices */, 6 /* expected array length */, GL_TRIANGLES, 624 m_geometry_shader_code_input_triangles_with_adjacency, m_geometry_shader_code_output_triangle_strip); 625 626 m_tests.push_back(&m_test_triangles_adjacency_to_triangle_strip); 627 628 /* Initialize program objects */ 629 for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it) 630 { 631 /* Case instance */ 632 Case* test = *it; 633 634 /* Init program */ 635 initCaseProgram(*test, captured_varyings, sizeof(captured_varyings) / sizeof(captured_varyings[0])); 636 } 637 638 /* Generate, bind and allocate buffer */ 639 gl.genBuffers(1, &m_buffer_object_id); 640 gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id); 641 gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_DRAW); 642 643 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object"); 644 645 /* Generate and bind VAO */ 646 gl.genVertexArrays(1, &m_vertex_array_object_id); 647 gl.bindVertexArray(m_vertex_array_object_id); 648 649 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object"); 650} 651 652/** Executes the test. 653 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 654 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 655 * Note the function throws exception should an error occur! 656 **/ 657tcu::TestCase::IterateResult GeometryShader_gl_in_ArrayLengthTest::iterate() 658{ 659 /* GL */ 660 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 661 662 /* This test should only run if EXT_geometry_shader is supported */ 663 if (true != m_is_geometry_shader_extension_supported) 664 { 665 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 666 } 667 668 /* Setup transform feedback */ 669 gl.enable(GL_RASTERIZER_DISCARD); 670 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id); 671 672 /* Execute tests */ 673 for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it) 674 { 675 glw::GLint result_value = 0; 676 Case* test = *it; 677 678 /* Execute */ 679 gl.useProgram(test->po_id); 680 681 gl.beginTransformFeedback(test->tf_mode); 682 { 683 gl.drawArrays(test->draw_call_mode, 0, /* first */ 684 test->draw_call_n_vertices); 685 } 686 gl.endTransformFeedback(); 687 688 GLU_EXPECT_NO_ERROR(gl.getError(), "Error doing a draw call"); 689 690 /* Map transform feedback results */ 691 glw::GLint* result = (glw::GLint*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 692 sizeof(glw::GLint), GL_MAP_READ_BIT); 693 694 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space"); 695 696 /* Extract value from transform feedback */ 697 result_value = *result; 698 699 /* Unmap transform feedback buffer */ 700 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 701 702 GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object"); 703 704 /* Verify results */ 705 if (result_value != test->expected_array_length) 706 { 707 m_testCtx.getLog() << tcu::TestLog::Message << "Expected array length: " << test->expected_array_length 708 << " but found: " << result_value << tcu::TestLog::EndMessage; 709 710 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 711 return STOP; 712 } 713 } 714 715 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 716 return STOP; 717} 718 719/** Deinitializes test case 720 * 721 **/ 722void GeometryShader_gl_in_ArrayLengthTest::deinit() 723{ 724 /* GL */ 725 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 726 727 /* Bind default values */ 728 gl.useProgram(0); 729 gl.bindVertexArray(0); 730 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */); 731 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 732 733 /* Delete everything */ 734 if (0 != m_vertex_array_object_id) 735 { 736 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 737 } 738 739 if (0 != m_buffer_object_id) 740 { 741 gl.deleteBuffers(1, &m_buffer_object_id); 742 } 743 744 /* Deinit test cases */ 745 for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it) 746 { 747 Case* test = *it; 748 749 deinitCase(*test); 750 } 751 752 m_tests.clear(); 753 754 /* Deinitialize Base */ 755 TestCaseBase::deinit(); 756} 757 758/** Deinitialize test case instance 759 * 760 * @param info Case instance 761 **/ 762void GeometryShader_gl_in_ArrayLengthTest::deinitCase(Case& info) 763{ 764 /* GL */ 765 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 766 767 /* Delete everything */ 768 if (0 != info.po_id) 769 { 770 gl.deleteProgram(info.po_id); 771 } 772 773 if (0 != info.vs_id) 774 { 775 gl.deleteShader(info.vs_id); 776 } 777 778 if (0 != info.gs_id) 779 { 780 gl.deleteShader(info.gs_id); 781 } 782 783 if (0 != info.fs_id) 784 { 785 gl.deleteShader(info.fs_id); 786 } 787 788 /* Clear case */ 789 resetCase(info); 790} 791 792/** Initialize test case instance with provided data. 793 * 794 * @param info Case instance; 795 * @param draw_call_mode Primitive type used by a draw call; 796 * @param draw_call_n_vertices Number of vertices used by a draw call; 797 * @param expected_array_length Expected size of gl_in array; 798 * @param tf_mode Primitive type used by transform feedback; 799 * @param input_body_part Part of geometry shader which specifies input layout; 800 * @param output_body_part Part of geometry shader which specifies output layout; 801 **/ 802void GeometryShader_gl_in_ArrayLengthTest::initCase(Case& info, glw::GLenum draw_call_mode, 803 glw::GLint draw_call_n_vertices, glw::GLint expected_array_length, 804 glw::GLenum tf_mode, const glw::GLchar* input_body_part, 805 const glw::GLchar* output_body_part) 806{ 807 /* Reset case descriptor */ 808 resetCase(info); 809 810 /* Set fields */ 811 info.draw_call_mode = draw_call_mode; 812 info.draw_call_n_vertices = draw_call_n_vertices; 813 info.expected_array_length = expected_array_length; 814 info.input_body_part = input_body_part; 815 info.output_body_part = output_body_part; 816 info.tf_mode = tf_mode; 817} 818 819/** Creates and build program for given Case 820 * 821 * @param info Case instance 822 * @param captured_varyings Name of varyings captured by transform feedback 823 * @param n_captured_varyings_size Number of varyings captured by transform feedback 824 **/ 825void GeometryShader_gl_in_ArrayLengthTest::initCaseProgram(Case& info, const glw::GLchar** captured_varyings, 826 glw::GLuint n_captured_varyings_size) 827{ 828 /* GL */ 829 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 830 831 /* Create program and shader objects */ 832 info.po_id = gl.createProgram(); 833 834 info.vs_id = gl.createShader(GL_VERTEX_SHADER); 835 info.gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 836 info.fs_id = gl.createShader(GL_FRAGMENT_SHADER); 837 838 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object"); 839 840 /* Prepare geometry shader parts */ 841 const char* const geometry_shader_parts[] = { m_geometry_shader_code_preamble, info.input_body_part, 842 info.output_body_part, m_geometry_shader_code_main }; 843 844 /* Set up transform feedback */ 845 gl.transformFeedbackVaryings(info.po_id, n_captured_varyings_size, captured_varyings, GL_SEPARATE_ATTRIBS); 846 847 /* Build program */ 848 if (false == buildProgram(info.po_id, info.fs_id, 1 /* number of fragment shader code parts */, 849 &m_fragment_shader_code, info.gs_id, DE_LENGTH_OF_ARRAY(geometry_shader_parts), 850 geometry_shader_parts, info.vs_id, 1 /* number of vertex shader code parts */, 851 &m_vertex_shader_code)) 852 { 853 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 854 } 855} 856 857/** Reset Case instance descriptor's contents. 858 * 859 * @param info Case instance 860 **/ 861void GeometryShader_gl_in_ArrayLengthTest::resetCase(Case& info) 862{ 863 memset(&info, 0, sizeof(info)); 864} 865 866/** Constructor 867 * 868 * @param context Test context 869 * @param name Test case's name 870 * @param description Test case's desricption 871 **/ 872GeometryShader_gl_PointSize_ValueTest::GeometryShader_gl_PointSize_ValueTest(Context& context, 873 const ExtParameters& extParams, 874 const char* name, const char* description) 875 : TestCaseBase(context, extParams, name, description) 876 , m_fragment_shader_id(0) 877 , m_geometry_shader_id(0) 878 , m_program_object_id(0) 879 , m_vertex_shader_id(0) 880 , m_vertex_array_object_id(0) 881 , m_color_texture_id(0) 882 , m_framebuffer_object_id(0) 883{ 884 /* Nothing to be done here */ 885} 886 887/** Initialize test case 888 * 889 **/ 890void GeometryShader_gl_PointSize_ValueTest::init() 891{ 892 /* Initialize Base */ 893 TestCaseBase::init(); 894 895 /* This test should only run if EXT_geometry_shader and EXT_geometry_point_size both are supported */ 896 if (true != m_is_geometry_shader_extension_supported) 897 { 898 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 899 } 900 901 if (true != m_is_geometry_shader_point_size_supported) 902 { 903 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 904 } 905 906 /* GL */ 907 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 908 909 /* Verify that point size range is supported */ 910 glw::GLfloat point_size_range[2] = { 0 }; 911 912 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 913 { 914 gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range); 915 } 916 else 917 { 918 gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range); 919 } 920 921 if (8.0f > point_size_range[1]) 922 { 923 m_testCtx.getLog() << tcu::TestLog::Message 924 << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : " 925 << point_size_range[1] << tcu::TestLog::EndMessage; 926 927 throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__); 928 } 929 930 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 931 { 932 gl.enable(GL_PROGRAM_POINT_SIZE); 933 } 934 935 /* Create program and shaders */ 936 m_program_object_id = gl.createProgram(); 937 938 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 939 m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 940 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 941 942 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program"); 943 944 /* Build program */ 945 if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */, 946 &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */, 947 &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */, 948 &m_vertex_shader_code)) 949 { 950 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 951 } 952 953 /* Set up texture object and a FBO */ 954 gl.genTextures(1, &m_color_texture_id); 955 gl.genFramebuffers(1, &m_framebuffer_object_id); 956 957 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer"); 958 959 if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8, 960 m_texture_width, m_texture_height)) 961 { 962 TCU_FAIL("Failed to setup framebuffer"); 963 } 964 965 /* Set up a vertex array object */ 966 gl.genVertexArrays(1, &m_vertex_array_object_id); 967 gl.bindVertexArray(m_vertex_array_object_id); 968 969 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object"); 970} 971 972/** Executes the test. 973 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 974 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 975 * Note the function throws exception should an error occur! 976 **/ 977tcu::TestCase::IterateResult GeometryShader_gl_PointSize_ValueTest::iterate() 978{ 979 /* Buffer to store results of rendering */ 980 unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size]; 981 982 /* This test should only run if EXT_geometry_shader is supported */ 983 if (true != m_is_geometry_shader_extension_supported) 984 { 985 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 986 } 987 988 if (true != m_is_geometry_shader_point_size_supported) 989 { 990 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 991 } 992 993 /* GL */ 994 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 995 996 /* Render */ 997 gl.useProgram(m_program_object_id); 998 999 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program"); 1000 1001 gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */); 1002 gl.clear(GL_COLOR_BUFFER_BIT); 1003 1004 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer"); 1005 1006 gl.drawArrays(GL_POINTS, 0 /* first */, 2 /* count */); 1007 1008 GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed"); 1009 1010 /* Check if the data was modified during the rendering process */ 1011 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image); 1012 1013 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer"); 1014 1015 /* 1) pixel at (2, 8) is (255, 255, 255, 255) */ 1016 unsigned int referencePixelCoordinates[2] = { 2, 8 }; 1017 1018 if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */, 1019 m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */, 1020 255 /* blue */, 255 /* alpha */)) 1021 { 1022 const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size + 1023 referencePixelCoordinates[0] * m_texture_pixel_size; 1024 1025 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", " 1026 << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", " 1027 << result_image[texel_offset + 3] << "]" 1028 << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage; 1029 1030 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1031 return STOP; 1032 } 1033 1034 /* 2) pixel at (14, 8) is (255, 255, 255, 255) */ 1035 referencePixelCoordinates[0] = 14; 1036 referencePixelCoordinates[1] = 8; 1037 1038 if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */, 1039 m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */, 1040 255 /* blue */, 255 /* alpha */)) 1041 { 1042 const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size + 1043 referencePixelCoordinates[0] * m_texture_pixel_size; 1044 1045 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", " 1046 << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", " 1047 << result_image[texel_offset + 3] << "]" 1048 << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage; 1049 1050 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1051 return STOP; 1052 } 1053 1054 /* 3) pixel at (6, 8) is (0, 0, 0, 0) */ 1055 referencePixelCoordinates[0] = 6; 1056 referencePixelCoordinates[1] = 8; 1057 1058 if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */, 1059 m_texture_width, m_texture_height, m_texture_pixel_size, 0 /* red */, 0 /* green */, 1060 0 /* blue */, 0 /* alpha */)) 1061 { 1062 const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size + 1063 referencePixelCoordinates[0] * m_texture_pixel_size; 1064 1065 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", " 1066 << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", " 1067 << result_image[texel_offset + 3] << "]" 1068 << "is different from reference data [0, 0, 0, 0]!" << tcu::TestLog::EndMessage; 1069 1070 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1071 return STOP; 1072 } 1073 1074 /* Done */ 1075 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1076 return STOP; 1077} 1078 1079/** Deinitializes test case 1080 * 1081 **/ 1082void GeometryShader_gl_PointSize_ValueTest::deinit() 1083{ 1084 /* GL */ 1085 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1086 1087 /* Bind defaults */ 1088 gl.useProgram(0); 1089 gl.bindVertexArray(0); 1090 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0 /* texture */, 0 /* level */); 1091 gl.bindTexture(GL_TEXTURE_2D, 0); 1092 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1093 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1094 { 1095 gl.disable(GL_PROGRAM_POINT_SIZE); 1096 } 1097 1098 /* Delete everything */ 1099 if (m_program_object_id != 0) 1100 { 1101 gl.deleteProgram(m_program_object_id); 1102 } 1103 1104 if (m_fragment_shader_id != 0) 1105 { 1106 gl.deleteShader(m_fragment_shader_id); 1107 } 1108 1109 if (m_geometry_shader_id != 0) 1110 { 1111 gl.deleteShader(m_geometry_shader_id); 1112 } 1113 1114 if (m_vertex_shader_id != 0) 1115 { 1116 gl.deleteShader(m_vertex_shader_id); 1117 } 1118 1119 if (m_vertex_array_object_id != 0) 1120 { 1121 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 1122 } 1123 1124 if (m_color_texture_id != 0) 1125 { 1126 gl.deleteTextures(1, &m_color_texture_id); 1127 } 1128 1129 if (m_framebuffer_object_id != 0) 1130 { 1131 gl.deleteFramebuffers(1, &m_framebuffer_object_id); 1132 } 1133 1134 /* Release base class */ 1135 TestCaseBase::deinit(); 1136} 1137 1138/** Constructor 1139 * 1140 * @param context Test context 1141 * @param name Test case's name 1142 * @param description Test case's desricption 1143 **/ 1144GeometryShader_gl_Position_ValueTest::GeometryShader_gl_Position_ValueTest(Context& context, 1145 const ExtParameters& extParams, 1146 const char* name, const char* description) 1147 : TestCaseBase(context, extParams, name, description) 1148 , m_fragment_shader_id(0) 1149 , m_geometry_shader_id(0) 1150 , m_program_object_id(0) 1151 , m_vertex_shader_id(0) 1152 , m_vertex_array_object_id(0) 1153 , m_color_texture_id(0) 1154 , m_framebuffer_object_id(0) 1155{ 1156 /* Nothing to be done here */ 1157} 1158 1159/** Initialize test case 1160 * 1161 **/ 1162void GeometryShader_gl_Position_ValueTest::init() 1163{ 1164 /* Initialize base */ 1165 TestCaseBase::init(); 1166 1167 /* This test should only run if EXT_geometry_shader is supported */ 1168 if (true != m_is_geometry_shader_extension_supported) 1169 { 1170 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 1171 } 1172 1173 if (true != m_is_geometry_shader_point_size_supported) 1174 { 1175 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 1176 } 1177 1178 /* GL */ 1179 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1180 1181 /* Verify that point size range is supported */ 1182 glw::GLfloat point_size_range[2] = { 0 }; 1183 1184 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1185 { 1186 gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range); 1187 } 1188 else 1189 { 1190 gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range); 1191 } 1192 1193 if (8.0f > point_size_range[1]) 1194 { 1195 m_testCtx.getLog() << tcu::TestLog::Message 1196 << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : " 1197 << point_size_range[1] << tcu::TestLog::EndMessage; 1198 1199 throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__); 1200 } 1201 1202 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1203 { 1204 gl.enable(GL_PROGRAM_POINT_SIZE); 1205 } 1206 1207 /* Create program and shaders */ 1208 m_program_object_id = gl.createProgram(); 1209 1210 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 1211 m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 1212 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 1213 1214 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program"); 1215 1216 /* Build program */ 1217 if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */, 1218 &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */, 1219 &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */, 1220 &m_vertex_shader_code)) 1221 { 1222 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 1223 } 1224 1225 /* Set up a texture object and a FBO */ 1226 gl.genTextures(1, &m_color_texture_id); 1227 gl.genFramebuffers(1, &m_framebuffer_object_id); 1228 1229 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer"); 1230 1231 if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8, 1232 m_texture_width, m_texture_height)) 1233 { 1234 TCU_FAIL("Failed to setup framebuffer"); 1235 } 1236 1237 /* Set up a vertex array object */ 1238 gl.genVertexArrays(1, &m_vertex_array_object_id); 1239 gl.bindVertexArray(m_vertex_array_object_id); 1240 1241 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object"); 1242} 1243 1244/** Executes the test. 1245 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 1246 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 1247 * Note the function throws exception should an error occur! 1248 **/ 1249tcu::TestCase::IterateResult GeometryShader_gl_Position_ValueTest::iterate() 1250{ 1251 /* Variables used for image verification purposes */ 1252 unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size]; 1253 1254 /* This test should only run if EXT_geometry_shader is supported */ 1255 if (true != m_is_geometry_shader_extension_supported) 1256 { 1257 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 1258 } 1259 1260 /* GL */ 1261 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1262 1263 /* Render */ 1264 gl.useProgram(m_program_object_id); 1265 1266 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program"); 1267 1268 gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */); 1269 gl.clear(GL_COLOR_BUFFER_BIT); 1270 1271 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer"); 1272 1273 gl.drawArrays(GL_POINTS, 0 /* first */, 8 /* count */); 1274 1275 GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed"); 1276 1277 /* Check if the data was modified during the rendering process */ 1278 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image); 1279 1280 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer"); 1281 1282 /* The test passes if centers of the rendered points are lit at expected locations. */ 1283 for (unsigned int x = 4; x < m_texture_width; x += 8) 1284 { 1285 if (false == comparePixel(result_image, x, 32 /* y */, m_texture_width, m_texture_height, m_texture_pixel_size, 1286 255 /* red */, 255 /* green */, 255 /* blue */, 255 /* alpha */)) 1287 { 1288 const unsigned int texel_offset = 32 * m_texture_width * m_texture_pixel_size + x * m_texture_pixel_size; 1289 1290 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", " 1291 << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", " 1292 << result_image[texel_offset + 3] << "]" 1293 << "is different from reference data [255, 255, 255, 255] !" << tcu::TestLog::EndMessage; 1294 1295 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1296 return STOP; 1297 } 1298 } 1299 1300 /* Done */ 1301 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1302 return STOP; 1303} 1304 1305/** Deinitializes test case 1306 * 1307 **/ 1308void GeometryShader_gl_Position_ValueTest::deinit() 1309{ 1310 /* GL */ 1311 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1312 1313 /* Bind default values */ 1314 gl.useProgram(0); 1315 gl.bindVertexArray(0); 1316 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0 /* texture */, 0 /* level */); 1317 gl.bindTexture(GL_TEXTURE_2D, 0); 1318 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1319 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1320 { 1321 gl.disable(GL_PROGRAM_POINT_SIZE); 1322 } 1323 1324 /* Delete everything */ 1325 if (m_program_object_id != 0) 1326 { 1327 gl.deleteProgram(m_program_object_id); 1328 } 1329 1330 if (m_fragment_shader_id != 0) 1331 { 1332 gl.deleteShader(m_fragment_shader_id); 1333 } 1334 1335 if (m_geometry_shader_id != 0) 1336 { 1337 gl.deleteShader(m_geometry_shader_id); 1338 } 1339 1340 if (m_vertex_shader_id != 0) 1341 { 1342 gl.deleteShader(m_vertex_shader_id); 1343 } 1344 1345 if (m_vertex_array_object_id != 0) 1346 { 1347 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 1348 } 1349 1350 if (m_color_texture_id != 0) 1351 { 1352 gl.deleteTextures(1, &m_color_texture_id); 1353 } 1354 1355 if (m_framebuffer_object_id != 0) 1356 { 1357 gl.deleteFramebuffers(1, &m_framebuffer_object_id); 1358 } 1359 1360 /* Release base class */ 1361 TestCaseBase::deinit(); 1362} 1363 1364} /* glcts */ 1365