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 39 namespace glcts 40 { 41 /* Vertex Shader for GeometryShaderMaxUniformComponentsTest */ 42 const 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 */ 53 const 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 63 const glw::GLchar* const GeometryShaderMaxUniformComponentsTest::m_geometry_shader_code_number_of_uniforms = 64 "#define NUMBER_OF_UNIFORMS "; 65 66 const 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 */ 90 const 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 */ 102 const 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 */ 113 const 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 123 const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_geometry_shader_code_number_of_uniforms = 124 "#define NUMBER_OF_UNIFORM_BLOCKS "; 125 126 const 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 141 const 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 */ 148 const 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 */ 160 const 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 167 const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_vertex_shader_code_number_of_uniforms = 168 "#define NUMBER_OF_GEOMETRY_INPUT_VECTORS "; 169 170 const 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 */ 190 const 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 200 const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_geometry_shader_code_number_of_uniforms = 201 "#define NUMBER_OF_GEOMETRY_INPUT_VECTORS "; 202 203 const 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 */ 230 const 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 */ 242 const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_common_shader_code_gs_fs_out = "gs_fs_out_"; 243 244 const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_common_shader_code_number_of_points = 245 "#define NUMBER_OF_POINTS "; 246 247 const 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 */ 251 const 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 */ 262 const 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 270 const 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 277 const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_geometry_shader_code_flat_out_ivec4 = 278 "flat out ivec4"; 279 280 const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_geometry_shader_code_assignment = 281 " = ivec4(index++, index++, index++, index++);\n"; 282 283 const 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 293 const 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 */ 305 const 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 312 const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_fragment_shader_code_flat_in_ivec4 = "flat in ivec4"; 313 314 const glw::GLchar* const GeometryShaderMaxOutputComponentsTest::m_fragment_shader_code_sum = "sum += "; 315 316 const 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 326 const 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 */ 332 const 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 */ 343 const 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 351 const 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 */ 370 const 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 */ 386 const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_common_shader_code_gs_fs_out = 387 "gs_fs_out_"; 388 389 const 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 */ 393 const 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 */ 404 const 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 414 const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_geometry_shader_code_flat_out_ivec4 = 415 "flat out ivec4"; 416 417 const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_geometry_shader_code_assignment = 418 " = ivec4(index++, index++, index++, index++);\n"; 419 420 const 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 428 const 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 */ 438 const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_fragment_shader_code_preamble = 439 "${VERSION}\n" 440 "\n" 441 "${GEOMETRY_SHADER_REQUIRE}\n" 442 "\n"; 443 444 const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_fragment_shader_code_flat_in_ivec4 = 445 "flat in ivec4"; 446 447 const glw::GLchar* const GeometryShaderMaxOutputComponentsSinglePointTest::m_fragment_shader_code_sum = "sum += "; 448 449 const 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 459 const 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 */ 466 const 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 475 const 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 */ 488 const 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 502 const 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 */ 539 const 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 */ 556 const 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 */ 569 const 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 578 const 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 584 const glw::GLchar* const GeometryShaderMaxInvocationsTest::m_geometry_shader_code_layout_invocations = 585 "layout(invocations = GEOMETRY_SHADER_INVOCATIONS) in;\n"; 586 587 const 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 */ 604 const 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 */ 620 const 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 630 const 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 */ 654 const 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 667 const 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 */ 696 const 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 707 const 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 */ 730 const unsigned int GeometryShaderMaxUniformComponentsTest::m_buffer_size = sizeof(glw::GLint); 731 const glw::GLchar* const GeometryShaderMaxUniformComponentsTest::m_captured_varyings_names = "gs_out_sum"; 732 733 /* Constants for GeometryShaderMaxUniformBlocksTest */ 734 const unsigned int GeometryShaderMaxUniformBlocksTest::m_buffer_size = sizeof(glw::GLint); 735 const glw::GLchar* const GeometryShaderMaxUniformBlocksTest::m_captured_varyings_names = "gs_out_sum"; 736 737 /* Constants for GeometryShaderMaxInputComponentsTest */ 738 const unsigned int GeometryShaderMaxInputComponentsTest::m_buffer_size = sizeof(glw::GLint); 739 const glw::GLchar* const GeometryShaderMaxInputComponentsTest::m_captured_varyings_names = "gs_out_sum"; 740 741 /* Constants for GeometryShaderMaxOutputComponentsTest */ 742 const unsigned int GeometryShaderMaxOutputComponentsTest::m_point_size = 2; 743 const unsigned int GeometryShaderMaxOutputComponentsTest::m_texture_height = m_point_size; 744 const unsigned int GeometryShaderMaxOutputComponentsTest::m_texture_pixel_size = 4 * sizeof(glw::GLint); 745 746 /* Constants for GeometryShaderMaxOutputComponentsSinglePointTest */ 747 const unsigned int GeometryShaderMaxOutputComponentsSinglePointTest::m_point_size = 2; 748 const unsigned int GeometryShaderMaxOutputComponentsSinglePointTest::m_texture_height = m_point_size; 749 const unsigned int GeometryShaderMaxOutputComponentsSinglePointTest::m_texture_pixel_size = 4 * sizeof(glw::GLint); 750 const unsigned int GeometryShaderMaxOutputComponentsSinglePointTest::m_texture_width = m_point_size; 751 752 /* Constants for GeometryShaderMaxTextureUnitsTest */ 753 const unsigned int GeometryShaderMaxTextureUnitsTest::m_point_size = 2; 754 const unsigned int GeometryShaderMaxTextureUnitsTest::m_texture_height = m_point_size; 755 const unsigned int GeometryShaderMaxTextureUnitsTest::m_texture_pixel_size = 4 * sizeof(glw::GLint); 756 757 /* Constants for GeometryShaderMaxInvocationsTest */ 758 const unsigned int GeometryShaderMaxInvocationsTest::m_triangle_edge_length = 9; 759 const unsigned int GeometryShaderMaxInvocationsTest::m_texture_height = m_triangle_edge_length; 760 const unsigned int GeometryShaderMaxInvocationsTest::m_texture_pixel_size = 4 * sizeof(glw::GLubyte); 761 762 /* Constants for GeometryShaderMaxCombinedTextureUnitsTest */ 763 const unsigned int GeometryShaderMaxCombinedTextureUnitsTest::m_point_size = 1; 764 const unsigned int GeometryShaderMaxCombinedTextureUnitsTest::m_texture_height = m_point_size; 765 const 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 **/ 773 GeometryShaderLimitsTransformFeedbackBase::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 */ 800 void 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 **/ 867 tcu::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 */ 934 void 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 **/ 999 GeometryShaderLimitsRenderingBase::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 */ 1028 void 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 **/ 1129 tcu::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 */ 1186 void 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 **/ 1261 GeometryShaderMaxUniformComponentsTest::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 **/ 1276 void 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 **/ 1286 void 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 **/ 1305 void 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 **/ 1347 void 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 **/ 1355 void 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 **/ 1395 bool 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 **/ 1423 GeometryShaderMaxUniformBlocksTest::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 **/ 1433 void 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 **/ 1463 void 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 **/ 1482 void 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 **/ 1533 void 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 **/ 1541 void 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 **/ 1580 bool 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 **/ 1608 GeometryShaderMaxInputComponentsTest::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 **/ 1621 void 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 **/ 1631 void 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 **/ 1650 void 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 **/ 1697 void 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 **/ 1705 void 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 **/ 1718 bool 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 **/ 1746 GeometryShaderMaxOutputComponentsTest::GeometryShaderMaxOutputComponentsTest(Context& context, 1747 const ExtParameters& extParams, 1748 const char* name, const char* description) 1749 : GeometryShaderLimitsRenderingBase(context, extParams, name, description) 1750 , m_texture_width(0) 1751 , m_max_output_components(0) 1752 , m_max_output_vectors(0) 1753 , m_max_total_output_components(0) 1754 , m_n_available_vectors(0) 1755 , m_n_output_points(0) 1756 { 1757 /* Nothing to be done here */ 1758 } 1759 1760 /** Clears data after draw call and result verification 1761 * 1762 **/ 1763 void GeometryShaderMaxOutputComponentsTest::clean() 1764 { 1765 /* Nothing to be done here */ 1766 } 1767 1768 /** Get details for draw call 1769 * 1770 * @param out_primitive_type Type of primitive that will be used by next draw call 1771 * @param out_n_vertices Number of vertices that will used with next draw call 1772 **/ 1773 void GeometryShaderMaxOutputComponentsTest::getDrawCallDetails(glw::GLenum& out_primitive_type, 1774 glw::GLuint& out_n_vertices) 1775 { 1776 /* Draw one point */ 1777 out_primitive_type = GL_POINTS; 1778 out_n_vertices = 1; 1779 } 1780 1781 /** Get dimensions and format for texture bind to color attachment 0, get format and type for glReadPixels 1782 * 1783 * @param out_texture_format Format for texture used as color attachment 0 1784 * @param out_texture_read_format Format of data used with glReadPixels 1785 * @param out_texture_read_type Type of data used with glReadPixels 1786 * @param out_texture_width Width of texture used as color attachment 0 1787 * @param out_texture_height Height of texture used as color attachment 0 1788 * @param out_texture_pixel_size Size of single pixel in bytes 1789 **/ 1790 void GeometryShaderMaxOutputComponentsTest::getFramebufferDetails( 1791 glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format, glw::GLenum& out_texture_read_type, 1792 glw::GLuint& out_texture_width, glw::GLuint& out_texture_height, unsigned int& out_texture_pixel_size) 1793 { 1794 out_texture_format = GL_R32I; 1795 out_texture_read_format = GL_RGBA_INTEGER; 1796 out_texture_read_type = GL_INT; 1797 out_texture_width = m_texture_width; 1798 out_texture_height = m_texture_height; 1799 out_texture_pixel_size = 4 * 4; 1800 } 1801 1802 void GeometryShaderMaxOutputComponentsTest::getRequiredPointSize(glw::GLfloat& out_point_size) 1803 { 1804 /* This test should only run if EXT_geometry_point_size is supported */ 1805 if (!m_is_geometry_shader_point_size_supported) 1806 { 1807 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 1808 } 1809 1810 out_point_size = (float)m_point_size; 1811 } 1812 1813 /** Get parts of shaders 1814 * 1815 * @param out_fragment_shader_parts Array of fragment shader parts 1816 * @param out_n_fragment_shader_parts Number of fragment shader parts 1817 * @param out_geometry_shader_parts Array of geometry shader parts 1818 * @param out_n_geometry_shader_parts Number of geometry shader parts 1819 * @param out_vertex_shader_parts Array of vertex shader parts 1820 * @param out_n_vertex_shader_parts Number of vertex shader parts 1821 **/ 1822 void GeometryShaderMaxOutputComponentsTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 1823 unsigned int& out_n_fragment_shader_parts, 1824 const glw::GLchar* const*& out_geometry_shader_parts, 1825 unsigned int& out_n_geometry_shader_parts, 1826 const glw::GLchar* const*& out_vertex_shader_parts, 1827 unsigned int& out_n_vertex_shader_parts) 1828 { 1829 /* GL functions */ 1830 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1831 1832 /* Get maximum number of output components */ 1833 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &m_max_total_output_components); 1834 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_COMPONENTS, &m_max_output_components); 1835 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed"); 1836 1837 m_n_output_points = m_max_total_output_components / m_max_output_components; 1838 m_max_output_vectors = m_max_output_components / 4; /* 4 components per vector */ 1839 m_n_available_vectors = m_max_output_vectors - 2; /* 2 vectors are reserved for gl_Position and gl_PointSize */ 1840 1841 /* Framebuffer width */ 1842 m_texture_width = m_point_size * m_n_output_points; 1843 1844 /* Fragment shader parts */ 1845 prepareFragmentShader(m_fragment_shader_code); 1846 1847 m_fragment_shader_code_c_str = m_fragment_shader_code.c_str(); 1848 out_fragment_shader_parts = &m_fragment_shader_code_c_str; 1849 out_n_fragment_shader_parts = 1; 1850 1851 /* Geometry shader parts */ 1852 prepareGeometryShader(m_geometry_shader_code); 1853 1854 m_geometry_shader_code_c_str = m_geometry_shader_code.c_str(); 1855 out_geometry_shader_parts = &m_geometry_shader_code_c_str; 1856 out_n_geometry_shader_parts = 1; 1857 1858 /* Vertex shader */ 1859 out_vertex_shader_parts = &m_vertex_shader_code; 1860 out_n_vertex_shader_parts = 1; 1861 } 1862 1863 /** Prepare test specific program input for draw call 1864 * 1865 **/ 1866 void GeometryShaderMaxOutputComponentsTest::prepareProgramInput() 1867 { 1868 /* Nothing to be done here */ 1869 } 1870 1871 /** Verify rendered image 1872 * 1873 * @param data Image to verify 1874 * 1875 * @return true Image pixels match expected values 1876 * false Some pixels have wrong values 1877 **/ 1878 bool GeometryShaderMaxOutputComponentsTest::verifyResult(const void* data) 1879 { 1880 const unsigned char* result_image = (const unsigned char*)data; 1881 const unsigned int line_size = m_texture_width * m_texture_pixel_size; 1882 const glw::GLint n_components_per_point = m_n_available_vectors * 4; /* 4 components per vector */ 1883 1884 /* For each drawn point */ 1885 for (glw::GLint point = 0; point < m_n_output_points; ++point) 1886 { 1887 const glw::GLint first_value = point * n_components_per_point + 1; 1888 const glw::GLint last_value = (point + 1) * n_components_per_point; 1889 const glw::GLint expected_value = ((first_value + last_value) * n_components_per_point) / 2; 1890 const unsigned int point_offset = point * m_texture_pixel_size * m_point_size; 1891 1892 /* Verify all pixels that belong to point, area m_point_size x m_point_size */ 1893 for (unsigned int y = 0; y < m_point_size; ++y) 1894 { 1895 const unsigned int line_offset = y * line_size; 1896 const unsigned int first_texel_offset = line_offset + point_offset; 1897 1898 for (unsigned int x = 0; x < m_point_size; ++x) 1899 { 1900 const unsigned int texel_offset = first_texel_offset + x * m_texture_pixel_size; 1901 1902 if (0 != memcmp(result_image + texel_offset, &expected_value, sizeof(expected_value))) 1903 { 1904 glw::GLint* result_value = (glw::GLint*)(result_image + texel_offset); 1905 1906 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! Expected: " << expected_value 1907 << " Extracted: " << *result_value << " Point: " << point << " X: " << x 1908 << " Y: " << y << tcu::TestLog::EndMessage; 1909 1910 return false; 1911 } 1912 } 1913 } 1914 } 1915 1916 return true; 1917 } 1918 1919 /** Prepare fragment shader code 1920 * 1921 * @param out_shader_code String that will be used to store shaders code 1922 **/ 1923 void GeometryShaderMaxOutputComponentsTest::prepareFragmentShader(std::string& out_shader_code) const 1924 { 1925 std::stringstream stream; 1926 1927 stream << m_fragment_shader_code_preamble; 1928 stream << m_common_shader_code_gs_fs_out_definitions; 1929 1930 for (int i = 0; i < m_n_available_vectors; ++i) 1931 { 1932 stream << m_fragment_shader_code_flat_in_ivec4 << " " << m_common_shader_code_gs_fs_out << i << ";\n"; 1933 } 1934 1935 stream << m_fragment_shader_code_body_begin; 1936 1937 for (int i = 0; i < m_n_available_vectors; ++i) 1938 { 1939 stream << " " << m_fragment_shader_code_sum << m_common_shader_code_gs_fs_out << i << ".x + " 1940 << m_common_shader_code_gs_fs_out << i << ".y + " << m_common_shader_code_gs_fs_out << i << ".z + " 1941 << m_common_shader_code_gs_fs_out << i << ".w;\n"; 1942 } 1943 1944 stream << m_fragment_shader_code_body_end; 1945 1946 out_shader_code = stream.str(); 1947 } 1948 1949 /** Prepare geometry shader code 1950 * 1951 * @param out_shader_code String that will be used to store shaders code 1952 **/ 1953 void GeometryShaderMaxOutputComponentsTest::prepareGeometryShader(std::string& out_shader_code) const 1954 { 1955 std::stringstream stream; 1956 1957 stream << m_geometry_shader_code_preamble; 1958 stream << m_common_shader_code_number_of_points; 1959 stream << m_n_output_points; 1960 stream << m_geometry_shader_code_layout; 1961 stream << m_common_shader_code_gs_fs_out_definitions; 1962 1963 for (int i = 0; i < m_n_available_vectors; ++i) 1964 { 1965 stream << m_geometry_shader_code_flat_out_ivec4 << " " << m_common_shader_code_gs_fs_out << i << ";\n"; 1966 } 1967 1968 stream << m_geometry_shader_code_body_begin; 1969 1970 for (int i = 0; i < m_n_available_vectors; ++i) 1971 { 1972 stream << " " << m_common_shader_code_gs_fs_out << i << m_geometry_shader_code_assignment; 1973 } 1974 1975 stream << m_geometry_shader_code_body_end; 1976 1977 out_shader_code = stream.str(); 1978 } 1979 1980 /** Constructor 1981 * 1982 * @param context Test context 1983 * @param name Test case's name 1984 * @param description Test case's description 1985 **/ 1986 GeometryShaderMaxOutputVerticesTest::GeometryShaderMaxOutputVerticesTest(Context& context, 1987 const ExtParameters& extParams, 1988 const char* name, const char* description) 1989 : TestCaseBase(context, extParams, name, description) 1990 { 1991 /* Nothing to be done here */ 1992 } 1993 1994 /** Executes the test. 1995 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 1996 * 1997 * Note the function throws exception should an error occur! 1998 * 1999 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 2000 * 2001 **/ 2002 tcu::TestCase::IterateResult GeometryShaderMaxOutputVerticesTest::iterate() 2003 { 2004 /* This test should only run if EXT_geometry_shader is supported */ 2005 if (!m_is_geometry_shader_extension_supported) 2006 { 2007 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 2008 } 2009 2010 /* GL */ 2011 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2012 2013 /* Get maximum number of output vertices and prepare strings */ 2014 glw::GLint max_output_vertices; 2015 std::string valid_output_vertices_string; 2016 std::string invalid_output_vertices_string; 2017 2018 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_VERTICES, &max_output_vertices); 2019 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT pname"); 2020 2021 std::stringstream stream_valid; 2022 stream_valid << max_output_vertices; 2023 valid_output_vertices_string = stream_valid.str(); 2024 2025 std::stringstream stream_invalid; 2026 stream_invalid << max_output_vertices + 1; 2027 invalid_output_vertices_string = stream_invalid.str(); 2028 2029 /* Geometry shader parts */ 2030 const glw::GLchar* geometry_shader_valid_parts[] = { m_geometry_shader_code_preamble, 2031 valid_output_vertices_string.c_str(), 2032 m_geometry_shader_code_body }; 2033 2034 const glw::GLchar* geometry_shader_invalid_parts[] = { m_geometry_shader_code_preamble, 2035 invalid_output_vertices_string.c_str(), 2036 m_geometry_shader_code_body }; 2037 2038 /* Try to build programs */ 2039 bool does_valid_build = 2040 doesProgramBuild(1, &m_fragment_shader_code, 3, geometry_shader_valid_parts, 1, &m_vertex_shader_code); 2041 2042 bool does_invalid_build = 2043 doesProgramBuild(1, &m_fragment_shader_code, 3, geometry_shader_invalid_parts, 1, &m_vertex_shader_code); 2044 2045 /* Verify results */ 2046 if ((true == does_valid_build) && (false == does_invalid_build)) 2047 { 2048 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2049 } 2050 else 2051 { 2052 if (true != does_valid_build) 2053 { 2054 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to build valid program! GS::max_vertices " 2055 "set to MAX_GEOMETRY_OUTPUT_VERTICES.\n" 2056 << tcu::TestLog::EndMessage; 2057 } 2058 2059 if (false != does_invalid_build) 2060 { 2061 m_testCtx.getLog() << tcu::TestLog::Message << "Build of invalid program was successful! GS::max_vertices " 2062 "set to MAX_GEOMETRY_OUTPUT_VERTICES + 1.\n" 2063 << tcu::TestLog::EndMessage; 2064 } 2065 2066 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2067 } 2068 2069 return STOP; 2070 } 2071 2072 /** Constructor 2073 * 2074 * @param context Test context 2075 * @param name Test case's name 2076 * @param description Test case's decsription 2077 **/ 2078 GeometryShaderMaxOutputComponentsSinglePointTest::GeometryShaderMaxOutputComponentsSinglePointTest( 2079 Context& context, const ExtParameters& extParams, const char* name, const char* description) 2080 : GeometryShaderLimitsRenderingBase(context, extParams, name, description) 2081 , m_max_output_components(0) 2082 , m_max_output_vectors(0) 2083 , m_n_available_vectors(0) 2084 { 2085 /* Nothing to be done here */ 2086 } 2087 2088 /** Clears data after draw call and result verification 2089 * 2090 **/ 2091 void GeometryShaderMaxOutputComponentsSinglePointTest::clean() 2092 { 2093 /* Nothing to be done here */ 2094 } 2095 2096 /** Get details for draw call 2097 * 2098 * @param out_primitive_type Type of primitive that will be used by next draw call 2099 * @param out_n_vertices Number of vertices that will used with next draw call 2100 **/ 2101 void GeometryShaderMaxOutputComponentsSinglePointTest::getDrawCallDetails(glw::GLenum& out_primitive_type, 2102 glw::GLuint& out_n_vertices) 2103 { 2104 /* Draw one point */ 2105 out_primitive_type = GL_POINTS; 2106 out_n_vertices = 1; 2107 } 2108 2109 /** Get dimensions and format for texture bind to color attachment 0, get format and type for glReadPixels 2110 * 2111 * @param out_texture_format Format for texture used as color attachment 0 2112 * @param out_texture_read_format Format of data used with glReadPixels 2113 * @param out_texture_read_type Type of data used with glReadPixels 2114 * @param out_texture_width Width of texture used as color attachment 0 2115 * @param out_texture_height Height of texture used as color attachment 0 2116 * @param out_texture_pixel_size Size of single pixel in bytes 2117 **/ 2118 void GeometryShaderMaxOutputComponentsSinglePointTest::getFramebufferDetails( 2119 glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format, glw::GLenum& out_texture_read_type, 2120 glw::GLuint& out_texture_width, glw::GLuint& out_texture_height, unsigned int& out_texture_pixel_size) 2121 { 2122 out_texture_format = GL_R32I; 2123 out_texture_read_format = GL_RGBA_INTEGER; 2124 out_texture_read_type = GL_INT; 2125 out_texture_width = m_texture_width; 2126 out_texture_height = m_texture_height; 2127 out_texture_pixel_size = 4 * 4; 2128 } 2129 2130 void GeometryShaderMaxOutputComponentsSinglePointTest::getRequiredPointSize(glw::GLfloat& out_point_size) 2131 { 2132 /* This test should only run if EXT_geometry_point_size is supported */ 2133 if (!m_is_geometry_shader_point_size_supported) 2134 { 2135 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 2136 } 2137 2138 out_point_size = (float)m_point_size; 2139 } 2140 2141 /** Get parts of shaders 2142 * 2143 * @param out_fragment_shader_parts Array of fragment shader parts 2144 * @param out_n_fragment_shader_parts Number of fragment shader parts 2145 * @param out_geometry_shader_parts Array of geometry shader parts 2146 * @param out_n_geometry_shader_parts Number of geometry shader parts 2147 * @param out_vertex_shader_parts Array of vertex shader parts 2148 * @param out_n_vertex_shader_parts Number of vertex shader parts 2149 **/ 2150 void GeometryShaderMaxOutputComponentsSinglePointTest::getShaderParts( 2151 const glw::GLchar* const*& out_fragment_shader_parts, unsigned int& out_n_fragment_shader_parts, 2152 const glw::GLchar* const*& out_geometry_shader_parts, unsigned int& out_n_geometry_shader_parts, 2153 const glw::GLchar* const*& out_vertex_shader_parts, unsigned int& out_n_vertex_shader_parts) 2154 { 2155 /* Retrieve ES entry-points */ 2156 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2157 2158 /* Get maximum number of output components */ 2159 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_COMPONENTS, &m_max_output_components); 2160 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT pname"); 2161 2162 m_max_output_vectors = m_max_output_components / 4; /* 4 components per vector */ 2163 m_n_available_vectors = m_max_output_vectors - 2; /* 2 vectors are reserved for gl_Position and gl_PointSize */ 2164 2165 /* Fragment shader parts */ 2166 prepareFragmentShader(m_fragment_shader_code); 2167 2168 m_fragment_shader_code_c_str = m_fragment_shader_code.c_str(); 2169 out_fragment_shader_parts = &m_fragment_shader_code_c_str; 2170 out_n_fragment_shader_parts = 1; 2171 2172 /* Geometry shader parts */ 2173 prepareGeometryShader(m_geometry_shader_code); 2174 2175 m_geometry_shader_code_c_str = m_geometry_shader_code.c_str(); 2176 out_geometry_shader_parts = &m_geometry_shader_code_c_str; 2177 out_n_geometry_shader_parts = 1; 2178 2179 /* Vertex shader */ 2180 out_vertex_shader_parts = &m_vertex_shader_code; 2181 out_n_vertex_shader_parts = 1; 2182 } 2183 2184 /** Prepare test specific program input for draw call 2185 * 2186 **/ 2187 void GeometryShaderMaxOutputComponentsSinglePointTest::prepareProgramInput() 2188 { 2189 /* Nothing to be done here */ 2190 } 2191 2192 /** Verify rendered image 2193 * 2194 * @param data Image to verify 2195 * 2196 * @return true Image pixels match expected values 2197 * false Some pixels have wrong values 2198 **/ 2199 bool GeometryShaderMaxOutputComponentsSinglePointTest::verifyResult(const void* data) 2200 { 2201 const unsigned char* result_image = (const unsigned char*)data; 2202 const unsigned int line_size = m_texture_width * m_texture_pixel_size; 2203 const glw::GLint n_components_per_point = m_n_available_vectors * 4; /* 4 components per vector */ 2204 2205 const glw::GLint first_value = 1; 2206 const glw::GLint last_value = n_components_per_point; 2207 const glw::GLint expected_value = ((first_value + last_value) * n_components_per_point) / 2; 2208 2209 /* Verify all pixels that belong to point, area m_point_size x m_point_size */ 2210 for (unsigned int y = 0; y < m_point_size; ++y) 2211 { 2212 const unsigned int line_offset = y * line_size; 2213 2214 for (unsigned int x = 0; x < m_point_size; ++x) 2215 { 2216 const unsigned int texel_offset = line_offset + x * m_texture_pixel_size; 2217 2218 if (0 != memcmp(result_image + texel_offset, &expected_value, sizeof(expected_value))) 2219 { 2220 const glw::GLint* result_value = (const glw::GLint*)(result_image + texel_offset); 2221 2222 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! Expected: " << expected_value 2223 << " Extracted: " << *result_value << " X: " << x << " Y: " << y 2224 << tcu::TestLog::EndMessage; 2225 2226 return false; 2227 } 2228 } 2229 } 2230 2231 return true; 2232 } 2233 2234 /** Prepare fragment shader code 2235 * 2236 * @param out_shader_code String that will be used to store shaders code 2237 **/ 2238 void GeometryShaderMaxOutputComponentsSinglePointTest::prepareFragmentShader(std::string& out_shader_code) const 2239 { 2240 std::stringstream stream; 2241 2242 stream << m_fragment_shader_code_preamble; 2243 stream << m_common_shader_code_gs_fs_out_definitions; 2244 2245 for (int i = 0; i < m_n_available_vectors; ++i) 2246 { 2247 stream << m_fragment_shader_code_flat_in_ivec4 << " " << m_common_shader_code_gs_fs_out << i << ";\n"; 2248 } 2249 2250 stream << m_fragment_shader_code_body_begin; 2251 2252 for (int i = 0; i < m_n_available_vectors; ++i) 2253 { 2254 stream << " " << m_fragment_shader_code_sum << m_common_shader_code_gs_fs_out << i << ".x + " 2255 << m_common_shader_code_gs_fs_out << i << ".y + " << m_common_shader_code_gs_fs_out << i << ".z + " 2256 << m_common_shader_code_gs_fs_out << i << ".w;\n"; 2257 } 2258 2259 stream << m_fragment_shader_code_body_end; 2260 2261 out_shader_code = stream.str(); 2262 } 2263 2264 /** Prepare geometry shader code 2265 * 2266 * @param out_shader_code String that will be used to store shaders code 2267 **/ 2268 void GeometryShaderMaxOutputComponentsSinglePointTest::prepareGeometryShader(std::string& out_shader_code) const 2269 { 2270 std::stringstream stream; 2271 2272 stream << m_geometry_shader_code_preamble; 2273 stream << m_common_shader_code_gs_fs_out_definitions; 2274 2275 for (int i = 0; i < m_n_available_vectors; ++i) 2276 { 2277 stream << m_geometry_shader_code_flat_out_ivec4 << " " << m_common_shader_code_gs_fs_out << i << ";\n"; 2278 } 2279 2280 stream << m_geometry_shader_code_body_begin; 2281 2282 for (int i = 0; i < m_n_available_vectors; ++i) 2283 { 2284 stream << " " << m_common_shader_code_gs_fs_out << i << m_geometry_shader_code_assignment; 2285 } 2286 2287 stream << m_geometry_shader_code_body_end; 2288 2289 out_shader_code = stream.str(); 2290 } 2291 2292 /** Constructor 2293 * 2294 * @param context Test context 2295 * @param name Test case's name 2296 * @param description Test case's description 2297 **/ 2298 GeometryShaderMaxTextureUnitsTest::GeometryShaderMaxTextureUnitsTest(Context& context, const ExtParameters& extParams, 2299 const char* name, const char* description) 2300 : GeometryShaderLimitsRenderingBase(context, extParams, name, description) 2301 , m_texture_width(0) 2302 , m_max_texture_units(0) 2303 { 2304 /* Nothing to be done here */ 2305 } 2306 2307 /** Clears data after draw call and result verification 2308 * 2309 **/ 2310 void GeometryShaderMaxTextureUnitsTest::clean() 2311 { 2312 /* GL functions */ 2313 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2314 2315 /* Bind 0 to all texture units */ 2316 for (int i = 0; i < m_max_texture_units; ++i) 2317 { 2318 gl.activeTexture(GL_TEXTURE0 + i); 2319 gl.bindTexture(GL_TEXTURE_2D, 0); 2320 } 2321 gl.activeTexture(GL_TEXTURE0); 2322 2323 /* Delete textures */ 2324 for (int i = 0; i < m_max_texture_units; ++i) 2325 { 2326 gl.deleteTextures(1, &m_textures[i].texture_id); 2327 } 2328 2329 m_textures.clear(); 2330 } 2331 2332 /** Get details for draw call 2333 * 2334 * @param out_primitive_type Type of primitive that will be used by next draw call 2335 * @param out_n_vertices Number of vertices that will used with next draw call 2336 **/ 2337 void GeometryShaderMaxTextureUnitsTest::getDrawCallDetails(glw::GLenum& out_primitive_type, glw::GLuint& out_n_vertices) 2338 { 2339 /* Draw GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT points */ 2340 out_primitive_type = GL_POINTS; 2341 out_n_vertices = m_max_texture_units; 2342 } 2343 2344 /** Get dimensions and format for texture bind to color attachment 0, get format and type for glReadPixels 2345 * 2346 * @param out_texture_format Format for texture used as color attachment 0 2347 * @param out_texture_read_format Format of data used with glReadPixels 2348 * @param out_texture_read_type Type of data used with glReadPixels 2349 * @param out_texture_width Width of texture used as color attachment 0 2350 * @param out_texture_height Height of texture used as color attachment 0 2351 * @param out_texture_pixel_size Size of single pixel in bytes 2352 **/ 2353 void GeometryShaderMaxTextureUnitsTest::getFramebufferDetails( 2354 glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format, glw::GLenum& out_texture_read_type, 2355 glw::GLuint& out_texture_width, glw::GLuint& out_texture_height, unsigned int& out_texture_pixel_size) 2356 { 2357 out_texture_format = GL_R32I; 2358 out_texture_read_format = GL_RGBA_INTEGER; 2359 out_texture_read_type = GL_INT; 2360 out_texture_width = m_texture_width; 2361 out_texture_height = m_texture_height; 2362 out_texture_pixel_size = 4 * 4; 2363 } 2364 2365 void GeometryShaderMaxTextureUnitsTest::getRequiredPointSize(glw::GLfloat& out_point_size) 2366 { 2367 /* This test should only run if EXT_geometry_point_size is supported */ 2368 if (!m_is_geometry_shader_point_size_supported) 2369 { 2370 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__); 2371 } 2372 2373 out_point_size = (float)m_point_size; 2374 } 2375 2376 /** Get parts of shaders 2377 * 2378 * @param out_fragment_shader_parts Array of fragment shader parts 2379 * @param out_n_fragment_shader_parts Number of fragment shader parts 2380 * @param out_geometry_shader_parts Array of geometry shader parts 2381 * @param out_n_geometry_shader_parts Number of geometry shader parts 2382 * @param out_vertex_shader_parts Array of vertex shader parts 2383 * @param out_n_vertex_shader_parts Number of vertex shader parts 2384 **/ 2385 void GeometryShaderMaxTextureUnitsTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 2386 unsigned int& out_n_fragment_shader_parts, 2387 const glw::GLchar* const*& out_geometry_shader_parts, 2388 unsigned int& out_n_geometry_shader_parts, 2389 const glw::GLchar* const*& out_vertex_shader_parts, 2390 unsigned int& out_n_vertex_shader_parts) 2391 { 2392 /* Retrieve ES entry-points */ 2393 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2394 2395 /* Get maximum number of texture units */ 2396 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &m_max_texture_units); 2397 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT pname"); 2398 2399 /* Number of drawn points is equal to GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ 2400 m_texture_width = m_max_texture_units * m_point_size; 2401 2402 /* Prepare texture units string */ 2403 std::stringstream stream; 2404 stream << m_max_texture_units; 2405 m_max_texture_units_string = stream.str(); 2406 2407 /* Fragment shader parts */ 2408 out_fragment_shader_parts = &m_fragment_shader_code; 2409 out_n_fragment_shader_parts = 1; 2410 2411 /* Geometry shader parts */ 2412 m_geometry_shader_parts[0] = m_geometry_shader_code_preamble; 2413 m_geometry_shader_parts[1] = m_max_texture_units_string.c_str(); 2414 m_geometry_shader_parts[2] = m_geometry_shader_code_body; 2415 2416 out_geometry_shader_parts = m_geometry_shader_parts; 2417 out_n_geometry_shader_parts = 3; 2418 2419 /* Vertex shader parts */ 2420 m_vertex_shader_parts[0] = m_vertex_shader_code_preamble; 2421 m_vertex_shader_parts[1] = m_max_texture_units_string.c_str(); 2422 m_vertex_shader_parts[2] = m_vertex_shader_code_body; 2423 2424 out_vertex_shader_parts = m_vertex_shader_parts; 2425 out_n_vertex_shader_parts = 3; 2426 } 2427 2428 /** Prepare test specific program input for draw call 2429 * 2430 **/ 2431 void GeometryShaderMaxTextureUnitsTest::prepareProgramInput() 2432 { 2433 /* Retrieve ES entry-points */ 2434 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2435 2436 m_textures.resize(m_max_texture_units); 2437 2438 /* Prepare texture storage and fill data */ 2439 for (int i = 0; i < m_max_texture_units; ++i) 2440 { 2441 /* (starting from 1, delta: 2) */ 2442 m_textures[i].data = i * 2 + 1; 2443 2444 /* Generate and bind texture */ 2445 gl.genTextures(1, &m_textures[i].texture_id); 2446 gl.bindTexture(GL_TEXTURE_2D, m_textures[i].texture_id); 2447 2448 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create texture"); 2449 2450 /* Allocate and upload texture data */ 2451 gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, GL_R32I, 1 /* width */, 1 /* height */, 0 /* border */, 2452 GL_RED_INTEGER, GL_INT, &m_textures[i].data); 2453 2454 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2455 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2456 2457 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create storage and fill texture with data"); 2458 } 2459 2460 /* Prepare sampler uniforms */ 2461 for (int i = 0; i < m_max_texture_units; ++i) 2462 { 2463 /* Prepare name of sampler */ 2464 std::stringstream stream; 2465 2466 stream << "gs_texture[" << i << "]"; 2467 2468 /* Get sampler location */ 2469 glw::GLint gs_texture_location = gl.getUniformLocation(m_program_object_id, stream.str().c_str()); 2470 2471 if (-1 == gs_texture_location || (GL_NO_ERROR != gl.getError())) 2472 { 2473 TCU_FAIL("Failed to get uniform isampler2D location"); 2474 } 2475 2476 /* Set uniform at sampler location value to index of texture unit */ 2477 gl.uniform1i(gs_texture_location, i); 2478 2479 if (GL_NO_ERROR != gl.getError()) 2480 { 2481 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to set uniform at location: " << gs_texture_location 2482 << " to value: " << i << tcu::TestLog::EndMessage; 2483 2484 TCU_FAIL("Failed to get uniform isampler2D location"); 2485 } 2486 } 2487 2488 /* Bind textures to texture units */ 2489 for (int i = 0; i < m_max_texture_units; ++i) 2490 { 2491 gl.activeTexture(GL_TEXTURE0 + i); 2492 gl.bindTexture(GL_TEXTURE_2D, m_textures[i].texture_id); 2493 } 2494 2495 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set texture units up"); 2496 } 2497 2498 /** Verify rendered image 2499 * 2500 * @param data Image to verify 2501 * 2502 * @return true Image pixels match expected values 2503 * false Some pixels have wrong values 2504 **/ 2505 bool GeometryShaderMaxTextureUnitsTest::verifyResult(const void* data) 2506 { 2507 const unsigned char* result_image = (const unsigned char*)data; 2508 const unsigned int line_size = m_texture_width * m_texture_pixel_size; 2509 2510 /* For each drawn point */ 2511 for (glw::GLint point = 0; point < m_max_texture_units; ++point) 2512 { 2513 const glw::GLint first_value = m_textures[0].data; 2514 const glw::GLint last_value = m_textures[point].data; 2515 const glw::GLint expected_value = ((first_value + last_value) * (point + 1)) / 2; 2516 const unsigned int point_offset = point * m_texture_pixel_size * m_point_size; 2517 2518 /* Verify all pixels that belong to point, area m_point_size x m_point_size */ 2519 for (unsigned int y = 0; y < m_point_size; ++y) 2520 { 2521 const unsigned int line_offset = y * line_size; 2522 const unsigned int first_texel_offset = line_offset + point_offset; 2523 2524 for (unsigned int x = 0; x < m_point_size; ++x) 2525 { 2526 const unsigned int texel_offset = first_texel_offset + x * m_texture_pixel_size; 2527 2528 if (0 != memcmp(result_image + texel_offset, &expected_value, sizeof(expected_value))) 2529 { 2530 glw::GLint* result_value = (glw::GLint*)(result_image + texel_offset); 2531 2532 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result! " 2533 "Expected: " 2534 << expected_value << " Extracted: " << *result_value << " Point: " << point 2535 << " X: " << x << " Y: " << y << tcu::TestLog::EndMessage; 2536 2537 return false; 2538 } 2539 } 2540 } 2541 } 2542 2543 return true; 2544 } 2545 2546 /** Constructor 2547 * 2548 * @param context Test context 2549 * @param name Test case's name 2550 * @param description Test case's description 2551 **/ 2552 GeometryShaderMaxInvocationsTest::GeometryShaderMaxInvocationsTest(Context& context, const ExtParameters& extParams, 2553 const char* name, const char* description) 2554 : TestCaseBase(context, extParams, name, description) 2555 , m_fragment_shader_id_for_multiple_invocations_pass(0) 2556 , m_geometry_shader_id_for_multiple_invocations_pass(0) 2557 , m_program_object_id_for_multiple_invocations_pass(0) 2558 , m_vertex_shader_id_for_multiple_invocations_pass(0) 2559 , m_fragment_shader_id_for_single_invocation_pass(0) 2560 , m_geometry_shader_id_for_single_invocation_pass(0) 2561 , m_program_object_id_for_single_invocation_pass(0) 2562 , m_vertex_shader_id_for_single_invocation_pass(0) 2563 , m_max_geometry_shader_invocations(0) 2564 , m_framebuffer_object_id(0) 2565 , m_color_texture_id(0) 2566 , m_texture_width(0) 2567 , m_vertex_array_object_id(0) 2568 { 2569 /* Nothing to be done here */ 2570 } 2571 2572 /** Initializes GLES objects used during the test. 2573 * 2574 */ 2575 void GeometryShaderMaxInvocationsTest::initTest() 2576 { 2577 /* This test should only run if EXT_geometry_shader is supported */ 2578 if (!m_is_geometry_shader_extension_supported) 2579 { 2580 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 2581 } 2582 2583 /* Retrieve ES entry-points */ 2584 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2585 2586 /* Get GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT */ 2587 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_INVOCATIONS, &m_max_geometry_shader_invocations); 2588 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT"); 2589 2590 /* Prepare string for GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT */ 2591 std::stringstream stream; 2592 stream << m_max_geometry_shader_invocations; 2593 m_max_geometry_shader_invocations_string = stream.str(); 2594 2595 /* Prepare gemetry shader parts for multiple invocations pass */ 2596 const glw::GLuint n_geometry_shader_parts_for_multiple_invocations_pass = 5; 2597 2598 m_geometry_shader_parts_for_multiple_invocations_pass[0] = m_geometry_shader_code_preamble; 2599 m_geometry_shader_parts_for_multiple_invocations_pass[1] = m_max_geometry_shader_invocations_string.c_str(); 2600 m_geometry_shader_parts_for_multiple_invocations_pass[2] = m_geometry_shader_code_layout; 2601 m_geometry_shader_parts_for_multiple_invocations_pass[3] = m_geometry_shader_code_layout_invocations; 2602 m_geometry_shader_parts_for_multiple_invocations_pass[4] = m_geometry_shader_code_body; 2603 2604 /* Prepare gemetry shader parts for single invocation pass */ 2605 const glw::GLuint n_geometry_shader_parts_for_single_invocation_pass = 4; 2606 2607 m_geometry_shader_parts_for_single_invocation_pass[0] = m_geometry_shader_code_preamble; 2608 m_geometry_shader_parts_for_single_invocation_pass[1] = m_max_geometry_shader_invocations_string.c_str(); 2609 m_geometry_shader_parts_for_single_invocation_pass[2] = m_geometry_shader_code_layout; 2610 m_geometry_shader_parts_for_single_invocation_pass[3] = m_geometry_shader_code_body; 2611 2612 /* Create program and shaders for multiple GS invocations */ 2613 m_program_object_id_for_multiple_invocations_pass = gl.createProgram(); 2614 2615 m_fragment_shader_id_for_multiple_invocations_pass = gl.createShader(GL_FRAGMENT_SHADER); 2616 m_geometry_shader_id_for_multiple_invocations_pass = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 2617 m_vertex_shader_id_for_multiple_invocations_pass = gl.createShader(GL_VERTEX_SHADER); 2618 2619 /* Create program and shaders for single GS invocations */ 2620 m_program_object_id_for_single_invocation_pass = gl.createProgram(); 2621 2622 m_fragment_shader_id_for_single_invocation_pass = gl.createShader(GL_FRAGMENT_SHADER); 2623 m_geometry_shader_id_for_single_invocation_pass = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 2624 m_vertex_shader_id_for_single_invocation_pass = gl.createShader(GL_VERTEX_SHADER); 2625 2626 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program or shader objects"); 2627 2628 /* Build program for multiple GS invocations */ 2629 if (false == buildProgram(m_program_object_id_for_multiple_invocations_pass, 2630 m_fragment_shader_id_for_multiple_invocations_pass, 1, &m_fragment_shader_code, 2631 m_geometry_shader_id_for_multiple_invocations_pass, 2632 n_geometry_shader_parts_for_multiple_invocations_pass, 2633 m_geometry_shader_parts_for_multiple_invocations_pass, 2634 m_vertex_shader_id_for_multiple_invocations_pass, 1, &m_vertex_shader_code)) 2635 { 2636 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 2637 } 2638 2639 /* Build program for single GS invocations */ 2640 if (false == buildProgram(m_program_object_id_for_single_invocation_pass, 2641 m_fragment_shader_id_for_single_invocation_pass, 1, &m_fragment_shader_code, 2642 m_geometry_shader_id_for_single_invocation_pass, 2643 n_geometry_shader_parts_for_single_invocation_pass, 2644 m_geometry_shader_parts_for_single_invocation_pass, 2645 m_vertex_shader_id_for_single_invocation_pass, 1, &m_vertex_shader_code)) 2646 { 2647 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader"); 2648 } 2649 2650 /* Set up texture object and a FBO */ 2651 gl.genTextures(1, &m_color_texture_id); 2652 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create texture object"); 2653 2654 gl.genFramebuffers(1, &m_framebuffer_object_id); 2655 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer object"); 2656 2657 m_texture_width = m_triangle_edge_length * m_max_geometry_shader_invocations; 2658 2659 if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8, 2660 m_texture_width, m_texture_height)) 2661 { 2662 TCU_FAIL("Failed to setup framebuffer"); 2663 } 2664 2665 /* Set up a vertex array object */ 2666 gl.genVertexArrays(1, &m_vertex_array_object_id); 2667 gl.bindVertexArray(m_vertex_array_object_id); 2668 2669 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object"); 2670 } 2671 2672 /** Executes the test. 2673 * 2674 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 2675 * 2676 * Note the function throws exception should an error occur! 2677 * 2678 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 2679 **/ 2680 tcu::TestCase::IterateResult GeometryShaderMaxInvocationsTest::iterate() 2681 { 2682 initTest(); 2683 2684 /* Variables used for image verification purposes */ 2685 std::vector<unsigned char> result_image(m_texture_width * m_texture_height * m_texture_pixel_size); 2686 2687 /* Retrieve ES entry-points */ 2688 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2689 2690 /* Render with multiple GS invocations */ 2691 gl.useProgram(m_program_object_id_for_multiple_invocations_pass); 2692 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program"); 2693 2694 gl.clearColor(255 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */); 2695 gl.clear(GL_COLOR_BUFFER_BIT); 2696 2697 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer"); 2698 2699 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 2700 GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed"); 2701 2702 /* Extract image from FBO */ 2703 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, &result_image[0]); 2704 2705 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer"); 2706 2707 /* Run verification */ 2708 bool result_of_multiple_invocations_pass = verifyResultOfMultipleInvocationsPass(&result_image[0]); 2709 2710 /* Render with single GS invocations */ 2711 gl.useProgram(m_program_object_id_for_single_invocation_pass); 2712 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program"); 2713 2714 gl.clearColor(255 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */); 2715 gl.clear(GL_COLOR_BUFFER_BIT); 2716 2717 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer"); 2718 2719 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 2720 GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed"); 2721 2722 /* Extract image from FBO */ 2723 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, &result_image[0]); 2724 2725 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer"); 2726 2727 /* Run verification */ 2728 bool result_of_single_invocation_pass = verifyResultOfSingleInvocationPass(&result_image[0]); 2729 2730 /* Set test result */ 2731 if (result_of_multiple_invocations_pass && result_of_single_invocation_pass) 2732 { 2733 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2734 } 2735 else 2736 { 2737 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2738 } 2739 2740 return STOP; 2741 } 2742 2743 /** Deinitializes GLES objects created during the test. 2744 * 2745 */ 2746 void GeometryShaderMaxInvocationsTest::deinit() 2747 { 2748 /* Retrieve ES entry-points */ 2749 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2750 2751 /* Reset OpenGL ES state */ 2752 gl.useProgram(0); 2753 gl.bindVertexArray(0); 2754 gl.bindTexture(GL_TEXTURE_2D, 0); 2755 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 2756 2757 /* Delete everything */ 2758 if (m_program_object_id_for_multiple_invocations_pass != 0) 2759 { 2760 gl.deleteProgram(m_program_object_id_for_multiple_invocations_pass); 2761 2762 m_program_object_id_for_multiple_invocations_pass = 0; 2763 } 2764 2765 if (m_fragment_shader_id_for_multiple_invocations_pass != 0) 2766 { 2767 gl.deleteShader(m_fragment_shader_id_for_multiple_invocations_pass); 2768 2769 m_fragment_shader_id_for_multiple_invocations_pass = 0; 2770 } 2771 2772 if (m_geometry_shader_id_for_multiple_invocations_pass != 0) 2773 { 2774 gl.deleteShader(m_geometry_shader_id_for_multiple_invocations_pass); 2775 2776 m_geometry_shader_id_for_multiple_invocations_pass = 0; 2777 } 2778 2779 if (m_vertex_shader_id_for_multiple_invocations_pass != 0) 2780 { 2781 gl.deleteShader(m_vertex_shader_id_for_multiple_invocations_pass); 2782 2783 m_vertex_shader_id_for_multiple_invocations_pass = 0; 2784 } 2785 2786 if (m_program_object_id_for_single_invocation_pass != 0) 2787 { 2788 gl.deleteProgram(m_program_object_id_for_single_invocation_pass); 2789 2790 m_program_object_id_for_single_invocation_pass = 0; 2791 } 2792 2793 if (m_fragment_shader_id_for_single_invocation_pass != 0) 2794 { 2795 gl.deleteShader(m_fragment_shader_id_for_single_invocation_pass); 2796 2797 m_fragment_shader_id_for_single_invocation_pass = 0; 2798 } 2799 2800 if (m_geometry_shader_id_for_single_invocation_pass != 0) 2801 { 2802 gl.deleteShader(m_geometry_shader_id_for_single_invocation_pass); 2803 2804 m_geometry_shader_id_for_single_invocation_pass = 0; 2805 } 2806 2807 if (m_vertex_shader_id_for_single_invocation_pass != 0) 2808 { 2809 gl.deleteShader(m_vertex_shader_id_for_single_invocation_pass); 2810 2811 m_vertex_shader_id_for_single_invocation_pass = 0; 2812 } 2813 2814 if (m_vertex_array_object_id != 0) 2815 { 2816 gl.deleteVertexArrays(1, &m_vertex_array_object_id); 2817 2818 m_vertex_array_object_id = 0; 2819 } 2820 2821 if (m_color_texture_id != 0) 2822 { 2823 gl.deleteTextures(1, &m_color_texture_id); 2824 2825 m_color_texture_id = 0; 2826 } 2827 2828 if (m_framebuffer_object_id != 0) 2829 { 2830 gl.deleteFramebuffers(1, &m_framebuffer_object_id); 2831 2832 m_framebuffer_object_id = 0; 2833 } 2834 2835 /* Deinitilize base class */ 2836 TestCaseBase::deinit(); 2837 } 2838 2839 /** Verify image rendered during draw call for multiple invocations pass 2840 * 2841 * @param result_image Image data 2842 * 2843 * @return true When image is as expected 2844 * false When image is wrong 2845 **/ 2846 bool GeometryShaderMaxInvocationsTest::verifyResultOfMultipleInvocationsPass(unsigned char* result_image) 2847 { 2848 for (unsigned int i = 0; i < (unsigned int)m_max_geometry_shader_invocations; ++i) 2849 { 2850 /* Verify that pixel at triangle's center was modified */ 2851 const unsigned int x1 = m_triangle_edge_length * i; 2852 const unsigned int x2 = m_triangle_edge_length * i; 2853 const unsigned int x3 = m_triangle_edge_length * (i + 1) - 1; 2854 2855 const unsigned int y1 = 0; 2856 const unsigned int y2 = m_triangle_edge_length - 1; 2857 const unsigned int y3 = m_triangle_edge_length - 1; 2858 2859 const unsigned int center_x = (x1 + x2 + x3) / 3; 2860 const unsigned int center_y = (y1 + y2 + y3) / 3; 2861 2862 bool is_pixel_valid = comparePixel(result_image, center_x, center_y, m_texture_width, m_texture_height, 2863 m_texture_pixel_size, 0, 255, 0, 0); 2864 2865 if (false == is_pixel_valid) 2866 { 2867 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at " 2868 "[" 2869 << center_x << ";" << center_y << "]! " 2870 "Triangle index: " 2871 << i << " from range <0:" << m_max_geometry_shader_invocations << ")." 2872 << tcu::TestLog::EndMessage; 2873 2874 return false; 2875 } 2876 2877 /* Verify that background's pixel was not modified */ 2878 const unsigned int x4 = m_triangle_edge_length * (i + 1) - 1; 2879 const unsigned int y4 = m_triangle_edge_length - 1; 2880 2881 is_pixel_valid = 2882 comparePixel(result_image, x4, y4, m_texture_width, m_texture_height, m_texture_pixel_size, 255, 0, 0, 0); 2883 2884 if (false == is_pixel_valid) 2885 { 2886 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << x4 << ";" << y4 2887 << "]! " 2888 "Background for index: " 2889 << i << "from range <0:" << m_max_geometry_shader_invocations << ")." 2890 << tcu::TestLog::EndMessage; 2891 2892 return false; 2893 } 2894 } 2895 2896 return true; 2897 } 2898 2899 /** Verify image rendered during draw call for single invocation pass 2900 * 2901 * @param result_image Image data 2902 * 2903 * @return true When image is as expected 2904 * false When image is wrong 2905 **/ 2906 bool GeometryShaderMaxInvocationsTest::verifyResultOfSingleInvocationPass(unsigned char* result_image) 2907 { 2908 /* Only one triangle should be drawn, verify that pixel at its center was modified */ 2909 { 2910 const unsigned int x1 = 0; 2911 const unsigned int x2 = 0; 2912 const unsigned int x3 = m_triangle_edge_length - 1; 2913 2914 const unsigned int y1 = 0; 2915 const unsigned int y2 = m_triangle_edge_length - 1; 2916 const unsigned int y3 = m_triangle_edge_length - 1; 2917 2918 const unsigned int center_x = (x1 + x2 + x3) / 3; 2919 const unsigned int center_y = (y1 + y2 + y3) / 3; 2920 2921 bool is_pixel_valid = comparePixel(result_image, center_x, center_y, m_texture_width, m_texture_height, 2922 m_texture_pixel_size, 0, 255, 0, 0); 2923 2924 if (false == is_pixel_valid) 2925 { 2926 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << center_x << ";" << center_y 2927 << "]! " 2928 "Triangle index: " 2929 << 0 << " from range <0:" << m_max_geometry_shader_invocations << ")." 2930 << tcu::TestLog::EndMessage; 2931 2932 return false; 2933 } 2934 2935 /* Verify that background's pixel was not modified */ 2936 const unsigned int x4 = m_triangle_edge_length - 1; 2937 const unsigned int y4 = m_triangle_edge_length - 1; 2938 2939 is_pixel_valid = 2940 comparePixel(result_image, x4, y4, m_texture_width, m_texture_height, m_texture_pixel_size, 255, 0, 0, 0); 2941 2942 if (false == is_pixel_valid) 2943 { 2944 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << x4 << ";" << y4 2945 << "]! " 2946 "Background for index: " 2947 << 0 << " from range <0:" << m_max_geometry_shader_invocations << ")." 2948 << tcu::TestLog::EndMessage; 2949 2950 return false; 2951 } 2952 } 2953 2954 for (unsigned int i = 1; i < (unsigned int)m_max_geometry_shader_invocations; ++i) 2955 { 2956 /* Verify that pixel at triangle's center was not modified */ 2957 const unsigned int x1 = m_triangle_edge_length * i; 2958 const unsigned int x2 = m_triangle_edge_length * i; 2959 const unsigned int x3 = m_triangle_edge_length * (i + 1) - 1; 2960 2961 const unsigned int y1 = 0; 2962 const unsigned int y2 = m_triangle_edge_length - 1; 2963 const unsigned int y3 = m_triangle_edge_length - 1; 2964 2965 const unsigned int center_x = (x1 + x2 + x3) / 3; 2966 const unsigned int center_y = (y1 + y2 + y3) / 3; 2967 2968 bool is_pixel_valid = comparePixel(result_image, center_x, center_y, m_texture_width, m_texture_height, 2969 m_texture_pixel_size, 255, 0, 0, 0); 2970 2971 if (false == is_pixel_valid) 2972 { 2973 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << center_x << ";" << center_y 2974 << "]! " 2975 "Triangle index: " 2976 << i << " from range <0:" << m_max_geometry_shader_invocations << ")." 2977 << tcu::TestLog::EndMessage; 2978 2979 return false; 2980 } 2981 2982 /* Verify that background's pixel was not modified */ 2983 const unsigned int x4 = m_triangle_edge_length * (i + 1) - 1; 2984 const unsigned int y4 = m_triangle_edge_length - 1; 2985 2986 is_pixel_valid = 2987 comparePixel(result_image, x4, y4, m_texture_width, m_texture_height, m_texture_pixel_size, 255, 0, 0, 0); 2988 2989 if (false == is_pixel_valid) 2990 { 2991 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel at [" << x4 << ";" << y4 2992 << "]! " 2993 "Background for index: " 2994 << i << " from range <0:" << m_max_geometry_shader_invocations << ")." 2995 << tcu::TestLog::EndMessage; 2996 2997 return false; 2998 } 2999 } 3000 3001 return true; 3002 } 3003 3004 /** Constructor 3005 * 3006 * @param context Test context 3007 * @param name Test case's name 3008 * @param description Test case's description 3009 **/ 3010 GeometryShaderMaxCombinedTextureUnitsTest::GeometryShaderMaxCombinedTextureUnitsTest(Context& context, 3011 const ExtParameters& extParams, 3012 const char* name, 3013 const char* description) 3014 : GeometryShaderLimitsRenderingBase(context, extParams, name, description) 3015 , m_texture_width(0) 3016 , m_max_combined_texture_units(0) 3017 , m_max_fragment_texture_units(0) 3018 , m_max_geometry_texture_units(0) 3019 , m_max_vertex_texture_units(0) 3020 , m_min_texture_units(0) 3021 , m_n_fragment_texture_units(0) 3022 , m_n_geometry_texture_units(0) 3023 , m_n_texture_units(0) 3024 , m_n_vertex_texture_units(0) 3025 { 3026 /* Nothing to be done here */ 3027 } 3028 3029 /** Clears data after draw call and result verification 3030 * 3031 **/ 3032 void GeometryShaderMaxCombinedTextureUnitsTest::clean() 3033 { 3034 /* GL functions */ 3035 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3036 3037 /* Bind 0 to all texture units */ 3038 for (int i = 0; i < m_n_texture_units; ++i) 3039 { 3040 gl.activeTexture(GL_TEXTURE0 + i); 3041 gl.bindTexture(GL_TEXTURE_2D, 0); 3042 } 3043 3044 /* Delete textures */ 3045 for (int i = 0; i < m_n_texture_units; ++i) 3046 { 3047 gl.deleteTextures(1, &m_textures[i].texture_id); 3048 } 3049 3050 m_textures.clear(); 3051 } 3052 3053 /** Get details for draw call 3054 * 3055 * @param out_primitive_type Type of primitive that will be used by next draw call 3056 * @param out_n_vertices Number of vertices that will used with next draw call 3057 **/ 3058 void GeometryShaderMaxCombinedTextureUnitsTest::getDrawCallDetails(glw::GLenum& out_primitive_type, 3059 glw::GLuint& out_n_vertices) 3060 { 3061 /* Draw GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT points */ 3062 out_primitive_type = GL_POINTS; 3063 out_n_vertices = m_min_texture_units; 3064 } 3065 3066 /** Get dimensions and format for texture bind to color attachment 0, get format and type for glReadPixels 3067 * 3068 * @param out_texture_format Format for texture used as color attachment 0 3069 * @param out_texture_read_format Format of data used with glReadPixels 3070 * @param out_texture_read_type Type of data used with glReadPixels 3071 * @param out_texture_width Width of texture used as color attachment 0 3072 * @param out_texture_height Height of texture used as color attachment 0 3073 * @param out_texture_pixel_size Size of single pixel in bytes 3074 **/ 3075 void GeometryShaderMaxCombinedTextureUnitsTest::getFramebufferDetails( 3076 glw::GLenum& out_texture_format, glw::GLenum& out_texture_read_format, glw::GLenum& out_texture_read_type, 3077 glw::GLuint& out_texture_width, glw::GLuint& out_texture_height, unsigned int& out_texture_pixel_size) 3078 { 3079 out_texture_format = GL_R32UI; 3080 out_texture_read_format = GL_RGBA_INTEGER; 3081 out_texture_read_type = GL_UNSIGNED_INT; 3082 out_texture_width = m_texture_width; 3083 out_texture_height = m_texture_height; 3084 out_texture_pixel_size = 4 * 4; 3085 } 3086 3087 void GeometryShaderMaxCombinedTextureUnitsTest::getRequiredPointSize(glw::GLfloat& out_point_size) 3088 { 3089 out_point_size = (float)m_point_size; 3090 } 3091 3092 /** Get parts of shaders 3093 * 3094 * @param out_fragment_shader_parts Array of fragment shader parts 3095 * @param out_n_fragment_shader_parts Number of fragment shader parts 3096 * @param out_geometry_shader_parts Array of geometry shader parts 3097 * @param out_n_geometry_shader_parts Number of geometry shader parts 3098 * @param out_vertex_shader_parts Array of vertex shader parts 3099 * @param out_n_vertex_shader_parts Number of vertex shader parts 3100 **/ 3101 void GeometryShaderMaxCombinedTextureUnitsTest::getShaderParts(const glw::GLchar* const*& out_fragment_shader_parts, 3102 unsigned int& out_n_fragment_shader_parts, 3103 const glw::GLchar* const*& out_geometry_shader_parts, 3104 unsigned int& out_n_geometry_shader_parts, 3105 const glw::GLchar* const*& out_vertex_shader_parts, 3106 unsigned int& out_n_vertex_shader_parts) 3107 { 3108 /* GL functions */ 3109 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3110 3111 /* Get maximum number of texture units */ 3112 gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &m_max_combined_texture_units); 3113 gl.getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &m_max_vertex_texture_units); 3114 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &m_max_geometry_texture_units); 3115 gl.getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_max_fragment_texture_units); 3116 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed"); 3117 3118 m_n_texture_units = 3119 de::max(m_max_vertex_texture_units, de::max(m_max_geometry_texture_units, m_max_fragment_texture_units)); 3120 m_n_vertex_texture_units = de::max(1, de::min(m_max_combined_texture_units - 2, m_max_vertex_texture_units)); 3121 m_n_fragment_texture_units = 3122 de::max(1, de::min(m_max_combined_texture_units - m_n_vertex_texture_units - 1, m_max_fragment_texture_units)); 3123 m_n_geometry_texture_units = 3124 de::max(1, de::min(m_max_combined_texture_units - m_n_vertex_texture_units - m_n_fragment_texture_units, 3125 m_max_geometry_texture_units)); 3126 m_min_texture_units = 3127 de::min(m_n_vertex_texture_units, de::min(m_n_fragment_texture_units, m_n_geometry_texture_units)); 3128 3129 /* Number of drawn points is equal to GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ 3130 m_texture_width = m_n_texture_units * m_point_size; 3131 3132 /* Prepare texture units string */ 3133 std::stringstream stream_fragment; 3134 stream_fragment << m_n_fragment_texture_units; 3135 m_n_fragment_texture_units_string = stream_fragment.str(); 3136 3137 std::stringstream stream_geometry; 3138 stream_geometry << m_n_geometry_texture_units; 3139 m_n_geometry_texture_units_string = stream_geometry.str(); 3140 3141 std::stringstream stream_vertex; 3142 stream_vertex << m_n_vertex_texture_units; 3143 m_n_vertex_texture_units_string = stream_vertex.str(); 3144 3145 /* Fragment shader parts */ 3146 m_fragment_shader_parts[0] = m_fragment_shader_code_preamble; 3147 m_fragment_shader_parts[1] = m_n_fragment_texture_units_string.c_str(); 3148 m_fragment_shader_parts[2] = m_fragment_shader_code_body; 3149 3150 out_fragment_shader_parts = m_fragment_shader_parts; 3151 out_n_fragment_shader_parts = 3; 3152 3153 /* Geometry shader parts */ 3154 m_geometry_shader_parts[0] = m_geometry_shader_code_preamble; 3155 m_geometry_shader_parts[1] = m_n_geometry_texture_units_string.c_str(); 3156 m_geometry_shader_parts[2] = m_geometry_shader_code_body; 3157 3158 out_geometry_shader_parts = m_geometry_shader_parts; 3159 out_n_geometry_shader_parts = 3; 3160 3161 /* Vertex shader parts */ 3162 m_vertex_shader_parts[0] = m_vertex_shader_code_preamble; 3163 m_vertex_shader_parts[1] = m_n_vertex_texture_units_string.c_str(); 3164 m_vertex_shader_parts[2] = m_vertex_shader_code_body; 3165 3166 out_vertex_shader_parts = m_vertex_shader_parts; 3167 out_n_vertex_shader_parts = 3; 3168 } 3169 3170 /** Prepare test specific program input for draw call 3171 * 3172 **/ 3173 void GeometryShaderMaxCombinedTextureUnitsTest::prepareProgramInput() 3174 { 3175 /* Retrieve ES entry-points */ 3176 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3177 3178 m_textures.resize(m_n_texture_units); 3179 3180 /* Prepare texture storage and fill data */ 3181 for (int i = 0; i < m_n_texture_units; ++i) 3182 { 3183 /* unique intensity equal to index of the texture */ 3184 m_textures[i].data = i; 3185 3186 /* Generate and bind texture */ 3187 gl.genTextures(1, &m_textures[i].texture_id); 3188 gl.bindTexture(GL_TEXTURE_2D, m_textures[i].texture_id); 3189 3190 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create texture"); 3191 3192 /* Allocate and upload texture data */ 3193 gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, GL_R32UI, 1 /* width*/, 1 /* height */, 0 /* border */, 3194 GL_RED_INTEGER, GL_UNSIGNED_INT, &m_textures[i].data); 3195 3196 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3197 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3198 3199 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create storage and fill texture with data"); 3200 } 3201 3202 /* Prepare sampler uniforms */ 3203 for (int i = 0; i < m_n_texture_units; ++i) 3204 { 3205 /* Prepare name of sampler */ 3206 std::stringstream stream; 3207 3208 stream << "sampler[" << i << "]"; 3209 3210 /* Get sampler location */ 3211 glw::GLint sampler_location = gl.getUniformLocation(m_program_object_id, stream.str().c_str()); 3212 3213 if (-1 == sampler_location || GL_NO_ERROR != gl.getError()) 3214 { 3215 TCU_FAIL("Failed to get uniform usampler2D location"); 3216 } 3217 3218 /* Set uniform at sampler location value to index of texture unit */ 3219 gl.uniform1i(sampler_location, i); 3220 3221 if (GL_NO_ERROR != gl.getError()) 3222 { 3223 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to set uniform at location: " << sampler_location 3224 << " to value: " << i << tcu::TestLog::EndMessage; 3225 3226 TCU_FAIL("Failed to get uniform isampler2D location"); 3227 } 3228 } 3229 3230 /* Bind textures to texture units */ 3231 for (int i = 0; i < m_n_texture_units; ++i) 3232 { 3233 gl.activeTexture(GL_TEXTURE0 + i); 3234 gl.bindTexture(GL_TEXTURE_2D, m_textures[i].texture_id); 3235 3236 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3237 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3238 } 3239 3240 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set texture units up"); 3241 } 3242 3243 /** Verify rendered image 3244 * 3245 * @param data Image to verify 3246 * 3247 * @return true Image pixels match expected values 3248 * false Some pixels have wrong values 3249 **/ 3250 bool GeometryShaderMaxCombinedTextureUnitsTest::verifyResult(const void* data) 3251 { 3252 const unsigned char* result_image = (const unsigned char*)data; 3253 const unsigned int line_size = m_texture_width * m_texture_pixel_size; 3254 3255 /* For each drawn point */ 3256 for (glw::GLint point = 0; point < m_n_texture_units; ++point) 3257 { 3258 const unsigned int last_vertex_index = de::min(point, m_n_vertex_texture_units); 3259 3260 glw::GLint expected_vertex_value = 0; 3261 glw::GLint expected_geometry_value = 0; 3262 glw::GLint expected_fragment_value = 0; 3263 3264 for (unsigned int i = 0; i < last_vertex_index; ++i) 3265 { 3266 expected_vertex_value += m_textures[i].data; 3267 } 3268 3269 for (unsigned int i = 0; i < last_vertex_index; ++i) 3270 { 3271 expected_geometry_value += m_textures[i].data; 3272 } 3273 3274 for (unsigned int i = 0; i < last_vertex_index; ++i) 3275 { 3276 expected_fragment_value += m_textures[i].data; 3277 } 3278 3279 const glw::GLint expected_value = expected_vertex_value + expected_geometry_value + expected_fragment_value; 3280 const unsigned int point_offset = point * m_texture_pixel_size * m_point_size; 3281 3282 /* Verify all pixels that belong to point, area m_point_size x m_point_size */ 3283 for (unsigned int y = 0; y < m_point_size; ++y) 3284 { 3285 const unsigned int line_offset = y * line_size; 3286 const unsigned int first_texel_offset = line_offset + point_offset; 3287 3288 for (unsigned int x = 0; x < m_point_size; ++x) 3289 { 3290 const unsigned int texel_offset = first_texel_offset + x * m_texture_pixel_size; 3291 3292 if (0 != memcmp(result_image + texel_offset, &expected_value, sizeof(expected_value))) 3293 { 3294 glw::GLint* result_value = (glw::GLint*)(result_image + texel_offset); 3295 3296 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong result!" 3297 " Expected: " 3298 << expected_value << " Extracted: " << *result_value << " Point: " << point 3299 << " X: " << x << " Y: " << y << tcu::TestLog::EndMessage; 3300 3301 return false; 3302 } 3303 } 3304 } 3305 } 3306 3307 return true; 3308 } 3309 3310 } /* glcts */ 3311