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 * \file esextcGeometryShaderLimits.cpp 25 * \brief Geometry Shader Limits (Test Group 16) 26 */ /*-------------------------------------------------------------------*/ 27 28#include "esextcGeometryShaderLimits.hpp" 29 30#include "gluContextInfo.hpp" 31#include "glwEnums.hpp" 32#include "glwFunctions.hpp" 33#include "tcuTestLog.hpp" 34 35#include <cstring> 36#include <sstream> 37#include <string> 38 39namespace glcts 40{ 41/* Vertex Shader for GeometryShaderMaxUniformComponentsTest */ 42const glw::GLchar* const GeometryShaderMaxUniformComponentsTest::m_vertex_shader_code = 43 "${VERSION}\n" 44 "\n" 45 "${GEOMETRY_SHADER_REQUIRE}\n" 46 "\n" 47 "void main()\n" 48 "{\n" 49 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n" 50 "}\n"; 51 52/* Geometry Shader parts for GeometryShaderMaxUniformComponentsTest */ 53const glw::GLchar* const GeometryShaderMaxUniformComponentsTest::m_geometry_shader_code_preamble = 54 "${VERSION}\n" 55 "\n" 56 "${GEOMETRY_SHADER_REQUIRE}\n" 57 "\n" 58 "layout(points) in;\n" 59 "layout(points, max_vertices=1) out;\n" 60 "\n" 61 "// definition of NUMBER_OF_UNIFORMS goes here\n"; 62 63const glw::GLchar* const GeometryShaderMaxUniformComponentsTest::m_geometry_shader_code_number_of_uniforms = 64 "#define NUMBER_OF_UNIFORMS "; 65 66const glw::GLchar* const GeometryShaderMaxUniformComponentsTest::m_geometry_shader_code_body = 67 "u\n" 68 "\n" 69 "uniform ivec4 uni_array[NUMBER_OF_UNIFORMS];\n" 70 "\n" 71 "flat out uint gs_out_sum;\n" 72 "\n" 73 "void main()\n" 74 "{\n" 75 " gs_out_sum = 0u;\n" 76 "\n" 77 " for (uint i = 0u; i < NUMBER_OF_UNIFORMS; ++i)\n" 78 " {\n" 79 " gs_out_sum += uint(uni_array[i].x);\n" 80 " gs_out_sum += uint(uni_array[i].y);\n" 81 " gs_out_sum += uint(uni_array[i].z);\n" 82 " gs_out_sum += uint(uni_array[i].w);\n" 83 " }\n" 84 " EmitVertex();\n" 85 " \n" 86 " EndPrimitive();\n" 87 "}\n"; 88 89/* Fragment Shader for GeometryShaderMaxUniformComponentsTest */ 90const glw::GLchar* const GeometryShaderMaxUniformComponentsTest::m_fragment_shader_code = 91 "${VERSION}\n" 92 "${GEOMETRY_SHADER_REQUIRE}\n" 93 "precision mediump float;\n" 94 "out vec4 fs_out_color;\n" 95 "void main()\n" 96 "{\n" 97 " fs_out_color = vec4(1, 1, 1, 1);\n" 98 "}\n"; 99 100/** ***************************************************************************************************** **/ 101/* Vertex Shader for GeometryShaderMaxUniformBlocksTest */ 102const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_vertex_shader_code = 103 "${VERSION}\n" 104 "\n" 105 "${GEOMETRY_SHADER_REQUIRE}\n" 106 "\n" 107 "void main()\n" 108 "{\n" 109 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n" 110 "}\n"; 111 112/* Geometry Shader Parts for GeometryShaderMaxUniformBlocksTest */ 113const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_geometry_shader_code_preamble = 114 "${VERSION}\n" 115 "\n" 116 "${GEOMETRY_SHADER_REQUIRE}\n" 117 "\n" 118 "layout(points) in;\n" 119 "layout(points, max_vertices=1) out;\n" 120 "\n" 121 "// definition of NUMBER_OF_UNIFORMS goes here\n"; 122 123const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_geometry_shader_code_number_of_uniforms = 124 "#define NUMBER_OF_UNIFORM_BLOCKS "; 125 126const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_geometry_shader_code_body_str = 127 "u\n" 128 "\n" 129 "layout(binding = 0) uniform UniformBlock\n" 130 "{\n" 131 " int entry;\n" 132 "} uni_block_array[NUMBER_OF_UNIFORM_BLOCKS];\n" 133 "\n" 134 "flat out int gs_out_sum;\n" 135 "\n" 136 "void main()\n" 137 "{\n" 138 " gs_out_sum = 0;\n" 139 "\n"; 140 141const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_geometry_shader_code_body_end = "\n" 142 " EmitVertex();\n" 143 "\n" 144 " EndPrimitive();\n" 145 "}\n"; 146 147/* Fragment Shader for GeometryShaderMaxUniformBlocksTest */ 148const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_fragment_shader_code = 149 "${VERSION}\n" 150 "${GEOMETRY_SHADER_REQUIRE}\n" 151 "precision mediump float;\n" 152 "out vec4 fs_out_color;\n" 153 "void main()\n" 154 "{\n" 155 " fs_out_color = vec4(1, 1, 1, 1);\n" 156 "}\n"; 157 158/** ****************************************************************************************** **/ 159/* Vertex Shader for GeometryShaderMaxInputComponentsTest */ 160const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_vertex_shader_code_preamble = 161 "${VERSION}\n" 162 "\n" 163 "${GEOMETRY_SHADER_REQUIRE}\n" 164 "\n" 165 "// definition of NUMBER_OF_GEOMETRY_INPUT_VECTORS\n"; 166 167const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_vertex_shader_code_number_of_uniforms = 168 "#define NUMBER_OF_GEOMETRY_INPUT_VECTORS "; 169 170const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_vertex_shader_code_body = 171 "u\n" 172 "\n" 173 "out Vertex\n" 174 "{" 175 " flat out ivec4 vs_gs_out[NUMBER_OF_GEOMETRY_INPUT_VECTORS];\n" 176 "};\n" 177 "\n" 178 "void main()\n" 179 "{\n" 180 " int index = 1;\n" 181 "\n" 182 " for (uint i = 0u; i < NUMBER_OF_GEOMETRY_INPUT_VECTORS; ++i)\n" 183 " {\n" 184 " vs_gs_out[i] = ivec4(index, index + 1, index + 2, index + 3);\n" 185 " index += 4;\n" 186 " }\n" 187 "}\n"; 188 189/* Geometry Shader Parts for GeometryShaderMaxInputComponentsTest */ 190const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_geometry_shader_code_preamble = 191 "${VERSION}\n" 192 "\n" 193 "${GEOMETRY_SHADER_REQUIRE}\n" 194 "\n" 195 "layout(points) in;\n" 196 "layout(points, max_vertices=1) out;\n" 197 "\n" 198 "// definition of NUMBER_OF_GEOMETRY_INPUT_VECTORS goes here\n"; 199 200const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_geometry_shader_code_number_of_uniforms = 201 "#define NUMBER_OF_GEOMETRY_INPUT_VECTORS "; 202 203const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_geometry_shader_code_body = 204 "u\n" 205 "\n" 206 "in Vertex\n" 207 "{\n" 208 " flat in ivec4 vs_gs_out[NUMBER_OF_GEOMETRY_INPUT_VECTORS];\n" 209 "} vertex[1];\n" 210 "\n" 211 "flat out int gs_out_sum;\n" 212 "\n" 213 "void main()\n" 214 "{\n" 215 " gs_out_sum = 0;\n" 216 "\n" 217 " for (uint i = 0u; i < NUMBER_OF_GEOMETRY_INPUT_VECTORS; ++i)\n" 218 " {\n" 219 " gs_out_sum += vertex[0].vs_gs_out[i].x;\n" 220 " gs_out_sum += vertex[0].vs_gs_out[i].y;\n" 221 " gs_out_sum += vertex[0].vs_gs_out[i].z;\n" 222 " gs_out_sum += vertex[0].vs_gs_out[i].w;\n" 223 " }\n" 224 " EmitVertex();\n" 225 " \n" 226 " EndPrimitive();\n" 227 "}\n"; 228 229/* Fragment Shader for GeometryShaderMaxInputComponentsTest */ 230const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_fragment_shader_code = 231 "${VERSION}\n" 232 "${GEOMETRY_SHADER_REQUIRE}\n" 233 "precision mediump float;\n" 234 "out vec4 fs_out_color;\n" 235 "void main()\n" 236 "{\n" 237 " fs_out_color = vec4(1, 1, 1, 1);\n" 238 "}\n"; 239 240/** **************************************************************************************************/ 241/* Common shader parts for GeometryShaderMaxOutputComponentsTest */ 242const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_common_shader_code_gs_fs_out = "gs_fs_out_"; 243 244const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_common_shader_code_number_of_points = 245 "#define NUMBER_OF_POINTS "; 246 247const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_common_shader_code_gs_fs_out_definitions = 248 "// definitions of gs_fs_out_ varyings go here\n"; 249 250/* Vertex Shader for GeometryShaderMaxOutputComponentsTest */ 251const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_vertex_shader_code = 252 "${VERSION}\n" 253 "\n" 254 "${GEOMETRY_SHADER_REQUIRE}\n" 255 "\n" 256 "void main()\n" 257 "{\n" 258 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n" 259 "}\n"; 260 261/* Geometry Shader Parts for GeometryShaderMaxOutputComponentsTest */ 262const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_geometry_shader_code_preamble = 263 "${VERSION}\n" 264 "\n" 265 "${GEOMETRY_SHADER_REQUIRE}\n" 266 "${GEOMETRY_POINT_SIZE_ENABLE}\n" 267 "\n" 268 "// definition of NUMBER_OF_POINTS goes here\n"; 269 270const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_geometry_shader_code_layout = 271 "u\n" 272 "\n" 273 "layout(points) in;\n" 274 "layout(points, max_vertices=NUMBER_OF_POINTS) out;\n" 275 "\n"; 276 277const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_geometry_shader_code_flat_out_ivec4 = 278 "flat out ivec4"; 279 280const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_geometry_shader_code_assignment = 281 " = ivec4(index++, index++, index++, index++);\n"; 282 283const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_geometry_shader_code_body_begin = 284 "\n" 285 "void main()\n" 286 "{\n" 287 " int index = 1;\n" 288 "\n" 289 " for (uint point = 0u; point < NUMBER_OF_POINTS; ++point)\n" 290 " {\n" 291 " // gs_fs_out assignments go here\n"; 292 293const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_geometry_shader_code_body_end = 294 "\n" 295 " gl_PointSize = 2.0;\n" 296 " gl_Position = vec4(-1.0 + ((2.0 / float(NUMBER_OF_POINTS)) * float(point)) + (1.0 / " 297 "float(NUMBER_OF_POINTS)), 0.0, 0.0, 1.0);\n" 298 "\n" 299 " EmitVertex();\n" 300 " EndPrimitive();\n" 301 " }\n" 302 "}\n"; 303 304/* Fragment Shader for GeometryShaderMaxOutputComponentsTest */ 305const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_fragment_shader_code_preamble = 306 "${VERSION}\n" 307 "\n" 308 "${GEOMETRY_SHADER_REQUIRE}\n" 309 "precision highp int;\n" 310 "\n"; 311 312const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_fragment_shader_code_flat_in_ivec4 = "flat in ivec4"; 313 314const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_fragment_shader_code_sum = "sum += "; 315 316const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_fragment_shader_code_body_begin = 317 "\n" 318 "layout(location = 0) out int fs_out;\n" 319 "\n" 320 "void main()\n" 321 "{\n" 322 " int sum = 0;\n" 323 "\n" 324 " // sum calculation go here\n"; 325 326const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_fragment_shader_code_body_end = "\n" 327 " fs_out = sum;\n" 328 "}\n"; 329 330/** ******************************************************************************************* **/ 331/* Vertex Shader for GeometryShaderMaxOutputVerticesTest */ 332const glw::GLchar* const GeometryShaderMaxOutputVerticesTest::m_vertex_shader_code = 333 "${VERSION}\n" 334 "\n" 335 "${GEOMETRY_SHADER_REQUIRE}\n" 336 "\n" 337 "void main()\n" 338 "{\n" 339 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n" 340 "}\n"; 341 342/* Geometry Shader for GeometryShaderMaxOutputVerticesTest */ 343const glw::GLchar* const GeometryShaderMaxOutputVerticesTest::m_geometry_shader_code_preamble = 344 "${VERSION}\n" 345 "\n" 346 "${GEOMETRY_SHADER_REQUIRE}\n" 347 "\n" 348 "// definition of NUMBER_OF_POINTS goes here\n" 349 "#define NUMBER_OF_POINTS "; 350 351const glw::GLchar* const GeometryShaderMaxOutputVerticesTest::m_geometry_shader_code_body = 352 "u\n" 353 "\n" 354 "layout(points) in;\n" 355 "layout(points, max_vertices=NUMBER_OF_POINTS) out;\n" 356 "\n" 357 "void main()\n" 358 "{\n" 359 " int index = 0;\n" 360 "\n" 361 " for (uint point = 0u; point < NUMBER_OF_POINTS; ++point)\n" 362 " {\n" 363 " EmitVertex();\n" 364 " EndPrimitive();\n" 365 " }\n" 366 "\n" 367 "}\n"; 368 369/* Fragment Shader for GeometryShaderMaxOutputVerticesTest */ 370const glw::GLchar* const GeometryShaderMaxOutputVerticesTest::m_fragment_shader_code = 371 "${VERSION}\n" 372 "\n" 373 "${GEOMETRY_SHADER_REQUIRE}\n" 374 "\n" 375 "precision highp float;\n" 376 "\n" 377 "layout(location = 0) out vec4 fs_out;\n" 378 "\n" 379 "void main()\n" 380 "{\n" 381 " fs_out = vec4(1, 1, 1, 1);\n" 382 "}\n"; 383 384/** ***************************************************************************************************************** **/ 385/* Common shader parts for GeometryShaderMaxOutputComponentsSinglePointTest */ 386const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_common_shader_code_gs_fs_out = 387 "gs_fs_out_"; 388 389const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_common_shader_code_gs_fs_out_definitions = 390 "// definitions of gs_fs_out_ varyings go here\n"; 391 392/* Vertex Shader for GeometryShaderMaxOutputComponentsSinglePointTest */ 393const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_vertex_shader_code = 394 "${VERSION}\n" 395 "\n" 396 "${GEOMETRY_SHADER_REQUIRE}\n" 397 "\n" 398 "void main()\n" 399 "{\n" 400 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n" 401 "}\n"; 402 403/* Geometry Shader Parts for GeometryShaderMaxOutputComponentsSinglePointTest */ 404const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_geometry_shader_code_preamble = 405 "${VERSION}\n" 406 "\n" 407 "${GEOMETRY_SHADER_REQUIRE}\n" 408 "${GEOMETRY_POINT_SIZE_ENABLE}\n" 409 "\n" 410 "layout(points) in;\n" 411 "layout(points, max_vertices=1) out;\n" 412 "\n"; 413 414const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_geometry_shader_code_flat_out_ivec4 = 415 "flat out ivec4"; 416 417const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_geometry_shader_code_assignment = 418 " = ivec4(index++, index++, index++, index++);\n"; 419 420const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_geometry_shader_code_body_begin = 421 "\n" 422 "void main()\n" 423 "{\n" 424 " int index = 1;\n" 425 "\n" 426 " // gs_fs_out assignments go here\n"; 427 428const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_geometry_shader_code_body_end = 429 "\n" 430 " gl_PointSize = 2.0;\n" 431 " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n" 432 "\n" 433 " EmitVertex();\n" 434 " EndPrimitive();\n" 435 "}\n"; 436 437/* Fragment Shader for GeometryShaderMaxOutputComponentsSinglePointTest */ 438const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_fragment_shader_code_preamble = 439 "${VERSION}\n" 440 "\n" 441 "${GEOMETRY_SHADER_REQUIRE}\n" 442 "\n"; 443 444const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_fragment_shader_code_flat_in_ivec4 = 445 "flat in ivec4"; 446 447const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_fragment_shader_code_sum = "sum += "; 448 449const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_fragment_shader_code_body_begin = 450 "\n" 451 "layout(location = 0) out int fs_out;\n" 452 "\n" 453 "void main()\n" 454 "{\n" 455 " int sum = 0;\n" 456 "\n" 457 " // sum calculation go here\n"; 458 459const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_fragment_shader_code_body_end = 460 "\n" 461 " fs_out = sum;\n" 462 "}\n"; 463 464/** ******************************************************************************************************************** **/ 465/* Vertex Shader for GeometryShaderMaxTextureUnitsTest */ 466const glw::GLchar* const GeometryShaderMaxTextureUnitsTest::m_vertex_shader_code_preamble = 467 "${VERSION}\n" 468 "\n" 469 "${GEOMETRY_SHADER_REQUIRE}\n" 470 "\n" 471 "precision highp float;\n" 472 "\n" 473 "#define NUMBER_OF_POINTS "; 474 475const glw::GLchar* const GeometryShaderMaxTextureUnitsTest::m_vertex_shader_code_body = 476 "u\n" 477 "\n" 478 "flat out int vs_gs_vertex_id;\n" 479 "\n" 480 "void main()\n" 481 "{\n" 482 " gl_Position = vec4(-1.0 + ((2.0 / float(NUMBER_OF_POINTS)) * float(gl_VertexID)) + (1.0 / " 483 "float(NUMBER_OF_POINTS)), 0, 0, 1.0);\n" 484 " vs_gs_vertex_id = gl_VertexID;\n" 485 "}\n"; 486 487/* Geometry Shader for GeometryShaderMaxTextureUnitsTest */ 488const glw::GLchar* const GeometryShaderMaxTextureUnitsTest::m_geometry_shader_code_preamble = 489 "${VERSION}\n" 490 "\n" 491 "${GEOMETRY_SHADER_REQUIRE}\n" 492 "${GEOMETRY_POINT_SIZE_ENABLE}\n" 493 "${GPU_SHADER5_REQUIRE}\n" 494 "\n" 495 "precision highp float;\n" 496 "\n" 497 "layout(points) in;\n" 498 "layout(triangle_strip, max_vertices = 4) out;\n" 499 "\n" 500 "#define NUMBER_OF_POINTS "; 501 502const glw::GLchar* const GeometryShaderMaxTextureUnitsTest::m_geometry_shader_code_body = 503 "u\n" 504 "\n" 505 "// NUMBER_OF_POINTS == NUMBER_OF_SAMPLERS\n" 506 " uniform lowp isampler2D gs_texture[NUMBER_OF_POINTS];\n" 507 "flat in int vs_gs_vertex_id[1];\n" 508 "flat out int gs_fs_color;\n" 509 "\n" 510 "void main()\n" 511 "{\n" 512 " float half_of_edge = (1.0 / float(NUMBER_OF_POINTS));\n" 513 " int color = 0;\n" 514 "\n" 515 " for (uint i = 0u; i <= uint(vs_gs_vertex_id[0]); ++i)\n" 516 " {\n" 517 " color += texture(gs_texture[i], vec2(0.0, 0.0)).r;\n" 518 " }\n" 519 "\n" 520 " gl_Position = gl_in[0].gl_Position + vec4(-half_of_edge, 1.0, 0, 0);\n" 521 " gs_fs_color = color;\n" 522 " EmitVertex();\n" 523 "\n" 524 " gl_Position = gl_in[0].gl_Position + vec4( half_of_edge, 1.0, 0, 0);\n" 525 " gs_fs_color = color;\n" 526 " EmitVertex();\n" 527 "\n" 528 " gl_Position = gl_in[0].gl_Position + vec4(-half_of_edge, -1.0, 0, 0);\n" 529 " gs_fs_color = color;\n" 530 " EmitVertex();\n" 531 "\n" 532 " gl_Position = gl_in[0].gl_Position + vec4( half_of_edge, -1.0, 0, 0);\n" 533 " gs_fs_color = color;\n" 534 " EmitVertex();\n" 535 " EndPrimitive();\n" 536 "}\n"; 537 538/* Fragment Shader for GeometryShaderMaxTextureUnitsTest */ 539const glw::GLchar* const GeometryShaderMaxTextureUnitsTest::m_fragment_shader_code = 540 "${VERSION}\n" 541 "\n" 542 "${GEOMETRY_SHADER_REQUIRE}\n" 543 "\n" 544 "precision highp float;\n" 545 "\n" 546 "flat in int gs_fs_color;\n" 547 "layout(location = 0) out int fs_out_color;\n" 548 "\n" 549 "void main()\n" 550 "{\n" 551 " fs_out_color = gs_fs_color;\n" 552 "}\n"; 553 554/** *******************************************************************************************************/ 555/* Vertex Shader for GeometryShaderMaxInvocationsTest */ 556const glw::GLchar* const GeometryShaderMaxInvocationsTest::m_vertex_shader_code = 557 "${VERSION}\n" 558 "\n" 559 "${GEOMETRY_SHADER_REQUIRE}\n" 560 "\n" 561 "precision highp float;\n" 562 "\n" 563 "void main()\n" 564 "{\n" 565 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n" 566 "}\n"; 567 568/* Geometry Shader for GeometryShaderMaxInvocationsTest */ 569const glw::GLchar* const GeometryShaderMaxInvocationsTest::m_geometry_shader_code_preamble = 570 "${VERSION}\n" 571 "\n" 572 "${GEOMETRY_SHADER_REQUIRE}\n" 573 "\n" 574 "precision highp float;\n" 575 "\n" 576 "#define GEOMETRY_SHADER_INVOCATIONS "; 577 578const glw::GLchar* const GeometryShaderMaxInvocationsTest::m_geometry_shader_code_layout = 579 "u\n" 580 "\n" 581 "layout(points) in;\n" 582 "layout(triangle_strip, max_vertices = 3) out;\n"; 583 584const glw::GLchar* const GeometryShaderMaxInvocationsTest::m_geometry_shader_code_layout_invocations = 585 "layout(invocations = GEOMETRY_SHADER_INVOCATIONS) in;\n"; 586 587const glw::GLchar* const GeometryShaderMaxInvocationsTest::m_geometry_shader_code_body = 588 "\n" 589 "void main()\n" 590 "{\n" 591 " float dx = (2.0 / float(GEOMETRY_SHADER_INVOCATIONS));\n" 592 " \n" 593 " gl_Position = vec4(-1.0 + (dx * float(gl_InvocationID)), -1.001, 0.0, 1.0);\n" 594 " EmitVertex();\n" 595 " \n" 596 " gl_Position = vec4(-1.0 + (dx * float(gl_InvocationID)), 1.001, 0.0, 1.0);\n" 597 " EmitVertex();\n" 598 " \n" 599 " gl_Position = vec4(-1.0 + (dx * float(gl_InvocationID + 1)), 1.001, 0.0, 1.0);\n" 600 " EmitVertex();\n" 601 "}\n"; 602 603/* Fragment Shader for GeometryShaderMaxInvocationsTest */ 604const glw::GLchar* const GeometryShaderMaxInvocationsTest::m_fragment_shader_code = 605 "${VERSION}\n" 606 "\n" 607 "${GEOMETRY_SHADER_REQUIRE}\n" 608 "\n" 609 "precision highp float;\n" 610 "\n" 611 "layout(location = 0) out vec4 fs_out_color;\n" 612 "\n" 613 "void main()\n" 614 "{\n" 615 " fs_out_color = vec4(0.0, 1.0, 0.0, 0.0);\n" 616 "}\n"; 617 618/** ***************************************************************************************************** **/ 619/* Vertex Shader for GeometryShaderMaxCombinedTextureUnitsTest */ 620const glw::GLchar* const GeometryShaderMaxCombinedTextureUnitsTest::m_vertex_shader_code_preamble = 621 "${VERSION}\n" 622 "\n" 623 "${GEOMETRY_SHADER_REQUIRE}\n" 624 "${GPU_SHADER5_ENABLE}\n" 625 "\n" 626 "precision highp float;\n" 627 "\n" 628 "#define NUMBER_OF_POINTS "; 629 630const glw::GLchar* const GeometryShaderMaxCombinedTextureUnitsTest::m_vertex_shader_code_body = 631 "u\n" 632 "\n" 633 "// NUMBER_OF_POINTS == NUMBER_OF_SAMPLERS\n" 634 " uniform highp usampler2D sampler[NUMBER_OF_POINTS];" 635 "flat out int vs_gs_vertex_id;\n" 636 "flat out uint vs_gs_sum;\n" 637 "\n" 638 "void main()\n" 639 "{\n" 640 " uint sum = 0u;\n" 641 "\n" 642 " for (uint i = 0u; i < uint(gl_VertexID); ++i)\n" 643 " {\n" 644 " sum += texture(sampler[i], vec2(0.0, 0.0)).r;\n" 645 " }\n" 646 "\n" 647 " gl_Position = vec4(-1.0 + ((2.0 / float(NUMBER_OF_POINTS)) * float(gl_VertexID)) + (1.0 / " 648 "float(NUMBER_OF_POINTS)), 0, 0, 1.0);\n" 649 " vs_gs_vertex_id = gl_VertexID;\n" 650 " vs_gs_sum = sum;\n" 651 "}\n"; 652 653/* Geometry Shader for GeometryShaderMaxCombinedTextureUnitsTest */ 654const glw::GLchar* const GeometryShaderMaxCombinedTextureUnitsTest::m_geometry_shader_code_preamble = 655 "${VERSION}\n" 656 "\n" 657 "${GEOMETRY_SHADER_REQUIRE}\n" 658 "${GPU_SHADER5_ENABLE}\n" 659 "\n" 660 "precision highp float;\n" 661 "\n" 662 "layout(points) in;\n" 663 "layout(points, max_vertices = 1) out;\n" 664 "\n" 665 "#define NUMBER_OF_POINTS "; 666 667const glw::GLchar* const GeometryShaderMaxCombinedTextureUnitsTest::m_geometry_shader_code_body = 668 "u\n" 669 "\n" 670 "// NUMBER_OF_POINTS == NUMBER_OF_SAMPLERS\n" 671 " uniform highp usampler2D sampler[NUMBER_OF_POINTS];\n" 672 "flat in int vs_gs_vertex_id[1];\n" 673 "flat in uint vs_gs_sum [1];\n" 674 "flat out int gs_fs_vertex_id;\n" 675 "flat out uint gs_fs_vertex_sum;\n" 676 "flat out uint gs_fs_geometry_sum;\n" 677 "\n" 678 "void main()\n" 679 "{\n" 680 " uint sum = 0u;\n" 681 "\n" 682 " for (uint i = 0u; i < uint(vs_gs_vertex_id[0]); ++i)\n" 683 " {\n" 684 " sum += texture(sampler[i], vec2(0.0, 0.0)).r;\n" 685 " }\n" 686 "\n" 687 " gl_Position = gl_in[0].gl_Position;\n" 688 " gs_fs_vertex_id = vs_gs_vertex_id[0];\n" 689 " gs_fs_vertex_sum = vs_gs_sum [0];\n" 690 " gs_fs_geometry_sum = sum;\n" 691 " EmitVertex();\n" 692 " EndPrimitive();\n" 693 "}\n"; 694 695/* Fragment Shader for GeometryShaderMaxCombinedTextureUnitsTest */ 696const glw::GLchar* const GeometryShaderMaxCombinedTextureUnitsTest::m_fragment_shader_code_preamble = 697 "${VERSION}\n" 698 "\n" 699 "${GEOMETRY_SHADER_REQUIRE}\n" 700 "${GPU_SHADER5_ENABLE}\n" 701 "\n" 702 "precision highp float;\n" 703 "\n" 704 "// NUMBER_OF_POINTS == NUMBER_OF_SAMPLERS\n" 705 "#define NUMBER_OF_POINTS "; 706 707const glw::GLchar* const GeometryShaderMaxCombinedTextureUnitsTest::m_fragment_shader_code_body = 708 "u\n" 709 "\n" 710 " uniform highp usampler2D sampler[NUMBER_OF_POINTS];\n" 711 "flat in int gs_fs_vertex_id;\n" 712 "flat in uint gs_fs_vertex_sum;\n" 713 "flat in uint gs_fs_geometry_sum;\n" 714 "layout(location = 0) out uint fs_out_color;\n" 715 "\n" 716 "void main()\n" 717 "{\n" 718 " uint sum = 0u;\n" 719 "\n" 720 " for (uint i = 0u; i < uint(gs_fs_vertex_id); ++i)\n" 721 " {\n" 722 " sum += texture(sampler[i], vec2(0.0, 0.0)).r;\n" 723 " }\n" 724 " fs_out_color = sum + gs_fs_vertex_sum + gs_fs_geometry_sum;\n" 725 "}\n"; 726 727/** ***************************************************************************************************************** **/ 728 729/* Constants for GeometryShaderMaxUniformComponentsTest */ 730const unsigned int GeometryShaderMaxUniformComponentsTest::m_buffer_size = sizeof(glw::GLint); 731const glw::GLchar* const GeometryShaderMaxUniformComponentsTest::m_captured_varyings_names = "gs_out_sum"; 732 733/* Constants for GeometryShaderMaxUniformBlocksTest */ 734const unsigned int GeometryShaderMaxUniformBlocksTest::m_buffer_size = sizeof(glw::GLint); 735const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_captured_varyings_names = "gs_out_sum"; 736 737/* Constants for GeometryShaderMaxInputComponentsTest */ 738const unsigned int GeometryShaderMaxInputComponentsTest::m_buffer_size = sizeof(glw::GLint); 739const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_captured_varyings_names = "gs_out_sum"; 740 741/* Constants for GeometryShaderMaxOutputComponentsTest */ 742const unsigned int GeometryShaderMaxOutputComponentsTest::m_point_size = 2; 743const unsigned int GeometryShaderMaxOutputComponentsTest::m_texture_height = m_point_size; 744const unsigned int GeometryShaderMaxOutputComponentsTest::m_texture_pixel_size = 4 * sizeof(glw::GLint); 745 746/* Constants for GeometryShaderMaxOutputComponentsSinglePointTest */ 747const unsigned int GeometryShaderMaxOutputComponentsSinglePointTest::m_point_size = 2; 748const unsigned int GeometryShaderMaxOutputComponentsSinglePointTest::m_texture_height = m_point_size; 749const unsigned int GeometryShaderMaxOutputComponentsSinglePointTest::m_texture_pixel_size = 4 * sizeof(glw::GLint); 750const unsigned int GeometryShaderMaxOutputComponentsSinglePointTest::m_texture_width = m_point_size; 751 752/* Constants for GeometryShaderMaxTextureUnitsTest */ 753const unsigned int GeometryShaderMaxTextureUnitsTest::m_point_size = 2; 754const unsigned int GeometryShaderMaxTextureUnitsTest::m_texture_height = m_point_size; 755const unsigned int GeometryShaderMaxTextureUnitsTest::m_texture_pixel_size = 4 * sizeof(glw::GLint); 756 757/* Constants for GeometryShaderMaxInvocationsTest */ 758const unsigned int GeometryShaderMaxInvocationsTest::m_triangle_edge_length = 9; 759const unsigned int GeometryShaderMaxInvocationsTest::m_texture_height = m_triangle_edge_length; 760const unsigned int GeometryShaderMaxInvocationsTest::m_texture_pixel_size = 4 * sizeof(glw::GLubyte); 761 762/* Constants for GeometryShaderMaxCombinedTextureUnitsTest */ 763const unsigned int GeometryShaderMaxCombinedTextureUnitsTest::m_point_size = 1; 764const unsigned int GeometryShaderMaxCombinedTextureUnitsTest::m_texture_height = m_point_size; 765const unsigned int GeometryShaderMaxCombinedTextureUnitsTest::m_texture_pixel_size = 4 * sizeof(glw::GLint); 766 767/** Constructor 768 * 769 * @param context Test context 770 * @param name Test case's name 771 * @param description Test case's description 772 **/ 773GeometryShaderLimitsTransformFeedbackBase::GeometryShaderLimitsTransformFeedbackBase(Context& context, 774 const ExtParameters& extParams, 775 const char* name, 776 const char* description) 777 : TestCaseBase(context, extParams, name, description) 778 , m_fragment_shader_id(0) 779 , m_geometry_shader_id(0) 780 , m_program_object_id(0) 781 , m_vertex_shader_id(0) 782 , m_buffer_object_id(0) 783 , m_vertex_array_object_id(0) 784 , m_fragment_shader_parts(0) 785 , m_geometry_shader_parts(0) 786 , m_vertex_shader_parts(0) 787 , m_n_fragment_shader_parts(0) 788 , m_n_geometry_shader_parts(0) 789 , m_n_vertex_shader_parts(0) 790 , m_captured_varyings_names(0) 791 , m_n_captured_varyings(0) 792 , m_buffer_size(0) 793{ 794 /* Nothing to be done here */ 795} 796 797/** Initializes GLES objects used during the test. 798 * 799 */ 800void GeometryShaderLimitsTransformFeedbackBase::initTest() 801{ 802 /* This test should only run if EXT_geometry_shader is supported */ 803 if (!m_is_geometry_shader_extension_supported) 804 { 805 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 806 } 807 808 /* Retrieve ES entrypoints */ 809 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 810 811 /* Get shaders code from child class */ 812 getShaderParts(m_fragment_shader_parts, m_n_fragment_shader_parts, m_geometry_shader_parts, 813 m_n_geometry_shader_parts, m_vertex_shader_parts, m_n_vertex_shader_parts); 814 815 /* Get captured varyings from inheriting class */ 816 getCapturedVaryings(m_captured_varyings_names, m_n_captured_varyings); 817 818 /* Create program and shaders */ 819 m_program_object_id = gl.createProgram(); 820 821 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 822 m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 823 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 824 825 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program or shader object(s)"); 826 827 /* Set up transform feedback */ 828 gl.transformFeedbackVaryings(m_program_object_id, m_n_captured_varyings, m_captured_varyings_names, 829 GL_INTERLEAVED_ATTRIBS); 830 831 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set transform feedback varyings"); 832 833 /* Build program */ 834 if (false == buildProgram(m_program_object_id, m_fragment_shader_id, m_n_fragment_shader_parts, 835 m_fragment_shader_parts, m_geometry_shader_id, m_n_geometry_shader_parts, 836 m_geometry_shader_parts, m_vertex_shader_id, m_n_vertex_shader_parts, 837 m_vertex_shader_parts)) 838 { 839 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 840 } 841 842 /* Generate and bind VAO */ 843 gl.genVertexArrays(1, &m_vertex_array_object_id); 844 gl.bindVertexArray(m_vertex_array_object_id); 845 846 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object"); 847 848 /* Get size of buffer used by transform feedback from child class */ 849 getTransformFeedbackBufferSize(m_buffer_size); 850 851 /* Generate, bind and allocate buffer */ 852 gl.genBuffers(1, &m_buffer_object_id); 853 gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id); 854 gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_COPY); 855 856 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object"); 857} 858 859/** Executes the test. 860 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 861 * 862 * Note the function throws exception should an error occur! 863 * 864 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 865 * 866 **/ 867tcu::TestCase::IterateResult GeometryShaderLimitsTransformFeedbackBase::iterate() 868{ 869 initTest(); 870 871 /* Retrieve ES entrypoints */ 872 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 873 874 /* Verification result */ 875 bool result = false; 876 877 /* Setup transform feedback */ 878 gl.enable(GL_RASTERIZER_DISCARD); 879 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed"); 880 881 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id); 882 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed"); 883 884 /* Setup draw call */ 885 gl.useProgram(m_program_object_id); 886 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program"); 887 888 gl.beginTransformFeedback(GL_POINTS); 889 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed"); 890 { 891 /* Let child class prepare input data */ 892 prepareProgramInput(); 893 894 /* Draw */ 895 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* one point */); 896 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed"); 897 } 898 /* Stop transform feedback */ 899 gl.endTransformFeedback(); 900 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed"); 901 902 /* Map transfrom feedback results */ 903 const void* transform_feedback_data = 904 gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, m_buffer_size, GL_MAP_READ_BIT); 905 906 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space"); 907 908 /* Verify data extracted from transfrom feedback */ 909 result = verifyResult(transform_feedback_data); 910 911 /* Unmap transform feedback buffer */ 912 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 913 GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object"); 914 915 /* Let child class clean itself */ 916 clean(); 917 918 /* Verify results */ 919 if (true != result) 920 { 921 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 922 } 923 else 924 { 925 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 926 } 927 928 return STOP; 929} 930 931/** Deinitializes GLES objects created during the test. 932 * 933 */ 934void GeometryShaderLimitsTransformFeedbackBase::deinit() 935{ 936 /* Retrieve ES entrypoints */ 937 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 938 939 /* Bind default values */ 940 gl.useProgram(0); 941 gl.bindVertexArray(0); 942 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */); 943 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 944 945 /* Delete program object and shaders */ 946 if (0 != m_program_object_id) 947 { 948 gl.deleteProgram(m_program_object_id); 949 950 m_program_object_id = 0; 951 } 952 953 if (0 != m_fragment_shader_id) 954 { 955 gl.deleteShader(m_fragment_shader_id); 956 957 m_fragment_shader_id = 0; 958 } 959 960 if (0 != m_geometry_shader_id) 961 { 962 gl.deleteShader(m_geometry_shader_id); 963 964 m_geometry_shader_id = 0; 965 } 966 967 if (0 != m_vertex_shader_id) 968 { 969 gl.deleteShader(m_vertex_shader_id); 970 971 m_vertex_shader_id = 0; 972 } 973 974 /* Delete buffer objects */ 975 if (0 != m_buffer_object_id) 976 { 977 gl.deleteBuffers(1, &m_buffer_object_id); 978 979 m_buffer_object_id = 0; 980 } 981 982 if (0 != m_vertex_array_object_id) 983 { 984 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 985 986 m_vertex_array_object_id = 0; 987 } 988 989 /* Deinitialize base class */ 990 TestCaseBase::deinit(); 991} 992 993/** Constructor 994 * 995 * @param context Test context 996 * @param name Test case's name 997 * @param description Test case's description 998 **/ 999GeometryShaderLimitsRenderingBase::GeometryShaderLimitsRenderingBase(Context& context, const ExtParameters& extParams, 1000 const char* name, const char* description) 1001 : TestCaseBase(context, extParams, name, description) 1002 , m_fragment_shader_id(0) 1003 , m_geometry_shader_id(0) 1004 , m_program_object_id(0) 1005 , m_vertex_shader_id(0) 1006 , m_framebuffer_object_id(0) 1007 , m_color_texture_id(0) 1008 , m_vertex_array_object_id(0) 1009 , m_fragment_shader_parts(0) 1010 , m_geometry_shader_parts(0) 1011 , m_vertex_shader_parts(0) 1012 , m_n_fragment_shader_parts(0) 1013 , m_n_geometry_shader_parts(0) 1014 , m_n_vertex_shader_parts(0) 1015 , m_texture_format(GL_RGBA8) 1016 , m_texture_height(0) 1017 , m_texture_pixel_size(0) 1018 , m_texture_read_format(GL_RGBA) 1019 , m_texture_read_type(GL_UNSIGNED_BYTE) 1020 , m_texture_width(0) 1021{ 1022 /* Nothing to be done here */ 1023} 1024 1025/** Initializes GLES objects used during the test. 1026 * 1027 */ 1028void GeometryShaderLimitsRenderingBase::initTest() 1029{ 1030 /* This test should only run if EXT_geometry_shader is supported */ 1031 if (!m_is_geometry_shader_extension_supported) 1032 { 1033 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 1034 } 1035 1036 /* Query on support of EXT_gpu_shader5 */ 1037 if (!m_is_gpu_shader5_supported) 1038 { 1039 throw tcu::NotSupportedError(GPU_SHADER5_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 1040 } 1041 1042 /* Retrieve ES entry-points */ 1043 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1044 1045 /* Verify that point size range is supported */ 1046 glw::GLfloat point_size_range[2] = { 0 }; 1047 glw::GLfloat required_point_size = 0.0f; 1048 1049 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1050 { 1051 gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range); 1052 } 1053 else 1054 { 1055 gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range); 1056 } 1057 1058 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() call failed"); 1059 1060 getRequiredPointSize(required_point_size); 1061 1062 if (required_point_size > point_size_range[1]) 1063 { 1064 m_testCtx.getLog() << tcu::TestLog::Message 1065 << "Test requires a minimum maximum point size of: " << required_point_size 1066 << ", implementation reports a maximum of : " << point_size_range[1] 1067 << tcu::TestLog::EndMessage; 1068 1069 throw tcu::NotSupportedError("Required point size is not supported", "", __FILE__, __LINE__); 1070 } 1071 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1072 { 1073 gl.enable(GL_PROGRAM_POINT_SIZE); 1074 } 1075 1076 /* Get shaders code from child class */ 1077 getShaderParts(m_fragment_shader_parts, m_n_fragment_shader_parts, m_geometry_shader_parts, 1078 m_n_geometry_shader_parts, m_vertex_shader_parts, m_n_vertex_shader_parts); 1079 1080 /* Create program and shaders */ 1081 m_program_object_id = gl.createProgram(); 1082 1083 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 1084 m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 1085 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 1086 1087 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program or shader object(s)"); 1088 1089 /* Build program */ 1090 if (false == buildProgram(m_program_object_id, m_fragment_shader_id, m_n_fragment_shader_parts, 1091 m_fragment_shader_parts, m_geometry_shader_id, m_n_geometry_shader_parts, 1092 m_geometry_shader_parts, m_vertex_shader_id, m_n_vertex_shader_parts, 1093 m_vertex_shader_parts)) 1094 { 1095 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 1096 } 1097 1098 /* Set up a vertex array object */ 1099 gl.genVertexArrays(1, &m_vertex_array_object_id); 1100 gl.bindVertexArray(m_vertex_array_object_id); 1101 1102 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object"); 1103 1104 /* Get framebuffer details */ 1105 getFramebufferDetails(m_texture_format, m_texture_read_format, m_texture_read_type, m_texture_width, 1106 m_texture_height, m_texture_pixel_size); 1107 1108 /* Set up texture object and a FBO */ 1109 gl.genTextures(1, &m_color_texture_id); 1110 gl.genFramebuffers(1, &m_framebuffer_object_id); 1111 1112 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer"); 1113 1114 if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, m_texture_format, 1115 m_texture_width, m_texture_height)) 1116 { 1117 TCU_FAIL("Failed to setup framebuffer"); 1118 } 1119} 1120 1121/** Executes the test. 1122 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 1123 * 1124 * Note the function throws exception should an error occur! 1125 * 1126 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 1127 * 1128 **/ 1129tcu::TestCase::IterateResult GeometryShaderLimitsRenderingBase::iterate() 1130{ 1131 initTest(); 1132 1133 /* Retrieve ES entry-points */ 1134 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1135 1136 /* Variables used for image verification purposes */ 1137 std::vector<unsigned char> result_image(m_texture_width * m_texture_height * m_texture_pixel_size); 1138 1139 /* Render */ 1140 gl.useProgram(m_program_object_id); 1141 1142 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program"); 1143 1144 /* Let child class prepare input for program */ 1145 prepareProgramInput(); 1146 1147 gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */); 1148 gl.clear(GL_COLOR_BUFFER_BIT); 1149 1150 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer"); 1151 1152 /* Get draw call details from child class */ 1153 glw::GLenum primitive_type = GL_POINTS; 1154 glw::GLuint n_vertices = 1; 1155 1156 getDrawCallDetails(primitive_type, n_vertices); 1157 1158 gl.drawArrays(primitive_type, 0 /* first */, n_vertices); 1159 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed"); 1160 1161 /* Extract image from FBO */ 1162 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, m_texture_read_format, m_texture_read_type, 1163 &result_image[0]); 1164 1165 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer"); 1166 1167 /* Run verification */ 1168 if (true == verifyResult(&result_image[0])) 1169 { 1170 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1171 } 1172 else 1173 { 1174 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1175 } 1176 1177 /* Let child class clean itself */ 1178 clean(); 1179 1180 return STOP; 1181} 1182 1183/** Deinitializes GLES objects created during the test. 1184 * 1185 */ 1186void GeometryShaderLimitsRenderingBase::deinit() 1187{ 1188 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1189 1190 /* Reset OpenGL ES state */ 1191 gl.useProgram(0); 1192 gl.bindVertexArray(0); 1193 gl.bindTexture(GL_TEXTURE_2D, 0); 1194 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1195 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1196 { 1197 gl.disable(GL_PROGRAM_POINT_SIZE); 1198 } 1199 1200 /* Delete program object and shaders */ 1201 if (m_program_object_id != 0) 1202 { 1203 gl.deleteProgram(m_program_object_id); 1204 1205 m_program_object_id = 0; 1206 } 1207 1208 if (m_fragment_shader_id != 0) 1209 { 1210 gl.deleteShader(m_fragment_shader_id); 1211 1212 m_fragment_shader_id = 0; 1213 } 1214 1215 if (m_geometry_shader_id != 0) 1216 { 1217 gl.deleteShader(m_geometry_shader_id); 1218 1219 m_geometry_shader_id = 0; 1220 } 1221 1222 if (m_vertex_shader_id != 0) 1223 { 1224 gl.deleteShader(m_vertex_shader_id); 1225 1226 m_vertex_shader_id = 0; 1227 } 1228 1229 /* Delete frambuffer and textures */ 1230 if (m_framebuffer_object_id != 0) 1231 { 1232 gl.deleteFramebuffers(1, &m_framebuffer_object_id); 1233 1234 m_framebuffer_object_id = 0; 1235 } 1236 1237 if (m_color_texture_id != 0) 1238 { 1239 gl.deleteTextures(1, &m_color_texture_id); 1240 1241 m_color_texture_id = 0; 1242 } 1243 1244 if (m_vertex_array_object_id != 0) 1245 { 1246 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 1247 1248 m_vertex_array_object_id = 0; 1249 } 1250 1251 /* Deinitialize base class */ 1252 TestCaseBase::deinit(); 1253} 1254 1255/** Constructor 1256 * 1257 * @param context Test context 1258 * @param name Test case's name 1259 * @param description Test case's description 1260 **/ 1261GeometryShaderMaxUniformComponentsTest::GeometryShaderMaxUniformComponentsTest(Context& context, 1262 const ExtParameters& extParams, 1263 const char* name, 1264 const char* description) 1265 : GeometryShaderLimitsTransformFeedbackBase(context, extParams, name, description) 1266 , m_max_uniform_components(0) 1267 , m_max_uniform_vectors(0) 1268 , m_uniform_location(0) 1269{ 1270 /* Nothing to be done here */ 1271} 1272 1273/** Clears data after draw call and result verification 1274 * 1275 **/ 1276void GeometryShaderMaxUniformComponentsTest::clean() 1277{ 1278 m_uniform_data.clear(); 1279} 1280 1281/** Get names and number of varyings to be captured by transform feedback 1282 * 1283 * @param out_captured_varyings_names Array of varying names 1284 * @param out_n_captured_varyings Number of varying names 1285 **/ 1286void GeometryShaderMaxUniformComponentsTest::getCapturedVaryings(const glw::GLchar* const*& out_captured_varyings_names, 1287 glw::GLuint& out_n_captured_varyings) 1288{ 1289 /* Varying names */ 1290 out_captured_varyings_names = &m_captured_varyings_names; 1291 1292 /* Number of varyings */ 1293 out_n_captured_varyings = 1; 1294} 1295 1296/** Get parts of shaders 1297 * 1298 * @param out_fragment_shader_parts Array of fragment shader parts 1299 * @param out_n_fragment_shader_parts Number of fragment shader parts 1300 * @param out_geometry_shader_parts Array of geometry shader parts 1301 * @param out_n_geometry_shader_parts Number of geometry shader parts 1302 * @param out_vertex_shader_parts Array of vertex shader parts 1303 * @param out_n_vertex_shader_parts Number of vertex shader parts 1304 **/ 1305void GeometryShaderMaxUniformComponentsTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 1306 unsigned int& out_n_fragment_shader_parts, 1307 const glw::GLchar* const*& out_geometry_shader_parts, 1308 unsigned int& out_n_geometry_shader_parts, 1309 const glw::GLchar* const*& out_vertex_shader_parts, 1310 unsigned int& out_n_vertex_shader_parts) 1311{ 1312 /* Retrieve ES entry-points */ 1313 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1314 1315 /* Fragment Shader */ 1316 out_fragment_shader_parts = &m_fragment_shader_code; 1317 out_n_fragment_shader_parts = 1; 1318 1319 /* Get maximum number of uniform */ 1320 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_COMPONENTS, &m_max_uniform_components); 1321 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT pname."); 1322 1323 m_max_uniform_vectors = m_max_uniform_components / 4 /* 4 components per vector */; 1324 1325 std::stringstream stream; 1326 stream << m_max_uniform_vectors; 1327 m_max_uniform_vectors_string = stream.str(); 1328 1329 /* Geometry Shader */ 1330 m_geometry_shader_parts[0] = m_geometry_shader_code_preamble; 1331 m_geometry_shader_parts[1] = m_geometry_shader_code_number_of_uniforms; 1332 m_geometry_shader_parts[2] = m_max_uniform_vectors_string.c_str(); 1333 m_geometry_shader_parts[3] = m_geometry_shader_code_body; 1334 1335 out_geometry_shader_parts = m_geometry_shader_parts; 1336 out_n_geometry_shader_parts = 4; 1337 1338 /* Vertex Shader */ 1339 out_vertex_shader_parts = &m_vertex_shader_code; 1340 out_n_vertex_shader_parts = 1; 1341} 1342 1343/** Get size of buffer used by transform feedback 1344 * 1345 * @param out_buffer_size Size of buffer in bytes 1346 **/ 1347void GeometryShaderMaxUniformComponentsTest::getTransformFeedbackBufferSize(unsigned int& out_buffer_size) 1348{ 1349 out_buffer_size = m_buffer_size; 1350} 1351 1352/** Prepare test specific program input for draw call 1353 * 1354 **/ 1355void GeometryShaderMaxUniformComponentsTest::prepareProgramInput() 1356{ 1357 /* Retrieve ES entry-points */ 1358 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1359 1360 /* Uniform location */ 1361 m_uniform_location = gl.getUniformLocation(m_program_object_id, "uni_array"); 1362 1363 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get uniform location"); 1364 1365 if (-1 == m_uniform_location) 1366 { 1367 TCU_FAIL("Invalid uniform location"); 1368 } 1369 1370 /* 3. Configure the uniforms to use subsequently increasing values, starting 1371 * from 1 for R component of first vector, 2 for G component of that vector, 1372 * 5 for first component of second vector, and so on. 1373 **/ 1374 m_uniform_data.resize(m_max_uniform_components); 1375 1376 for (glw::GLint i = 0; i < m_max_uniform_components; ++i) 1377 { 1378 m_uniform_data[i] = i + 1; 1379 } 1380 1381 /* Set uniform data */ 1382 gl.uniform4iv(m_uniform_location, m_max_uniform_vectors, &m_uniform_data[0]); 1383 1384 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set uniform data"); 1385} 1386 1387/** Verification of results 1388 * 1389 * @param result Pointer to data mapped from transform feedback buffer. 1390 ( Size of data is equal to buffer_size set by getTransformFeedbackBufferSize() 1391 * 1392 * @return true Result matches expected value 1393 * false Result has wrong value 1394 **/ 1395bool GeometryShaderMaxUniformComponentsTest::verifyResult(const void* data) 1396{ 1397 /* Expected data, sum of elements in range <x;y> with length n = ((x + y) / 2) * n */ 1398 const glw::GLint expected_data = ((1 + m_max_uniform_components) * m_max_uniform_components) / 2; 1399 1400 /* Cast to const GLint */ 1401 const glw::GLint* transform_feedback_data = (const glw::GLint*)data; 1402 1403 /* Verify data extracted from transfrom feedback */ 1404 if (0 != memcmp(transform_feedback_data, &expected_data, m_buffer_size)) 1405 { 1406 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! Expected: " << expected_data 1407 << " Extracted: " << *transform_feedback_data << tcu::TestLog::EndMessage; 1408 1409 return false; 1410 } 1411 else 1412 { 1413 return true; 1414 } 1415} 1416 1417/** Constructor 1418 * 1419 * @param context Test context 1420 * @param name Test case's name 1421 * @param description Test case's description 1422 **/ 1423GeometryShaderMaxUniformBlocksTest::GeometryShaderMaxUniformBlocksTest(Context& context, const ExtParameters& extParams, 1424 const char* name, const char* description) 1425 : GeometryShaderLimitsTransformFeedbackBase(context, extParams, name, description), m_max_uniform_blocks(0) 1426{ 1427 /* Nothing to be done here */ 1428} 1429 1430/** Clears data after draw call and result verification 1431 * 1432 **/ 1433void GeometryShaderMaxUniformBlocksTest::clean() 1434{ 1435 /* Retrieve ES entry-points */ 1436 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1437 1438 /* Bind default to uniform binding point */ 1439 gl.bindBuffer(GL_UNIFORM_BUFFER, 0); 1440 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed"); 1441 1442 /* Release buffers */ 1443 for (glw::GLint i = 0; i < m_max_uniform_blocks; ++i) 1444 { 1445 /* Bind default to uniform block */ 1446 gl.bindBufferBase(GL_UNIFORM_BUFFER, i, 0); 1447 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed"); 1448 1449 /* Delete buffer */ 1450 gl.deleteBuffers(1, &m_uniform_blocks[i].buffer_object_id); 1451 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() call failed"); 1452 } 1453 1454 /* Free memory */ 1455 m_uniform_blocks.clear(); 1456} 1457 1458/** Get names and number of varyings to be captured by transform feedback 1459 * 1460 * @param out_captured_varyings_names Array of varying names 1461 * @param out_n_captured_varyings Number of varying names 1462 **/ 1463void GeometryShaderMaxUniformBlocksTest::getCapturedVaryings(const glw::GLchar* const*& out_captured_varyings_names, 1464 glw::GLuint& out_n_captured_varyings) 1465{ 1466 /* Varying names */ 1467 out_captured_varyings_names = &m_captured_varyings_names; 1468 1469 /* Number of varyings */ 1470 out_n_captured_varyings = 1; 1471} 1472 1473/** Get parts of shaders 1474 * 1475 * @param out_fragment_shader_parts Array of fragment shader parts 1476 * @param out_n_fragment_shader_parts Number of fragment shader parts 1477 * @param out_geometry_shader_parts Array of geometry shader parts 1478 * @param out_n_geometry_shader_parts Number of geometry shader parts 1479 * @param out_vertex_shader_parts Array of vertex shader parts 1480 * @param out_n_vertex_shader_parts Number of vertex shader parts 1481 **/ 1482void GeometryShaderMaxUniformBlocksTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 1483 unsigned int& out_n_fragment_shader_parts, 1484 const glw::GLchar* const*& out_geometry_shader_parts, 1485 unsigned int& out_n_geometry_shader_parts, 1486 const glw::GLchar* const*& out_vertex_shader_parts, 1487 unsigned int& out_n_vertex_shader_parts) 1488{ 1489 /* Retrieve ES entry-points */ 1490 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1491 1492 /* Fragment Shader */ 1493 out_fragment_shader_parts = &m_fragment_shader_code; 1494 out_n_fragment_shader_parts = 1; 1495 1496 /* Get maximum number of uniform blocks */ 1497 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_BLOCKS, &m_max_uniform_blocks); 1498 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT"); 1499 1500 std::stringstream stream; 1501 stream << m_max_uniform_blocks; 1502 m_max_uniform_blocks_string = stream.str(); 1503 1504 /* Geometry Shader */ 1505 m_geometry_shader_parts[0] = m_geometry_shader_code_preamble; 1506 m_geometry_shader_parts[1] = m_geometry_shader_code_number_of_uniforms; 1507 m_geometry_shader_parts[2] = m_max_uniform_blocks_string.c_str(); 1508 m_geometry_shader_parts[3] = m_geometry_shader_code_body_str; 1509 1510 stream.str(std::string()); 1511 stream.clear(); 1512 for (glw::GLint uniform_block_nr = 0; uniform_block_nr < m_max_uniform_blocks; ++uniform_block_nr) 1513 { 1514 stream << " gs_out_sum += uni_block_array[" << uniform_block_nr << "].entry;\n"; 1515 } 1516 m_uniform_block_access_string = stream.str(); 1517 1518 m_geometry_shader_parts[4] = m_uniform_block_access_string.c_str(); 1519 m_geometry_shader_parts[5] = m_geometry_shader_code_body_end; 1520 1521 out_geometry_shader_parts = m_geometry_shader_parts; 1522 out_n_geometry_shader_parts = 6; 1523 1524 /* Vertex Shader */ 1525 out_vertex_shader_parts = &m_vertex_shader_code; 1526 out_n_vertex_shader_parts = 1; 1527} 1528 1529/** Get size of buffer used by transform feedback 1530 * 1531 * @param out_buffer_size Size of buffer in bytes 1532 **/ 1533void GeometryShaderMaxUniformBlocksTest::getTransformFeedbackBufferSize(unsigned int& out_buffer_size) 1534{ 1535 out_buffer_size = m_buffer_size; 1536} 1537 1538/** Prepare test specific program input for draw call 1539 * 1540 **/ 1541void GeometryShaderMaxUniformBlocksTest::prepareProgramInput() 1542{ 1543 /* Retrieve ES entry-points */ 1544 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1545 1546 /* Allocate memory */ 1547 m_uniform_blocks.resize(m_max_uniform_blocks); 1548 1549 /* Setup uniform blocks */ 1550 for (glw::GLint i = 0; i < m_max_uniform_blocks; ++i) 1551 { 1552 /* Generate and bind */ 1553 gl.genBuffers(1, &m_uniform_blocks[i].buffer_object_id); 1554 gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_blocks[i].buffer_object_id); 1555 1556 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed create buffer object"); 1557 1558 /** Expected data is range <1;GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT> 1559 * See test description for details 1560 **/ 1561 m_uniform_blocks[i].data = i + 1; 1562 1563 gl.bufferData(GL_UNIFORM_BUFFER, sizeof(glw::GLint), &m_uniform_blocks[i].data, GL_STATIC_DRAW); 1564 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set buffer data"); 1565 1566 /* Bind buffer to uniform block */ 1567 gl.bindBufferBase(GL_UNIFORM_BUFFER, i, m_uniform_blocks[i].buffer_object_id); 1568 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind buffer to uniform block"); 1569 } 1570} 1571 1572/** Verification of results 1573 * 1574 * @param result Pointer to data mapped from transform feedback buffer. 1575 * Size of data is equal to buffer_size set by getTransformFeedbackBufferSize() 1576 * 1577 * @return true Result match expected value 1578 * false Result has wrong value 1579 **/ 1580bool GeometryShaderMaxUniformBlocksTest::verifyResult(const void* data) 1581{ 1582 /* Expected data, sum of elements in range <x;y> with length n = ((x + y) / 2) * n */ 1583 const glw::GLint expected_data = ((1 + m_max_uniform_blocks) * m_max_uniform_blocks) / 2; 1584 1585 /* Cast to const GLint */ 1586 const glw::GLint* transform_feedback_data = (const glw::GLint*)data; 1587 1588 /* Verify data extracted from transfrom feedback */ 1589 if (0 != memcmp(transform_feedback_data, &expected_data, m_buffer_size)) 1590 { 1591 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! Expected: " << expected_data 1592 << " Extracted: " << *transform_feedback_data << tcu::TestLog::EndMessage; 1593 1594 return false; 1595 } 1596 else 1597 { 1598 return true; 1599 } 1600} 1601 1602/** Constructor 1603 * 1604 * @param context Test context 1605 * @param name Test case's name 1606 * @param description Test case's description 1607 **/ 1608GeometryShaderMaxInputComponentsTest::GeometryShaderMaxInputComponentsTest(Context& context, 1609 const ExtParameters& extParams, 1610 const char* name, const char* description) 1611 : GeometryShaderLimitsTransformFeedbackBase(context, extParams, name, description) 1612 , m_max_geometry_input_components(0) 1613 , m_max_geometry_input_vectors(0) 1614{ 1615 /* Nothing to be done here */ 1616} 1617 1618/** Clears data after draw call and result verification 1619 * 1620 **/ 1621void GeometryShaderMaxInputComponentsTest::clean() 1622{ 1623 /* Nothing to be done here */ 1624} 1625 1626/** Get names and number of varyings to be captured by transform feedback 1627 * 1628 * @param out_captured_varyings_names Array of varying names 1629 * @param out_n_captured_varyings Number of varying names 1630 **/ 1631void GeometryShaderMaxInputComponentsTest::getCapturedVaryings(const glw::GLchar* const*& out_captured_varyings_names, 1632 glw::GLuint& out_n_captured_varyings) 1633{ 1634 /* Varying names */ 1635 out_captured_varyings_names = &m_captured_varyings_names; 1636 1637 /* Number of varyings */ 1638 out_n_captured_varyings = 1; 1639} 1640 1641/** Get parts of shaders 1642 * 1643 * @param out_fragment_shader_parts Array of fragment shader parts 1644 * @param out_n_fragment_shader_parts Number of fragment shader parts 1645 * @param out_geometry_shader_parts Array of geometry shader parts 1646 * @param out_n_geometry_shader_parts Number of geometry shader parts 1647 * @param out_vertex_shader_parts Array of vertex shader parts 1648 * @param out_n_vertex_shader_parts Number of vertex shader parts 1649 **/ 1650void GeometryShaderMaxInputComponentsTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 1651 unsigned int& out_n_fragment_shader_parts, 1652 const glw::GLchar* const*& out_geometry_shader_parts, 1653 unsigned int& out_n_geometry_shader_parts, 1654 const glw::GLchar* const*& out_vertex_shader_parts, 1655 unsigned int& out_n_vertex_shader_parts) 1656{ 1657 /* Retrieve ES entry-points */ 1658 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1659 1660 /* Fragment Shader */ 1661 out_fragment_shader_parts = &m_fragment_shader_code; 1662 out_n_fragment_shader_parts = 1; 1663 1664 /* Get maximum number of uniform */ 1665 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_INPUT_COMPONENTS, &m_max_geometry_input_components); 1666 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT pname"); 1667 1668 m_max_geometry_input_vectors = m_max_geometry_input_components / 4 /* 4 components per vector */; 1669 1670 std::stringstream stream; 1671 stream << m_max_geometry_input_vectors; 1672 m_max_geometry_input_vectors_string = stream.str(); 1673 1674 /* Geometry Shader */ 1675 m_geometry_shader_parts[0] = m_geometry_shader_code_preamble; 1676 m_geometry_shader_parts[1] = m_geometry_shader_code_number_of_uniforms; 1677 m_geometry_shader_parts[2] = m_max_geometry_input_vectors_string.c_str(); 1678 m_geometry_shader_parts[3] = m_geometry_shader_code_body; 1679 1680 out_geometry_shader_parts = m_geometry_shader_parts; 1681 out_n_geometry_shader_parts = 4; 1682 1683 /* Vertex Shader */ 1684 m_vertex_shader_parts[0] = m_vertex_shader_code_preamble; 1685 m_vertex_shader_parts[1] = m_vertex_shader_code_number_of_uniforms; 1686 m_vertex_shader_parts[2] = m_max_geometry_input_vectors_string.c_str(); 1687 m_vertex_shader_parts[3] = m_vertex_shader_code_body; 1688 1689 out_vertex_shader_parts = m_vertex_shader_parts; 1690 out_n_vertex_shader_parts = 4; 1691} 1692 1693/** Get size of buffer used by transform feedback 1694 * 1695 * @param out_buffer_size Size of buffer in bytes 1696 **/ 1697void GeometryShaderMaxInputComponentsTest::getTransformFeedbackBufferSize(unsigned int& out_buffer_size) 1698{ 1699 out_buffer_size = m_buffer_size; 1700} 1701 1702/** Prepare test specific program input for draw call 1703 * 1704 **/ 1705void GeometryShaderMaxInputComponentsTest::prepareProgramInput() 1706{ 1707 /* Nothing to be done here */ 1708} 1709 1710/** Verification of results 1711 * 1712 * @param result Pointer to data mapped from transform feedback buffer. 1713 * Size of data is equal to buffer_size set by getTransformFeedbackBufferSize() 1714 * 1715 * @return true Result match expected value 1716 * false Result has wrong value 1717 **/ 1718bool GeometryShaderMaxInputComponentsTest::verifyResult(const void* data) 1719{ 1720 /* Expected data, sum of elements in range <x;y> with length n = ((x + y) / 2) * n */ 1721 const glw::GLint expected_data = ((1 + m_max_geometry_input_components) * m_max_geometry_input_components) / 2; 1722 1723 /* Cast to const GLint */ 1724 const glw::GLint* transform_feedback_data = (const glw::GLint*)data; 1725 1726 /* Verify data extracted from transfrom feedback */ 1727 if (0 != memcmp(transform_feedback_data, &expected_data, m_buffer_size)) 1728 { 1729 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! Expected: " << expected_data 1730 << " Extracted: " << *transform_feedback_data << tcu::TestLog::EndMessage; 1731 1732 return false; 1733 } 1734 else 1735 { 1736 return true; 1737 } 1738} 1739 1740/** Constructor 1741 * 1742 * @param context Test context 1743 * @param name Test case's name 1744 * @param description Test case's description 1745 **/ 1746GeometryShaderMaxOutputComponentsTest::GeometryShaderMaxOutputComponentsTest(Context& context, 1747 const ExtParameters& extParams, 1748 const char* name, const char* description) 1749 : GeometryShaderLimitsRenderingBase(context, extParams, name, description) 1750 , m_fragment_shader_code_c_str(0) 1751 , m_geometry_shader_code_c_str(0) 1752 , m_texture_width(0) 1753 , m_max_output_components(0) 1754 , m_max_output_vectors(0) 1755 , m_max_total_output_components(0) 1756 , m_n_available_vectors(0) 1757 , m_n_output_points(0) 1758{ 1759 /* Nothing to be done here */ 1760} 1761 1762/** Clears data after draw call and result verification 1763 * 1764 **/ 1765void GeometryShaderMaxOutputComponentsTest::clean() 1766{ 1767 /* Nothing to be done here */ 1768} 1769 1770/** Get details for draw call 1771 * 1772 * @param out_primitive_type Type of primitive that will be used by next draw call 1773 * @param out_n_vertices Number of vertices that will used with next draw call 1774 **/ 1775void GeometryShaderMaxOutputComponentsTest::getDrawCallDetails(glw::GLenum& out_primitive_type, 1776 glw::GLuint& out_n_vertices) 1777{ 1778 /* Draw one point */ 1779 out_primitive_type = GL_POINTS; 1780 out_n_vertices = 1; 1781} 1782 1783/** Get dimensions and format for texture bind to color attachment 0, get format and type for glReadPixels 1784 * 1785 * @param out_texture_format Format for texture used as color attachment 0 1786 * @param out_texture_read_format Format of data used with glReadPixels 1787 * @param out_texture_read_type Type of data used with glReadPixels 1788 * @param out_texture_width Width of texture used as color attachment 0 1789 * @param out_texture_height Height of texture used as color attachment 0 1790 * @param out_texture_pixel_size Size of single pixel in bytes 1791 **/ 1792void GeometryShaderMaxOutputComponentsTest::getFramebufferDetails( 1793 glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format, glw::GLenum& out_texture_read_type, 1794 glw::GLuint& out_texture_width, glw::GLuint& out_texture_height, unsigned int& out_texture_pixel_size) 1795{ 1796 out_texture_format = GL_R32I; 1797 out_texture_read_format = GL_RGBA_INTEGER; 1798 out_texture_read_type = GL_INT; 1799 out_texture_width = m_texture_width; 1800 out_texture_height = m_texture_height; 1801 out_texture_pixel_size = 4 * 4; 1802} 1803 1804void GeometryShaderMaxOutputComponentsTest::getRequiredPointSize(glw::GLfloat& out_point_size) 1805{ 1806 /* This test should only run if EXT_geometry_point_size is supported */ 1807 if (!m_is_geometry_shader_point_size_supported) 1808 { 1809 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 1810 } 1811 1812 out_point_size = (float)m_point_size; 1813} 1814 1815/** Get parts of shaders 1816 * 1817 * @param out_fragment_shader_parts Array of fragment shader parts 1818 * @param out_n_fragment_shader_parts Number of fragment shader parts 1819 * @param out_geometry_shader_parts Array of geometry shader parts 1820 * @param out_n_geometry_shader_parts Number of geometry shader parts 1821 * @param out_vertex_shader_parts Array of vertex shader parts 1822 * @param out_n_vertex_shader_parts Number of vertex shader parts 1823 **/ 1824void GeometryShaderMaxOutputComponentsTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 1825 unsigned int& out_n_fragment_shader_parts, 1826 const glw::GLchar* const*& out_geometry_shader_parts, 1827 unsigned int& out_n_geometry_shader_parts, 1828 const glw::GLchar* const*& out_vertex_shader_parts, 1829 unsigned int& out_n_vertex_shader_parts) 1830{ 1831 /* GL functions */ 1832 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1833 1834 /* Get maximum number of output components */ 1835 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &m_max_total_output_components); 1836 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_COMPONENTS, &m_max_output_components); 1837 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed"); 1838 1839 m_n_output_points = m_max_total_output_components / m_max_output_components; 1840 m_max_output_vectors = m_max_output_components / 4; /* 4 components per vector */ 1841 m_n_available_vectors = m_max_output_vectors - 2; /* 2 vectors are reserved for gl_Position and gl_PointSize */ 1842 1843 /* Framebuffer width */ 1844 m_texture_width = m_point_size * m_n_output_points; 1845 1846 /* Fragment shader parts */ 1847 prepareFragmentShader(m_fragment_shader_code); 1848 1849 m_fragment_shader_code_c_str = m_fragment_shader_code.c_str(); 1850 out_fragment_shader_parts = &m_fragment_shader_code_c_str; 1851 out_n_fragment_shader_parts = 1; 1852 1853 /* Geometry shader parts */ 1854 prepareGeometryShader(m_geometry_shader_code); 1855 1856 m_geometry_shader_code_c_str = m_geometry_shader_code.c_str(); 1857 out_geometry_shader_parts = &m_geometry_shader_code_c_str; 1858 out_n_geometry_shader_parts = 1; 1859 1860 /* Vertex shader */ 1861 out_vertex_shader_parts = &m_vertex_shader_code; 1862 out_n_vertex_shader_parts = 1; 1863} 1864 1865/** Prepare test specific program input for draw call 1866 * 1867 **/ 1868void GeometryShaderMaxOutputComponentsTest::prepareProgramInput() 1869{ 1870 /* Nothing to be done here */ 1871} 1872 1873/** Verify rendered image 1874 * 1875 * @param data Image to verify 1876 * 1877 * @return true Image pixels match expected values 1878 * false Some pixels have wrong values 1879 **/ 1880bool GeometryShaderMaxOutputComponentsTest::verifyResult(const void* data) 1881{ 1882 const unsigned char* result_image = (const unsigned char*)data; 1883 const unsigned int line_size = m_texture_width * m_texture_pixel_size; 1884 const glw::GLint n_components_per_point = m_n_available_vectors * 4; /* 4 components per vector */ 1885 1886 /* For each drawn point */ 1887 for (glw::GLint point = 0; point < m_n_output_points; ++point) 1888 { 1889 const glw::GLint first_value = point * n_components_per_point + 1; 1890 const glw::GLint last_value = (point + 1) * n_components_per_point; 1891 const glw::GLint expected_value = ((first_value + last_value) * n_components_per_point) / 2; 1892 const unsigned int point_offset = point * m_texture_pixel_size * m_point_size; 1893 1894 /* Verify all pixels that belong to point, area m_point_size x m_point_size */ 1895 for (unsigned int y = 0; y < m_point_size; ++y) 1896 { 1897 const unsigned int line_offset = y * line_size; 1898 const unsigned int first_texel_offset = line_offset + point_offset; 1899 1900 for (unsigned int x = 0; x < m_point_size; ++x) 1901 { 1902 const unsigned int texel_offset = first_texel_offset + x * m_texture_pixel_size; 1903 1904 if (0 != memcmp(result_image + texel_offset, &expected_value, sizeof(expected_value))) 1905 { 1906 glw::GLint* result_value = (glw::GLint*)(result_image + texel_offset); 1907 1908 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! Expected: " << expected_value 1909 << " Extracted: " << *result_value << " Point: " << point << " X: " << x 1910 << " Y: " << y << tcu::TestLog::EndMessage; 1911 1912 return false; 1913 } 1914 } 1915 } 1916 } 1917 1918 return true; 1919} 1920 1921/** Prepare fragment shader code 1922 * 1923 * @param out_shader_code String that will be used to store shaders code 1924 **/ 1925void GeometryShaderMaxOutputComponentsTest::prepareFragmentShader(std::string& out_shader_code) const 1926{ 1927 std::stringstream stream; 1928 1929 stream << m_fragment_shader_code_preamble; 1930 stream << m_common_shader_code_gs_fs_out_definitions; 1931 1932 for (int i = 0; i < m_n_available_vectors; ++i) 1933 { 1934 stream << m_fragment_shader_code_flat_in_ivec4 << " " << m_common_shader_code_gs_fs_out << i << ";\n"; 1935 } 1936 1937 stream << m_fragment_shader_code_body_begin; 1938 1939 for (int i = 0; i < m_n_available_vectors; ++i) 1940 { 1941 stream << " " << m_fragment_shader_code_sum << m_common_shader_code_gs_fs_out << i << ".x + " 1942 << m_common_shader_code_gs_fs_out << i << ".y + " << m_common_shader_code_gs_fs_out << i << ".z + " 1943 << m_common_shader_code_gs_fs_out << i << ".w;\n"; 1944 } 1945 1946 stream << m_fragment_shader_code_body_end; 1947 1948 out_shader_code = stream.str(); 1949} 1950 1951/** Prepare geometry shader code 1952 * 1953 * @param out_shader_code String that will be used to store shaders code 1954 **/ 1955void GeometryShaderMaxOutputComponentsTest::prepareGeometryShader(std::string& out_shader_code) const 1956{ 1957 std::stringstream stream; 1958 1959 stream << m_geometry_shader_code_preamble; 1960 stream << m_common_shader_code_number_of_points; 1961 stream << m_n_output_points; 1962 stream << m_geometry_shader_code_layout; 1963 stream << m_common_shader_code_gs_fs_out_definitions; 1964 1965 for (int i = 0; i < m_n_available_vectors; ++i) 1966 { 1967 stream << m_geometry_shader_code_flat_out_ivec4 << " " << m_common_shader_code_gs_fs_out << i << ";\n"; 1968 } 1969 1970 stream << m_geometry_shader_code_body_begin; 1971 1972 for (int i = 0; i < m_n_available_vectors; ++i) 1973 { 1974 stream << " " << m_common_shader_code_gs_fs_out << i << m_geometry_shader_code_assignment; 1975 } 1976 1977 stream << m_geometry_shader_code_body_end; 1978 1979 out_shader_code = stream.str(); 1980} 1981 1982/** Constructor 1983 * 1984 * @param context Test context 1985 * @param name Test case's name 1986 * @param description Test case's description 1987 **/ 1988GeometryShaderMaxOutputVerticesTest::GeometryShaderMaxOutputVerticesTest(Context& context, 1989 const ExtParameters& extParams, 1990 const char* name, const char* description) 1991 : TestCaseBase(context, extParams, name, description) 1992{ 1993 /* Nothing to be done here */ 1994} 1995 1996/** Executes the test. 1997 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 1998 * 1999 * Note the function throws exception should an error occur! 2000 * 2001 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 2002 * 2003 **/ 2004tcu::TestCase::IterateResult GeometryShaderMaxOutputVerticesTest::iterate() 2005{ 2006 /* This test should only run if EXT_geometry_shader is supported */ 2007 if (!m_is_geometry_shader_extension_supported) 2008 { 2009 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 2010 } 2011 2012 /* GL */ 2013 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2014 2015 /* Get maximum number of output vertices and prepare strings */ 2016 glw::GLint max_output_vertices; 2017 std::string valid_output_vertices_string; 2018 std::string invalid_output_vertices_string; 2019 2020 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_VERTICES, &max_output_vertices); 2021 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT pname"); 2022 2023 std::stringstream stream_valid; 2024 stream_valid << max_output_vertices; 2025 valid_output_vertices_string = stream_valid.str(); 2026 2027 std::stringstream stream_invalid; 2028 stream_invalid << max_output_vertices + 1; 2029 invalid_output_vertices_string = stream_invalid.str(); 2030 2031 /* Geometry shader parts */ 2032 const glw::GLchar* geometry_shader_valid_parts[] = { m_geometry_shader_code_preamble, 2033 valid_output_vertices_string.c_str(), 2034 m_geometry_shader_code_body }; 2035 2036 const glw::GLchar* geometry_shader_invalid_parts[] = { m_geometry_shader_code_preamble, 2037 invalid_output_vertices_string.c_str(), 2038 m_geometry_shader_code_body }; 2039 2040 /* Try to build programs */ 2041 bool does_valid_build = 2042 doesProgramBuild(1, &m_fragment_shader_code, 3, geometry_shader_valid_parts, 1, &m_vertex_shader_code); 2043 2044 bool does_invalid_build = 2045 doesProgramBuild(1, &m_fragment_shader_code, 3, geometry_shader_invalid_parts, 1, &m_vertex_shader_code); 2046 2047 /* Verify results */ 2048 if ((true == does_valid_build) && (false == does_invalid_build)) 2049 { 2050 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2051 } 2052 else 2053 { 2054 if (true != does_valid_build) 2055 { 2056 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to build valid program! GS::max_vertices " 2057 "set to MAX_GEOMETRY_OUTPUT_VERTICES.\n" 2058 << tcu::TestLog::EndMessage; 2059 } 2060 2061 if (false != does_invalid_build) 2062 { 2063 m_testCtx.getLog() << tcu::TestLog::Message << "Build of invalid program was successful! GS::max_vertices " 2064 "set to MAX_GEOMETRY_OUTPUT_VERTICES + 1.\n" 2065 << tcu::TestLog::EndMessage; 2066 } 2067 2068 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2069 } 2070 2071 return STOP; 2072} 2073 2074/** Constructor 2075 * 2076 * @param context Test context 2077 * @param name Test case's name 2078 * @param description Test case's decsription 2079 **/ 2080GeometryShaderMaxOutputComponentsSinglePointTest::GeometryShaderMaxOutputComponentsSinglePointTest( 2081 Context& context, const ExtParameters& extParams, const char* name, const char* description) 2082 : GeometryShaderLimitsRenderingBase(context, extParams, name, description) 2083 , m_fragment_shader_code_c_str(0) 2084 , m_geometry_shader_code_c_str(0) 2085 , m_max_output_components(0) 2086 , m_max_output_vectors(0) 2087 , m_n_available_vectors(0) 2088{ 2089 /* Nothing to be done here */ 2090} 2091 2092/** Clears data after draw call and result verification 2093 * 2094 **/ 2095void GeometryShaderMaxOutputComponentsSinglePointTest::clean() 2096{ 2097 /* Nothing to be done here */ 2098} 2099 2100/** Get details for draw call 2101 * 2102 * @param out_primitive_type Type of primitive that will be used by next draw call 2103 * @param out_n_vertices Number of vertices that will used with next draw call 2104 **/ 2105void GeometryShaderMaxOutputComponentsSinglePointTest::getDrawCallDetails(glw::GLenum& out_primitive_type, 2106 glw::GLuint& out_n_vertices) 2107{ 2108 /* Draw one point */ 2109 out_primitive_type = GL_POINTS; 2110 out_n_vertices = 1; 2111} 2112 2113/** Get dimensions and format for texture bind to color attachment 0, get format and type for glReadPixels 2114 * 2115 * @param out_texture_format Format for texture used as color attachment 0 2116 * @param out_texture_read_format Format of data used with glReadPixels 2117 * @param out_texture_read_type Type of data used with glReadPixels 2118 * @param out_texture_width Width of texture used as color attachment 0 2119 * @param out_texture_height Height of texture used as color attachment 0 2120 * @param out_texture_pixel_size Size of single pixel in bytes 2121 **/ 2122void GeometryShaderMaxOutputComponentsSinglePointTest::getFramebufferDetails( 2123 glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format, glw::GLenum& out_texture_read_type, 2124 glw::GLuint& out_texture_width, glw::GLuint& out_texture_height, unsigned int& out_texture_pixel_size) 2125{ 2126 out_texture_format = GL_R32I; 2127 out_texture_read_format = GL_RGBA_INTEGER; 2128 out_texture_read_type = GL_INT; 2129 out_texture_width = m_texture_width; 2130 out_texture_height = m_texture_height; 2131 out_texture_pixel_size = 4 * 4; 2132} 2133 2134void GeometryShaderMaxOutputComponentsSinglePointTest::getRequiredPointSize(glw::GLfloat& out_point_size) 2135{ 2136 /* This test should only run if EXT_geometry_point_size is supported */ 2137 if (!m_is_geometry_shader_point_size_supported) 2138 { 2139 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 2140 } 2141 2142 out_point_size = (float)m_point_size; 2143} 2144 2145/** Get parts of shaders 2146 * 2147 * @param out_fragment_shader_parts Array of fragment shader parts 2148 * @param out_n_fragment_shader_parts Number of fragment shader parts 2149 * @param out_geometry_shader_parts Array of geometry shader parts 2150 * @param out_n_geometry_shader_parts Number of geometry shader parts 2151 * @param out_vertex_shader_parts Array of vertex shader parts 2152 * @param out_n_vertex_shader_parts Number of vertex shader parts 2153 **/ 2154void GeometryShaderMaxOutputComponentsSinglePointTest::getShaderParts( 2155 const glw::GLchar* const*& out_fragment_shader_parts, unsigned int& out_n_fragment_shader_parts, 2156 const glw::GLchar* const*& out_geometry_shader_parts, unsigned int& out_n_geometry_shader_parts, 2157 const glw::GLchar* const*& out_vertex_shader_parts, unsigned int& out_n_vertex_shader_parts) 2158{ 2159 /* Retrieve ES entry-points */ 2160 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2161 2162 /* Get maximum number of output components */ 2163 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_COMPONENTS, &m_max_output_components); 2164 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT pname"); 2165 2166 m_max_output_vectors = m_max_output_components / 4; /* 4 components per vector */ 2167 m_n_available_vectors = m_max_output_vectors - 2; /* 2 vectors are reserved for gl_Position and gl_PointSize */ 2168 2169 /* Fragment shader parts */ 2170 prepareFragmentShader(m_fragment_shader_code); 2171 2172 m_fragment_shader_code_c_str = m_fragment_shader_code.c_str(); 2173 out_fragment_shader_parts = &m_fragment_shader_code_c_str; 2174 out_n_fragment_shader_parts = 1; 2175 2176 /* Geometry shader parts */ 2177 prepareGeometryShader(m_geometry_shader_code); 2178 2179 m_geometry_shader_code_c_str = m_geometry_shader_code.c_str(); 2180 out_geometry_shader_parts = &m_geometry_shader_code_c_str; 2181 out_n_geometry_shader_parts = 1; 2182 2183 /* Vertex shader */ 2184 out_vertex_shader_parts = &m_vertex_shader_code; 2185 out_n_vertex_shader_parts = 1; 2186} 2187 2188/** Prepare test specific program input for draw call 2189 * 2190 **/ 2191void GeometryShaderMaxOutputComponentsSinglePointTest::prepareProgramInput() 2192{ 2193 /* Nothing to be done here */ 2194} 2195 2196/** Verify rendered image 2197 * 2198 * @param data Image to verify 2199 * 2200 * @return true Image pixels match expected values 2201 * false Some pixels have wrong values 2202 **/ 2203bool GeometryShaderMaxOutputComponentsSinglePointTest::verifyResult(const void* data) 2204{ 2205 const unsigned char* result_image = (const unsigned char*)data; 2206 const unsigned int line_size = m_texture_width * m_texture_pixel_size; 2207 const glw::GLint n_components_per_point = m_n_available_vectors * 4; /* 4 components per vector */ 2208 2209 const glw::GLint first_value = 1; 2210 const glw::GLint last_value = n_components_per_point; 2211 const glw::GLint expected_value = ((first_value + last_value) * n_components_per_point) / 2; 2212 2213 /* Verify all pixels that belong to point, area m_point_size x m_point_size */ 2214 for (unsigned int y = 0; y < m_point_size; ++y) 2215 { 2216 const unsigned int line_offset = y * line_size; 2217 2218 for (unsigned int x = 0; x < m_point_size; ++x) 2219 { 2220 const unsigned int texel_offset = line_offset + x * m_texture_pixel_size; 2221 2222 if (0 != memcmp(result_image + texel_offset, &expected_value, sizeof(expected_value))) 2223 { 2224 const glw::GLint* result_value = (const glw::GLint*)(result_image + texel_offset); 2225 2226 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! Expected: " << expected_value 2227 << " Extracted: " << *result_value << " X: " << x << " Y: " << y 2228 << tcu::TestLog::EndMessage; 2229 2230 return false; 2231 } 2232 } 2233 } 2234 2235 return true; 2236} 2237 2238/** Prepare fragment shader code 2239 * 2240 * @param out_shader_code String that will be used to store shaders code 2241 **/ 2242void GeometryShaderMaxOutputComponentsSinglePointTest::prepareFragmentShader(std::string& out_shader_code) const 2243{ 2244 std::stringstream stream; 2245 2246 stream << m_fragment_shader_code_preamble; 2247 stream << m_common_shader_code_gs_fs_out_definitions; 2248 2249 for (int i = 0; i < m_n_available_vectors; ++i) 2250 { 2251 stream << m_fragment_shader_code_flat_in_ivec4 << " " << m_common_shader_code_gs_fs_out << i << ";\n"; 2252 } 2253 2254 stream << m_fragment_shader_code_body_begin; 2255 2256 for (int i = 0; i < m_n_available_vectors; ++i) 2257 { 2258 stream << " " << m_fragment_shader_code_sum << m_common_shader_code_gs_fs_out << i << ".x + " 2259 << m_common_shader_code_gs_fs_out << i << ".y + " << m_common_shader_code_gs_fs_out << i << ".z + " 2260 << m_common_shader_code_gs_fs_out << i << ".w;\n"; 2261 } 2262 2263 stream << m_fragment_shader_code_body_end; 2264 2265 out_shader_code = stream.str(); 2266} 2267 2268/** Prepare geometry shader code 2269 * 2270 * @param out_shader_code String that will be used to store shaders code 2271 **/ 2272void GeometryShaderMaxOutputComponentsSinglePointTest::prepareGeometryShader(std::string& out_shader_code) const 2273{ 2274 std::stringstream stream; 2275 2276 stream << m_geometry_shader_code_preamble; 2277 stream << m_common_shader_code_gs_fs_out_definitions; 2278 2279 for (int i = 0; i < m_n_available_vectors; ++i) 2280 { 2281 stream << m_geometry_shader_code_flat_out_ivec4 << " " << m_common_shader_code_gs_fs_out << i << ";\n"; 2282 } 2283 2284 stream << m_geometry_shader_code_body_begin; 2285 2286 for (int i = 0; i < m_n_available_vectors; ++i) 2287 { 2288 stream << " " << m_common_shader_code_gs_fs_out << i << m_geometry_shader_code_assignment; 2289 } 2290 2291 stream << m_geometry_shader_code_body_end; 2292 2293 out_shader_code = stream.str(); 2294} 2295 2296/** Constructor 2297 * 2298 * @param context Test context 2299 * @param name Test case's name 2300 * @param description Test case's description 2301 **/ 2302GeometryShaderMaxTextureUnitsTest::GeometryShaderMaxTextureUnitsTest(Context& context, const ExtParameters& extParams, 2303 const char* name, const char* description) 2304 : GeometryShaderLimitsRenderingBase(context, extParams, name, description) 2305 , m_texture_width(0) 2306 , m_max_texture_units(0) 2307{ 2308 /* Nothing to be done here */ 2309} 2310 2311/** Clears data after draw call and result verification 2312 * 2313 **/ 2314void GeometryShaderMaxTextureUnitsTest::clean() 2315{ 2316 /* GL functions */ 2317 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2318 2319 /* Bind 0 to all texture units */ 2320 for (int i = 0; i < m_max_texture_units; ++i) 2321 { 2322 gl.activeTexture(GL_TEXTURE0 + i); 2323 gl.bindTexture(GL_TEXTURE_2D, 0); 2324 } 2325 gl.activeTexture(GL_TEXTURE0); 2326 2327 /* Delete textures */ 2328 for (int i = 0; i < m_max_texture_units; ++i) 2329 { 2330 gl.deleteTextures(1, &m_textures[i].texture_id); 2331 } 2332 2333 m_textures.clear(); 2334} 2335 2336/** Get details for draw call 2337 * 2338 * @param out_primitive_type Type of primitive that will be used by next draw call 2339 * @param out_n_vertices Number of vertices that will used with next draw call 2340 **/ 2341void GeometryShaderMaxTextureUnitsTest::getDrawCallDetails(glw::GLenum& out_primitive_type, glw::GLuint& out_n_vertices) 2342{ 2343 /* Draw GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT points */ 2344 out_primitive_type = GL_POINTS; 2345 out_n_vertices = m_max_texture_units; 2346} 2347 2348/** Get dimensions and format for texture bind to color attachment 0, get format and type for glReadPixels 2349 * 2350 * @param out_texture_format Format for texture used as color attachment 0 2351 * @param out_texture_read_format Format of data used with glReadPixels 2352 * @param out_texture_read_type Type of data used with glReadPixels 2353 * @param out_texture_width Width of texture used as color attachment 0 2354 * @param out_texture_height Height of texture used as color attachment 0 2355 * @param out_texture_pixel_size Size of single pixel in bytes 2356 **/ 2357void GeometryShaderMaxTextureUnitsTest::getFramebufferDetails( 2358 glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format, glw::GLenum& out_texture_read_type, 2359 glw::GLuint& out_texture_width, glw::GLuint& out_texture_height, unsigned int& out_texture_pixel_size) 2360{ 2361 out_texture_format = GL_R32I; 2362 out_texture_read_format = GL_RGBA_INTEGER; 2363 out_texture_read_type = GL_INT; 2364 out_texture_width = m_texture_width; 2365 out_texture_height = m_texture_height; 2366 out_texture_pixel_size = 4 * 4; 2367} 2368 2369void GeometryShaderMaxTextureUnitsTest::getRequiredPointSize(glw::GLfloat& out_point_size) 2370{ 2371 /* This test should only run if EXT_geometry_point_size is supported */ 2372 if (!m_is_geometry_shader_point_size_supported) 2373 { 2374 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 2375 } 2376 2377 out_point_size = (float)m_point_size; 2378} 2379 2380/** Get parts of shaders 2381 * 2382 * @param out_fragment_shader_parts Array of fragment shader parts 2383 * @param out_n_fragment_shader_parts Number of fragment shader parts 2384 * @param out_geometry_shader_parts Array of geometry shader parts 2385 * @param out_n_geometry_shader_parts Number of geometry shader parts 2386 * @param out_vertex_shader_parts Array of vertex shader parts 2387 * @param out_n_vertex_shader_parts Number of vertex shader parts 2388 **/ 2389void GeometryShaderMaxTextureUnitsTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 2390 unsigned int& out_n_fragment_shader_parts, 2391 const glw::GLchar* const*& out_geometry_shader_parts, 2392 unsigned int& out_n_geometry_shader_parts, 2393 const glw::GLchar* const*& out_vertex_shader_parts, 2394 unsigned int& out_n_vertex_shader_parts) 2395{ 2396 /* Retrieve ES entry-points */ 2397 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2398 2399 /* Get maximum number of texture units */ 2400 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &m_max_texture_units); 2401 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT pname"); 2402 2403 /* Number of drawn points is equal to GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ 2404 m_texture_width = m_max_texture_units * m_point_size; 2405 2406 /* Prepare texture units string */ 2407 std::stringstream stream; 2408 stream << m_max_texture_units; 2409 m_max_texture_units_string = stream.str(); 2410 2411 /* Fragment shader parts */ 2412 out_fragment_shader_parts = &m_fragment_shader_code; 2413 out_n_fragment_shader_parts = 1; 2414 2415 /* Geometry shader parts */ 2416 m_geometry_shader_parts[0] = m_geometry_shader_code_preamble; 2417 m_geometry_shader_parts[1] = m_max_texture_units_string.c_str(); 2418 m_geometry_shader_parts[2] = m_geometry_shader_code_body; 2419 2420 out_geometry_shader_parts = m_geometry_shader_parts; 2421 out_n_geometry_shader_parts = 3; 2422 2423 /* Vertex shader parts */ 2424 m_vertex_shader_parts[0] = m_vertex_shader_code_preamble; 2425 m_vertex_shader_parts[1] = m_max_texture_units_string.c_str(); 2426 m_vertex_shader_parts[2] = m_vertex_shader_code_body; 2427 2428 out_vertex_shader_parts = m_vertex_shader_parts; 2429 out_n_vertex_shader_parts = 3; 2430} 2431 2432/** Prepare test specific program input for draw call 2433 * 2434 **/ 2435void GeometryShaderMaxTextureUnitsTest::prepareProgramInput() 2436{ 2437 /* Retrieve ES entry-points */ 2438 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2439 2440 m_textures.resize(m_max_texture_units); 2441 2442 /* Prepare texture storage and fill data */ 2443 for (int i = 0; i < m_max_texture_units; ++i) 2444 { 2445 /* (starting from 1, delta: 2) */ 2446 m_textures[i].data = i * 2 + 1; 2447 2448 /* Generate and bind texture */ 2449 gl.genTextures(1, &m_textures[i].texture_id); 2450 gl.bindTexture(GL_TEXTURE_2D, m_textures[i].texture_id); 2451 2452 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create texture"); 2453 2454 /* Allocate and upload texture data */ 2455 gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, GL_R32I, 1 /* width */, 1 /* height */, 0 /* border */, 2456 GL_RED_INTEGER, GL_INT, &m_textures[i].data); 2457 2458 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2459 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2460 2461 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create storage and fill texture with data"); 2462 } 2463 2464 /* Prepare sampler uniforms */ 2465 for (int i = 0; i < m_max_texture_units; ++i) 2466 { 2467 /* Prepare name of sampler */ 2468 std::stringstream stream; 2469 2470 stream << "gs_texture[" << i << "]"; 2471 2472 /* Get sampler location */ 2473 glw::GLint gs_texture_location = gl.getUniformLocation(m_program_object_id, stream.str().c_str()); 2474 2475 if (-1 == gs_texture_location || (GL_NO_ERROR != gl.getError())) 2476 { 2477 TCU_FAIL("Failed to get uniform isampler2D location"); 2478 } 2479 2480 /* Set uniform at sampler location value to index of texture unit */ 2481 gl.uniform1i(gs_texture_location, i); 2482 2483 if (GL_NO_ERROR != gl.getError()) 2484 { 2485 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to set uniform at location: " << gs_texture_location 2486 << " to value: " << i << tcu::TestLog::EndMessage; 2487 2488 TCU_FAIL("Failed to get uniform isampler2D location"); 2489 } 2490 } 2491 2492 /* Bind textures to texture units */ 2493 for (int i = 0; i < m_max_texture_units; ++i) 2494 { 2495 gl.activeTexture(GL_TEXTURE0 + i); 2496 gl.bindTexture(GL_TEXTURE_2D, m_textures[i].texture_id); 2497 } 2498 2499 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set texture units up"); 2500} 2501 2502/** Verify rendered image 2503 * 2504 * @param data Image to verify 2505 * 2506 * @return true Image pixels match expected values 2507 * false Some pixels have wrong values 2508 **/ 2509bool GeometryShaderMaxTextureUnitsTest::verifyResult(const void* data) 2510{ 2511 const unsigned char* result_image = (const unsigned char*)data; 2512 const unsigned int line_size = m_texture_width * m_texture_pixel_size; 2513 2514 /* For each drawn point */ 2515 for (glw::GLint point = 0; point < m_max_texture_units; ++point) 2516 { 2517 const glw::GLint first_value = m_textures[0].data; 2518 const glw::GLint last_value = m_textures[point].data; 2519 const glw::GLint expected_value = ((first_value + last_value) * (point + 1)) / 2; 2520 const unsigned int point_offset = point * m_texture_pixel_size * m_point_size; 2521 2522 /* Verify all pixels that belong to point, area m_point_size x m_point_size */ 2523 for (unsigned int y = 0; y < m_point_size; ++y) 2524 { 2525 const unsigned int line_offset = y * line_size; 2526 const unsigned int first_texel_offset = line_offset + point_offset; 2527 2528 for (unsigned int x = 0; x < m_point_size; ++x) 2529 { 2530 const unsigned int texel_offset = first_texel_offset + x * m_texture_pixel_size; 2531 2532 if (0 != memcmp(result_image + texel_offset, &expected_value, sizeof(expected_value))) 2533 { 2534 glw::GLint* result_value = (glw::GLint*)(result_image + texel_offset); 2535 2536 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! " 2537 "Expected: " 2538 << expected_value << " Extracted: " << *result_value << " Point: " << point 2539 << " X: " << x << " Y: " << y << tcu::TestLog::EndMessage; 2540 2541 return false; 2542 } 2543 } 2544 } 2545 } 2546 2547 return true; 2548} 2549 2550/** Constructor 2551 * 2552 * @param context Test context 2553 * @param name Test case's name 2554 * @param description Test case's description 2555 **/ 2556GeometryShaderMaxInvocationsTest::GeometryShaderMaxInvocationsTest(Context& context, const ExtParameters& extParams, 2557 const char* name, const char* description) 2558 : TestCaseBase(context, extParams, name, description) 2559 , m_fragment_shader_id_for_multiple_invocations_pass(0) 2560 , m_geometry_shader_id_for_multiple_invocations_pass(0) 2561 , m_program_object_id_for_multiple_invocations_pass(0) 2562 , m_vertex_shader_id_for_multiple_invocations_pass(0) 2563 , m_fragment_shader_id_for_single_invocation_pass(0) 2564 , m_geometry_shader_id_for_single_invocation_pass(0) 2565 , m_program_object_id_for_single_invocation_pass(0) 2566 , m_vertex_shader_id_for_single_invocation_pass(0) 2567 , m_max_geometry_shader_invocations(0) 2568 , m_framebuffer_object_id(0) 2569 , m_color_texture_id(0) 2570 , m_texture_width(0) 2571 , m_vertex_array_object_id(0) 2572{ 2573 /* Nothing to be done here */ 2574} 2575 2576/** Initializes GLES objects used during the test. 2577 * 2578 */ 2579void GeometryShaderMaxInvocationsTest::initTest() 2580{ 2581 /* This test should only run if EXT_geometry_shader is supported */ 2582 if (!m_is_geometry_shader_extension_supported) 2583 { 2584 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 2585 } 2586 2587 /* Retrieve ES entry-points */ 2588 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2589 2590 /* Get GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT */ 2591 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_INVOCATIONS, &m_max_geometry_shader_invocations); 2592 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT"); 2593 2594 /* Prepare string for GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT */ 2595 std::stringstream stream; 2596 stream << m_max_geometry_shader_invocations; 2597 m_max_geometry_shader_invocations_string = stream.str(); 2598 2599 /* Prepare gemetry shader parts for multiple invocations pass */ 2600 const glw::GLuint n_geometry_shader_parts_for_multiple_invocations_pass = 5; 2601 2602 m_geometry_shader_parts_for_multiple_invocations_pass[0] = m_geometry_shader_code_preamble; 2603 m_geometry_shader_parts_for_multiple_invocations_pass[1] = m_max_geometry_shader_invocations_string.c_str(); 2604 m_geometry_shader_parts_for_multiple_invocations_pass[2] = m_geometry_shader_code_layout; 2605 m_geometry_shader_parts_for_multiple_invocations_pass[3] = m_geometry_shader_code_layout_invocations; 2606 m_geometry_shader_parts_for_multiple_invocations_pass[4] = m_geometry_shader_code_body; 2607 2608 /* Prepare gemetry shader parts for single invocation pass */ 2609 const glw::GLuint n_geometry_shader_parts_for_single_invocation_pass = 4; 2610 2611 m_geometry_shader_parts_for_single_invocation_pass[0] = m_geometry_shader_code_preamble; 2612 m_geometry_shader_parts_for_single_invocation_pass[1] = m_max_geometry_shader_invocations_string.c_str(); 2613 m_geometry_shader_parts_for_single_invocation_pass[2] = m_geometry_shader_code_layout; 2614 m_geometry_shader_parts_for_single_invocation_pass[3] = m_geometry_shader_code_body; 2615 2616 /* Create program and shaders for multiple GS invocations */ 2617 m_program_object_id_for_multiple_invocations_pass = gl.createProgram(); 2618 2619 m_fragment_shader_id_for_multiple_invocations_pass = gl.createShader(GL_FRAGMENT_SHADER); 2620 m_geometry_shader_id_for_multiple_invocations_pass = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 2621 m_vertex_shader_id_for_multiple_invocations_pass = gl.createShader(GL_VERTEX_SHADER); 2622 2623 /* Create program and shaders for single GS invocations */ 2624 m_program_object_id_for_single_invocation_pass = gl.createProgram(); 2625 2626 m_fragment_shader_id_for_single_invocation_pass = gl.createShader(GL_FRAGMENT_SHADER); 2627 m_geometry_shader_id_for_single_invocation_pass = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 2628 m_vertex_shader_id_for_single_invocation_pass = gl.createShader(GL_VERTEX_SHADER); 2629 2630 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program or shader objects"); 2631 2632 /* Build program for multiple GS invocations */ 2633 if (false == buildProgram(m_program_object_id_for_multiple_invocations_pass, 2634 m_fragment_shader_id_for_multiple_invocations_pass, 1, &m_fragment_shader_code, 2635 m_geometry_shader_id_for_multiple_invocations_pass, 2636 n_geometry_shader_parts_for_multiple_invocations_pass, 2637 m_geometry_shader_parts_for_multiple_invocations_pass, 2638 m_vertex_shader_id_for_multiple_invocations_pass, 1, &m_vertex_shader_code)) 2639 { 2640 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 2641 } 2642 2643 /* Build program for single GS invocations */ 2644 if (false == buildProgram(m_program_object_id_for_single_invocation_pass, 2645 m_fragment_shader_id_for_single_invocation_pass, 1, &m_fragment_shader_code, 2646 m_geometry_shader_id_for_single_invocation_pass, 2647 n_geometry_shader_parts_for_single_invocation_pass, 2648 m_geometry_shader_parts_for_single_invocation_pass, 2649 m_vertex_shader_id_for_single_invocation_pass, 1, &m_vertex_shader_code)) 2650 { 2651 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 2652 } 2653 2654 /* Set up texture object and a FBO */ 2655 gl.genTextures(1, &m_color_texture_id); 2656 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create texture object"); 2657 2658 gl.genFramebuffers(1, &m_framebuffer_object_id); 2659 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer object"); 2660 2661 m_texture_width = m_triangle_edge_length * m_max_geometry_shader_invocations; 2662 2663 if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8, 2664 m_texture_width, m_texture_height)) 2665 { 2666 TCU_FAIL("Failed to setup framebuffer"); 2667 } 2668 2669 /* Set up a vertex array object */ 2670 gl.genVertexArrays(1, &m_vertex_array_object_id); 2671 gl.bindVertexArray(m_vertex_array_object_id); 2672 2673 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object"); 2674} 2675 2676/** Executes the test. 2677 * 2678 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 2679 * 2680 * Note the function throws exception should an error occur! 2681 * 2682 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 2683 **/ 2684tcu::TestCase::IterateResult GeometryShaderMaxInvocationsTest::iterate() 2685{ 2686 initTest(); 2687 2688 /* Variables used for image verification purposes */ 2689 std::vector<unsigned char> result_image(m_texture_width * m_texture_height * m_texture_pixel_size); 2690 2691 /* Retrieve ES entry-points */ 2692 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2693 2694 /* Render with multiple GS invocations */ 2695 gl.useProgram(m_program_object_id_for_multiple_invocations_pass); 2696 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program"); 2697 2698 gl.clearColor(255 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */); 2699 gl.clear(GL_COLOR_BUFFER_BIT); 2700 2701 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer"); 2702 2703 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 2704 GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed"); 2705 2706 /* Extract image from FBO */ 2707 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, &result_image[0]); 2708 2709 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer"); 2710 2711 /* Run verification */ 2712 bool result_of_multiple_invocations_pass = verifyResultOfMultipleInvocationsPass(&result_image[0]); 2713 2714 /* Render with single GS invocations */ 2715 gl.useProgram(m_program_object_id_for_single_invocation_pass); 2716 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program"); 2717 2718 gl.clearColor(255 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */); 2719 gl.clear(GL_COLOR_BUFFER_BIT); 2720 2721 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer"); 2722 2723 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 2724 GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed"); 2725 2726 /* Extract image from FBO */ 2727 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, &result_image[0]); 2728 2729 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer"); 2730 2731 /* Run verification */ 2732 bool result_of_single_invocation_pass = verifyResultOfSingleInvocationPass(&result_image[0]); 2733 2734 /* Set test result */ 2735 if (result_of_multiple_invocations_pass && result_of_single_invocation_pass) 2736 { 2737 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2738 } 2739 else 2740 { 2741 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2742 } 2743 2744 return STOP; 2745} 2746 2747/** Deinitializes GLES objects created during the test. 2748 * 2749 */ 2750void GeometryShaderMaxInvocationsTest::deinit() 2751{ 2752 /* Retrieve ES entry-points */ 2753 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2754 2755 /* Reset OpenGL ES state */ 2756 gl.useProgram(0); 2757 gl.bindVertexArray(0); 2758 gl.bindTexture(GL_TEXTURE_2D, 0); 2759 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 2760 2761 /* Delete everything */ 2762 if (m_program_object_id_for_multiple_invocations_pass != 0) 2763 { 2764 gl.deleteProgram(m_program_object_id_for_multiple_invocations_pass); 2765 2766 m_program_object_id_for_multiple_invocations_pass = 0; 2767 } 2768 2769 if (m_fragment_shader_id_for_multiple_invocations_pass != 0) 2770 { 2771 gl.deleteShader(m_fragment_shader_id_for_multiple_invocations_pass); 2772 2773 m_fragment_shader_id_for_multiple_invocations_pass = 0; 2774 } 2775 2776 if (m_geometry_shader_id_for_multiple_invocations_pass != 0) 2777 { 2778 gl.deleteShader(m_geometry_shader_id_for_multiple_invocations_pass); 2779 2780 m_geometry_shader_id_for_multiple_invocations_pass = 0; 2781 } 2782 2783 if (m_vertex_shader_id_for_multiple_invocations_pass != 0) 2784 { 2785 gl.deleteShader(m_vertex_shader_id_for_multiple_invocations_pass); 2786 2787 m_vertex_shader_id_for_multiple_invocations_pass = 0; 2788 } 2789 2790 if (m_program_object_id_for_single_invocation_pass != 0) 2791 { 2792 gl.deleteProgram(m_program_object_id_for_single_invocation_pass); 2793 2794 m_program_object_id_for_single_invocation_pass = 0; 2795 } 2796 2797 if (m_fragment_shader_id_for_single_invocation_pass != 0) 2798 { 2799 gl.deleteShader(m_fragment_shader_id_for_single_invocation_pass); 2800 2801 m_fragment_shader_id_for_single_invocation_pass = 0; 2802 } 2803 2804 if (m_geometry_shader_id_for_single_invocation_pass != 0) 2805 { 2806 gl.deleteShader(m_geometry_shader_id_for_single_invocation_pass); 2807 2808 m_geometry_shader_id_for_single_invocation_pass = 0; 2809 } 2810 2811 if (m_vertex_shader_id_for_single_invocation_pass != 0) 2812 { 2813 gl.deleteShader(m_vertex_shader_id_for_single_invocation_pass); 2814 2815 m_vertex_shader_id_for_single_invocation_pass = 0; 2816 } 2817 2818 if (m_vertex_array_object_id != 0) 2819 { 2820 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 2821 2822 m_vertex_array_object_id = 0; 2823 } 2824 2825 if (m_color_texture_id != 0) 2826 { 2827 gl.deleteTextures(1, &m_color_texture_id); 2828 2829 m_color_texture_id = 0; 2830 } 2831 2832 if (m_framebuffer_object_id != 0) 2833 { 2834 gl.deleteFramebuffers(1, &m_framebuffer_object_id); 2835 2836 m_framebuffer_object_id = 0; 2837 } 2838 2839 /* Deinitilize base class */ 2840 TestCaseBase::deinit(); 2841} 2842 2843/** Verify image rendered during draw call for multiple invocations pass 2844 * 2845 * @param result_image Image data 2846 * 2847 * @return true When image is as expected 2848 * false When image is wrong 2849 **/ 2850bool GeometryShaderMaxInvocationsTest::verifyResultOfMultipleInvocationsPass(unsigned char* result_image) 2851{ 2852 for (unsigned int i = 0; i < (unsigned int)m_max_geometry_shader_invocations; ++i) 2853 { 2854 /* Verify that pixel at triangle's center was modified */ 2855 const unsigned int x1 = m_triangle_edge_length * i; 2856 const unsigned int x2 = m_triangle_edge_length * i; 2857 const unsigned int x3 = m_triangle_edge_length * (i + 1) - 1; 2858 2859 const unsigned int y1 = 0; 2860 const unsigned int y2 = m_triangle_edge_length - 1; 2861 const unsigned int y3 = m_triangle_edge_length - 1; 2862 2863 const unsigned int center_x = (x1 + x2 + x3) / 3; 2864 const unsigned int center_y = (y1 + y2 + y3) / 3; 2865 2866 bool is_pixel_valid = comparePixel(result_image, center_x, center_y, m_texture_width, m_texture_height, 2867 m_texture_pixel_size, 0, 255, 0, 0); 2868 2869 if (false == is_pixel_valid) 2870 { 2871 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at " 2872 "[" 2873 << center_x << ";" << center_y << "]! " 2874 "Triangle index: " 2875 << i << " from range <0:" << m_max_geometry_shader_invocations << ")." 2876 << tcu::TestLog::EndMessage; 2877 2878 return false; 2879 } 2880 2881 /* Verify that background's pixel was not modified */ 2882 const unsigned int x4 = m_triangle_edge_length * (i + 1) - 1; 2883 const unsigned int y4 = m_triangle_edge_length - 1; 2884 2885 is_pixel_valid = 2886 comparePixel(result_image, x4, y4, m_texture_width, m_texture_height, m_texture_pixel_size, 255, 0, 0, 0); 2887 2888 if (false == is_pixel_valid) 2889 { 2890 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << x4 << ";" << y4 2891 << "]! " 2892 "Background for index: " 2893 << i << "from range <0:" << m_max_geometry_shader_invocations << ")." 2894 << tcu::TestLog::EndMessage; 2895 2896 return false; 2897 } 2898 } 2899 2900 return true; 2901} 2902 2903/** Verify image rendered during draw call for single invocation pass 2904 * 2905 * @param result_image Image data 2906 * 2907 * @return true When image is as expected 2908 * false When image is wrong 2909 **/ 2910bool GeometryShaderMaxInvocationsTest::verifyResultOfSingleInvocationPass(unsigned char* result_image) 2911{ 2912 /* Only one triangle should be drawn, verify that pixel at its center was modified */ 2913 { 2914 const unsigned int x1 = 0; 2915 const unsigned int x2 = 0; 2916 const unsigned int x3 = m_triangle_edge_length - 1; 2917 2918 const unsigned int y1 = 0; 2919 const unsigned int y2 = m_triangle_edge_length - 1; 2920 const unsigned int y3 = m_triangle_edge_length - 1; 2921 2922 const unsigned int center_x = (x1 + x2 + x3) / 3; 2923 const unsigned int center_y = (y1 + y2 + y3) / 3; 2924 2925 bool is_pixel_valid = comparePixel(result_image, center_x, center_y, m_texture_width, m_texture_height, 2926 m_texture_pixel_size, 0, 255, 0, 0); 2927 2928 if (false == is_pixel_valid) 2929 { 2930 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << center_x << ";" << center_y 2931 << "]! " 2932 "Triangle index: " 2933 << 0 << " from range <0:" << m_max_geometry_shader_invocations << ")." 2934 << tcu::TestLog::EndMessage; 2935 2936 return false; 2937 } 2938 2939 /* Verify that background's pixel was not modified */ 2940 const unsigned int x4 = m_triangle_edge_length - 1; 2941 const unsigned int y4 = m_triangle_edge_length - 1; 2942 2943 is_pixel_valid = 2944 comparePixel(result_image, x4, y4, m_texture_width, m_texture_height, m_texture_pixel_size, 255, 0, 0, 0); 2945 2946 if (false == is_pixel_valid) 2947 { 2948 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << x4 << ";" << y4 2949 << "]! " 2950 "Background for index: " 2951 << 0 << " from range <0:" << m_max_geometry_shader_invocations << ")." 2952 << tcu::TestLog::EndMessage; 2953 2954 return false; 2955 } 2956 } 2957 2958 for (unsigned int i = 1; i < (unsigned int)m_max_geometry_shader_invocations; ++i) 2959 { 2960 /* Verify that pixel at triangle's center was not modified */ 2961 const unsigned int x1 = m_triangle_edge_length * i; 2962 const unsigned int x2 = m_triangle_edge_length * i; 2963 const unsigned int x3 = m_triangle_edge_length * (i + 1) - 1; 2964 2965 const unsigned int y1 = 0; 2966 const unsigned int y2 = m_triangle_edge_length - 1; 2967 const unsigned int y3 = m_triangle_edge_length - 1; 2968 2969 const unsigned int center_x = (x1 + x2 + x3) / 3; 2970 const unsigned int center_y = (y1 + y2 + y3) / 3; 2971 2972 bool is_pixel_valid = comparePixel(result_image, center_x, center_y, m_texture_width, m_texture_height, 2973 m_texture_pixel_size, 255, 0, 0, 0); 2974 2975 if (false == is_pixel_valid) 2976 { 2977 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << center_x << ";" << center_y 2978 << "]! " 2979 "Triangle index: " 2980 << i << " from range <0:" << m_max_geometry_shader_invocations << ")." 2981 << tcu::TestLog::EndMessage; 2982 2983 return false; 2984 } 2985 2986 /* Verify that background's pixel was not modified */ 2987 const unsigned int x4 = m_triangle_edge_length * (i + 1) - 1; 2988 const unsigned int y4 = m_triangle_edge_length - 1; 2989 2990 is_pixel_valid = 2991 comparePixel(result_image, x4, y4, m_texture_width, m_texture_height, m_texture_pixel_size, 255, 0, 0, 0); 2992 2993 if (false == is_pixel_valid) 2994 { 2995 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << x4 << ";" << y4 2996 << "]! " 2997 "Background for index: " 2998 << i << " from range <0:" << m_max_geometry_shader_invocations << ")." 2999 << tcu::TestLog::EndMessage; 3000 3001 return false; 3002 } 3003 } 3004 3005 return true; 3006} 3007 3008/** Constructor 3009 * 3010 * @param context Test context 3011 * @param name Test case's name 3012 * @param description Test case's description 3013 **/ 3014GeometryShaderMaxCombinedTextureUnitsTest::GeometryShaderMaxCombinedTextureUnitsTest(Context& context, 3015 const ExtParameters& extParams, 3016 const char* name, 3017 const char* description) 3018 : GeometryShaderLimitsRenderingBase(context, extParams, name, description) 3019 , m_texture_width(0) 3020 , m_max_combined_texture_units(0) 3021 , m_max_fragment_texture_units(0) 3022 , m_max_geometry_texture_units(0) 3023 , m_max_vertex_texture_units(0) 3024 , m_min_texture_units(0) 3025 , m_n_fragment_texture_units(0) 3026 , m_n_geometry_texture_units(0) 3027 , m_n_texture_units(0) 3028 , m_n_vertex_texture_units(0) 3029{ 3030 /* Nothing to be done here */ 3031} 3032 3033/** Clears data after draw call and result verification 3034 * 3035 **/ 3036void GeometryShaderMaxCombinedTextureUnitsTest::clean() 3037{ 3038 /* GL functions */ 3039 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3040 3041 /* Bind 0 to all texture units */ 3042 for (int i = 0; i < m_n_texture_units; ++i) 3043 { 3044 gl.activeTexture(GL_TEXTURE0 + i); 3045 gl.bindTexture(GL_TEXTURE_2D, 0); 3046 } 3047 3048 /* Delete textures */ 3049 for (int i = 0; i < m_n_texture_units; ++i) 3050 { 3051 gl.deleteTextures(1, &m_textures[i].texture_id); 3052 } 3053 3054 m_textures.clear(); 3055} 3056 3057/** Get details for draw call 3058 * 3059 * @param out_primitive_type Type of primitive that will be used by next draw call 3060 * @param out_n_vertices Number of vertices that will used with next draw call 3061 **/ 3062void GeometryShaderMaxCombinedTextureUnitsTest::getDrawCallDetails(glw::GLenum& out_primitive_type, 3063 glw::GLuint& out_n_vertices) 3064{ 3065 /* Draw GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT points */ 3066 out_primitive_type = GL_POINTS; 3067 out_n_vertices = m_min_texture_units; 3068} 3069 3070/** Get dimensions and format for texture bind to color attachment 0, get format and type for glReadPixels 3071 * 3072 * @param out_texture_format Format for texture used as color attachment 0 3073 * @param out_texture_read_format Format of data used with glReadPixels 3074 * @param out_texture_read_type Type of data used with glReadPixels 3075 * @param out_texture_width Width of texture used as color attachment 0 3076 * @param out_texture_height Height of texture used as color attachment 0 3077 * @param out_texture_pixel_size Size of single pixel in bytes 3078 **/ 3079void GeometryShaderMaxCombinedTextureUnitsTest::getFramebufferDetails( 3080 glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format, glw::GLenum& out_texture_read_type, 3081 glw::GLuint& out_texture_width, glw::GLuint& out_texture_height, unsigned int& out_texture_pixel_size) 3082{ 3083 out_texture_format = GL_R32UI; 3084 out_texture_read_format = GL_RGBA_INTEGER; 3085 out_texture_read_type = GL_UNSIGNED_INT; 3086 out_texture_width = m_texture_width; 3087 out_texture_height = m_texture_height; 3088 out_texture_pixel_size = 4 * 4; 3089} 3090 3091void GeometryShaderMaxCombinedTextureUnitsTest::getRequiredPointSize(glw::GLfloat& out_point_size) 3092{ 3093 out_point_size = (float)m_point_size; 3094} 3095 3096/** Get parts of shaders 3097 * 3098 * @param out_fragment_shader_parts Array of fragment shader parts 3099 * @param out_n_fragment_shader_parts Number of fragment shader parts 3100 * @param out_geometry_shader_parts Array of geometry shader parts 3101 * @param out_n_geometry_shader_parts Number of geometry shader parts 3102 * @param out_vertex_shader_parts Array of vertex shader parts 3103 * @param out_n_vertex_shader_parts Number of vertex shader parts 3104 **/ 3105void GeometryShaderMaxCombinedTextureUnitsTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 3106 unsigned int& out_n_fragment_shader_parts, 3107 const glw::GLchar* const*& out_geometry_shader_parts, 3108 unsigned int& out_n_geometry_shader_parts, 3109 const glw::GLchar* const*& out_vertex_shader_parts, 3110 unsigned int& out_n_vertex_shader_parts) 3111{ 3112 /* GL functions */ 3113 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3114 3115 /* Get maximum number of texture units */ 3116 gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &m_max_combined_texture_units); 3117 gl.getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &m_max_vertex_texture_units); 3118 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &m_max_geometry_texture_units); 3119 gl.getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_max_fragment_texture_units); 3120 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed"); 3121 3122 m_n_texture_units = 3123 de::max(m_max_vertex_texture_units, de::max(m_max_geometry_texture_units, m_max_fragment_texture_units)); 3124 m_n_vertex_texture_units = de::max(1, de::min(m_max_combined_texture_units - 2, m_max_vertex_texture_units)); 3125 m_n_fragment_texture_units = 3126 de::max(1, de::min(m_max_combined_texture_units - m_n_vertex_texture_units - 1, m_max_fragment_texture_units)); 3127 m_n_geometry_texture_units = 3128 de::max(1, de::min(m_max_combined_texture_units - m_n_vertex_texture_units - m_n_fragment_texture_units, 3129 m_max_geometry_texture_units)); 3130 m_min_texture_units = 3131 de::min(m_n_vertex_texture_units, de::min(m_n_fragment_texture_units, m_n_geometry_texture_units)); 3132 3133 /* Number of drawn points is equal to GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ 3134 m_texture_width = m_n_texture_units * m_point_size; 3135 3136 /* Prepare texture units string */ 3137 std::stringstream stream_fragment; 3138 stream_fragment << m_n_fragment_texture_units; 3139 m_n_fragment_texture_units_string = stream_fragment.str(); 3140 3141 std::stringstream stream_geometry; 3142 stream_geometry << m_n_geometry_texture_units; 3143 m_n_geometry_texture_units_string = stream_geometry.str(); 3144 3145 std::stringstream stream_vertex; 3146 stream_vertex << m_n_vertex_texture_units; 3147 m_n_vertex_texture_units_string = stream_vertex.str(); 3148 3149 /* Fragment shader parts */ 3150 m_fragment_shader_parts[0] = m_fragment_shader_code_preamble; 3151 m_fragment_shader_parts[1] = m_n_fragment_texture_units_string.c_str(); 3152 m_fragment_shader_parts[2] = m_fragment_shader_code_body; 3153 3154 out_fragment_shader_parts = m_fragment_shader_parts; 3155 out_n_fragment_shader_parts = 3; 3156 3157 /* Geometry shader parts */ 3158 m_geometry_shader_parts[0] = m_geometry_shader_code_preamble; 3159 m_geometry_shader_parts[1] = m_n_geometry_texture_units_string.c_str(); 3160 m_geometry_shader_parts[2] = m_geometry_shader_code_body; 3161 3162 out_geometry_shader_parts = m_geometry_shader_parts; 3163 out_n_geometry_shader_parts = 3; 3164 3165 /* Vertex shader parts */ 3166 m_vertex_shader_parts[0] = m_vertex_shader_code_preamble; 3167 m_vertex_shader_parts[1] = m_n_vertex_texture_units_string.c_str(); 3168 m_vertex_shader_parts[2] = m_vertex_shader_code_body; 3169 3170 out_vertex_shader_parts = m_vertex_shader_parts; 3171 out_n_vertex_shader_parts = 3; 3172} 3173 3174/** Prepare test specific program input for draw call 3175 * 3176 **/ 3177void GeometryShaderMaxCombinedTextureUnitsTest::prepareProgramInput() 3178{ 3179 /* Retrieve ES entry-points */ 3180 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3181 3182 m_textures.resize(m_n_texture_units); 3183 3184 /* Prepare texture storage and fill data */ 3185 for (int i = 0; i < m_n_texture_units; ++i) 3186 { 3187 /* Reset texture data to 0 after each 16 iterations */ 3188 m_textures[i].data = i % 16; 3189 3190 /* Generate and bind texture */ 3191 gl.genTextures(1, &m_textures[i].texture_id); 3192 gl.bindTexture(GL_TEXTURE_2D, m_textures[i].texture_id); 3193 3194 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create texture"); 3195 3196 /* Allocate and upload texture data */ 3197 gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, GL_R32UI, 1 /* width*/, 1 /* height */, 0 /* border */, 3198 GL_RED_INTEGER, GL_UNSIGNED_INT, &m_textures[i].data); 3199 3200 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3201 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3202 3203 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create storage and fill texture with data"); 3204 } 3205 3206 /* Prepare sampler uniforms */ 3207 for (int i = 0; i < m_n_texture_units; ++i) 3208 { 3209 /* Prepare name of sampler */ 3210 std::stringstream stream; 3211 3212 stream << "sampler[" << i << "]"; 3213 3214 /* Get sampler location */ 3215 glw::GLint sampler_location = gl.getUniformLocation(m_program_object_id, stream.str().c_str()); 3216 3217 if (-1 == sampler_location || GL_NO_ERROR != gl.getError()) 3218 { 3219 TCU_FAIL("Failed to get uniform usampler2D location"); 3220 } 3221 3222 /* Set uniform at sampler location value to index of texture unit */ 3223 gl.uniform1i(sampler_location, i); 3224 3225 if (GL_NO_ERROR != gl.getError()) 3226 { 3227 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to set uniform at location: " << sampler_location 3228 << " to value: " << i << tcu::TestLog::EndMessage; 3229 3230 TCU_FAIL("Failed to get uniform isampler2D location"); 3231 } 3232 } 3233 3234 /* Bind textures to texture units */ 3235 for (int i = 0; i < m_n_texture_units; ++i) 3236 { 3237 gl.activeTexture(GL_TEXTURE0 + i); 3238 gl.bindTexture(GL_TEXTURE_2D, m_textures[i].texture_id); 3239 3240 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3241 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3242 } 3243 3244 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set texture units up"); 3245} 3246 3247/** Verify rendered image 3248 * 3249 * @param data Image to verify 3250 * 3251 * @return true Image pixels match expected values 3252 * false Some pixels have wrong values 3253 **/ 3254bool GeometryShaderMaxCombinedTextureUnitsTest::verifyResult(const void* data) 3255{ 3256 const unsigned char* result_image = (const unsigned char*)data; 3257 const unsigned int line_size = m_texture_width * m_texture_pixel_size; 3258 3259 /* For each drawn point */ 3260 for (glw::GLint point = 0; point < m_n_texture_units; ++point) 3261 { 3262 const unsigned int last_vertex_index = de::min(point, m_n_vertex_texture_units); 3263 3264 glw::GLint expected_vertex_value = 0; 3265 glw::GLint expected_geometry_value = 0; 3266 glw::GLint expected_fragment_value = 0; 3267 3268 for (unsigned int i = 0; i < last_vertex_index; ++i) 3269 { 3270 expected_vertex_value += m_textures[i].data; 3271 } 3272 3273 for (unsigned int i = 0; i < last_vertex_index; ++i) 3274 { 3275 expected_geometry_value += m_textures[i].data; 3276 } 3277 3278 for (unsigned int i = 0; i < last_vertex_index; ++i) 3279 { 3280 expected_fragment_value += m_textures[i].data; 3281 } 3282 3283 const glw::GLint expected_value = expected_vertex_value + expected_geometry_value + expected_fragment_value; 3284 const unsigned int point_offset = point * m_texture_pixel_size * m_point_size; 3285 3286 /* Verify all pixels that belong to point, area m_point_size x m_point_size */ 3287 for (unsigned int y = 0; y < m_point_size; ++y) 3288 { 3289 const unsigned int line_offset = y * line_size; 3290 const unsigned int first_texel_offset = line_offset + point_offset; 3291 3292 for (unsigned int x = 0; x < m_point_size; ++x) 3293 { 3294 const unsigned int texel_offset = first_texel_offset + x * m_texture_pixel_size; 3295 3296 if (0 != memcmp(result_image + texel_offset, &expected_value, sizeof(expected_value))) 3297 { 3298 glw::GLint* result_value = (glw::GLint*)(result_image + texel_offset); 3299 3300 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result!" 3301 " Expected: " 3302 << expected_value << " Extracted: " << *result_value << " Point: " << point 3303 << " X: " << x << " Y: " << y << tcu::TestLog::EndMessage; 3304 3305 return false; 3306 } 3307 } 3308 } 3309 } 3310 3311 return true; 3312} 3313 3314} /* glcts */ 3315