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 /** 25 * \file gl4cTextureViewTests.cpp 26 * \brief Implements conformance tests for "texture view" functionality. 27 */ /*-------------------------------------------------------------------*/ 28 29 #include "gl4cTextureViewTests.hpp" 30 #include "deFloat16.h" 31 #include "deMath.h" 32 #include "gluContextInfo.hpp" 33 #include "glwFunctions.hpp" 34 #include "tcuFloat.hpp" 35 #include "tcuTestLog.hpp" 36 #include <algorithm> 37 38 /* Type definitions needed to handle GL_R11F_G11F_B10F internal format */ 39 typedef tcu::Float<deUint32, 5, 5, 15, 0> Float10; 40 typedef tcu::Float<deUint32, 5, 6, 15, 0> Float11; 41 42 namespace gl4cts 43 { 44 using namespace TextureView; 45 46 /** Stores internalformat->view class associations */ 47 const int internalformat_view_compatibility_array[] = { 48 /* [internalformat] [view class] */ 49 GL_RGBA32F, VIEW_CLASS_128_BITS, GL_RGBA32UI, VIEW_CLASS_128_BITS, GL_RGBA32I, VIEW_CLASS_128_BITS, GL_RGB32F, 50 VIEW_CLASS_96_BITS, GL_RGB32UI, VIEW_CLASS_96_BITS, GL_RGB32I, VIEW_CLASS_96_BITS, GL_RGBA16F, VIEW_CLASS_64_BITS, 51 GL_RG32F, VIEW_CLASS_64_BITS, GL_RGBA16UI, VIEW_CLASS_64_BITS, GL_RG32UI, VIEW_CLASS_64_BITS, GL_RGBA16I, 52 VIEW_CLASS_64_BITS, GL_RG32I, VIEW_CLASS_64_BITS, GL_RGBA16, VIEW_CLASS_64_BITS, GL_RGBA16_SNORM, 53 VIEW_CLASS_64_BITS, GL_RGB16, VIEW_CLASS_48_BITS, GL_RGB16_SNORM, VIEW_CLASS_48_BITS, GL_RGB16F, VIEW_CLASS_48_BITS, 54 GL_RGB16UI, VIEW_CLASS_48_BITS, GL_RGB16I, VIEW_CLASS_48_BITS, GL_RG16F, VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F, 55 VIEW_CLASS_32_BITS, GL_R32F, VIEW_CLASS_32_BITS, GL_RGB10_A2UI, VIEW_CLASS_32_BITS, GL_RGBA8UI, VIEW_CLASS_32_BITS, 56 GL_RG16UI, VIEW_CLASS_32_BITS, GL_R32UI, VIEW_CLASS_32_BITS, GL_RGBA8I, VIEW_CLASS_32_BITS, GL_RG16I, 57 VIEW_CLASS_32_BITS, GL_R32I, VIEW_CLASS_32_BITS, GL_RGB10_A2, VIEW_CLASS_32_BITS, GL_RGBA8, VIEW_CLASS_32_BITS, 58 GL_RG16, VIEW_CLASS_32_BITS, GL_RGBA8_SNORM, VIEW_CLASS_32_BITS, GL_RG16_SNORM, VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8, 59 VIEW_CLASS_32_BITS, GL_RGB9_E5, VIEW_CLASS_32_BITS, GL_RGB8, VIEW_CLASS_24_BITS, GL_RGB8_SNORM, VIEW_CLASS_24_BITS, 60 GL_SRGB8, VIEW_CLASS_24_BITS, GL_RGB8UI, VIEW_CLASS_24_BITS, GL_RGB8I, VIEW_CLASS_24_BITS, GL_R16F, 61 VIEW_CLASS_16_BITS, GL_RG8UI, VIEW_CLASS_16_BITS, GL_R16UI, VIEW_CLASS_16_BITS, GL_RG8I, VIEW_CLASS_16_BITS, 62 GL_R16I, VIEW_CLASS_16_BITS, GL_RG8, VIEW_CLASS_16_BITS, GL_R16, VIEW_CLASS_16_BITS, GL_RG8_SNORM, 63 VIEW_CLASS_16_BITS, GL_R16_SNORM, VIEW_CLASS_16_BITS, GL_R8UI, VIEW_CLASS_8_BITS, GL_R8I, VIEW_CLASS_8_BITS, GL_R8, 64 VIEW_CLASS_8_BITS, GL_R8_SNORM, VIEW_CLASS_8_BITS, 65 66 /* Compressed texture formats. */ 67 GL_COMPRESSED_RED_RGTC1, VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1, VIEW_CLASS_RGTC1_RED, 68 GL_COMPRESSED_RG_RGTC2, VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2, VIEW_CLASS_RGTC2_RG, 69 GL_COMPRESSED_RGBA_BPTC_UNORM, VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, VIEW_CLASS_BPTC_UNORM, 70 GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, 71 VIEW_CLASS_BPTC_FLOAT 72 }; 73 74 const int n_internalformat_view_compatibility_array_entries = 75 sizeof(internalformat_view_compatibility_array) / sizeof(internalformat_view_compatibility_array[0]); 76 77 /** Stores all internalformats valid in OpenGL 4.x. Information whether particular internalformat 78 * can be considered supported can be retrieved by calling TextureViewTests::isInternalformatSupported() 79 * function. 80 */ 81 const glw::GLenum valid_gl_internalformats[] = { 82 /* Section 8.5.1 */ 83 GL_RGBA32F, /* >= GL 4.0 */ 84 GL_RGBA32I, /* >= GL 4.0 */ 85 GL_RGBA32UI, /* >= GL 4.0 */ 86 GL_RGBA16, /* >= GL 4.0 */ 87 GL_RGBA16F, /* >= GL 4.0 */ 88 GL_RGBA16I, /* >= GL 4.0 */ 89 GL_RGBA16UI, /* >= GL 4.0 */ 90 GL_RGBA8, /* >= GL 4.0 */ 91 GL_RGBA8I, /* >= GL 4.0 */ 92 GL_RGBA8UI, /* >= GL 4.0 */ 93 GL_SRGB8_ALPHA8, /* >= GL 4.0 */ 94 GL_RGB10_A2, /* >= GL 4.0 */ 95 GL_RGB10_A2UI, /* >= GL 4.0 */ 96 GL_RGB5_A1, /* >= GL 4.0 */ 97 GL_RGBA4, /* >= GL 4.0 */ 98 GL_R11F_G11F_B10F, /* >= GL 4.0 */ 99 GL_RGB565, /* >= GL 4.2 */ 100 GL_RG32F, /* >= GL 4.0 */ 101 GL_RG32I, /* >= GL 4.0 */ 102 GL_RG32UI, /* >= GL 4.0 */ 103 GL_RG16, /* >= GL 4.0 */ 104 GL_RG16F, /* >= GL 4.0 */ 105 GL_RG16I, /* >= GL 4.0 */ 106 GL_RG16UI, /* >= GL 4.0 */ 107 GL_RG8, /* >= GL 4.0 */ 108 GL_RG8I, /* >= GL 4.0 */ 109 GL_RG8UI, /* >= GL 4.0 */ 110 GL_R32F, /* >= GL 4.0 */ 111 GL_R32I, /* >= GL 4.0 */ 112 GL_R32UI, /* >= GL 4.0 */ 113 GL_R16F, /* >= GL 4.0 */ 114 GL_R16I, /* >= GL 4.0 */ 115 GL_R16UI, /* >= GL 4.0 */ 116 GL_R16, /* >= GL 4.0 */ 117 GL_R8, /* >= GL 4.0 */ 118 GL_R8I, /* >= GL 4.0 */ 119 GL_R8UI, /* >= GL 4.0 */ 120 GL_RGBA16_SNORM, /* >= GL 4.0 */ 121 GL_RGBA8_SNORM, /* >= GL 4.0 */ 122 GL_RGB32F, /* >= GL 4.0 */ 123 GL_RGB32I, /* >= GL 4.0 */ 124 GL_RGB32UI, /* >= GL 4.0 */ 125 GL_RGB16_SNORM, /* >= GL 4.0 */ 126 GL_RGB16F, /* >= GL 4.0 */ 127 GL_RGB16I, /* >= GL 4.0 */ 128 GL_RGB16UI, /* >= GL 4.0 */ 129 GL_RGB16, /* >= GL 4.0 */ 130 GL_RGB8_SNORM, /* >= GL 4.0 */ 131 GL_RGB8, /* >= GL 4.0 */ 132 GL_RGB8I, /* >= GL 4.0 */ 133 GL_RGB8UI, /* >= GL 4.0 */ 134 GL_SRGB8, /* >= GL 4.0 */ 135 GL_RGB9_E5, /* >= GL 4.0 */ 136 GL_RG16_SNORM, /* >= GL 4.0 */ 137 GL_RG8_SNORM, /* >= GL 4.0 */ 138 GL_R16_SNORM, /* >= GL 4.0 */ 139 GL_R8_SNORM, /* >= GL 4.0 */ 140 141 GL_DEPTH_COMPONENT32F, /* >= GL 4.0 */ 142 GL_DEPTH_COMPONENT24, /* >= GL 4.0 */ 143 GL_DEPTH_COMPONENT16, /* >= GL 4.0 */ 144 145 GL_DEPTH32F_STENCIL8, /* >= GL 4.0 */ 146 GL_DEPTH24_STENCIL8, /* >= GL 4.0 */ 147 148 /* Table 8.14: generic compressed internalformats have been removed */ 149 GL_COMPRESSED_RED_RGTC1, /* >= GL 4.0 */ 150 GL_COMPRESSED_SIGNED_RED_RGTC1, /* >= GL 4.0 */ 151 GL_COMPRESSED_RG_RGTC2, /* >= GL 4.0 */ 152 GL_COMPRESSED_SIGNED_RG_RGTC2, /* >= GL 4.0 */ 153 GL_COMPRESSED_RGBA_BPTC_UNORM, /* >= GL 4.2 */ 154 GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, /* >= GL 4.2 */ 155 GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, /* >= GL 4.2 */ 156 GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, /* >= GL 4.2 */ 157 GL_COMPRESSED_RGB8_ETC2, /* >= GL 4.3 */ 158 GL_COMPRESSED_SRGB8_ETC2, /* >= GL 4.3 */ 159 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, /* >= GL 4.3 */ 160 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, /* >= GL 4.3 */ 161 GL_COMPRESSED_RGBA8_ETC2_EAC, /* >= GL 4.3 */ 162 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, /* >= GL 4.3 */ 163 GL_COMPRESSED_R11_EAC, /* >= GL 4.3 */ 164 GL_COMPRESSED_SIGNED_R11_EAC, /* >= GL 4.3 */ 165 GL_COMPRESSED_RG11_EAC, /* >= GL 4.3 */ 166 GL_COMPRESSED_SIGNED_RG11_EAC, /* >= GL 4.3 */ 167 }; 168 169 const int n_valid_gl_internalformats = sizeof(valid_gl_internalformats) / sizeof(valid_gl_internalformats[0]); 170 171 /** An array of texture targets that is used by a number of TextureViewUtilities methods. */ 172 static glw::GLenum valid_texture_targets[] = { GL_TEXTURE_1D, 173 GL_TEXTURE_1D_ARRAY, 174 GL_TEXTURE_2D, 175 GL_TEXTURE_2D_ARRAY, 176 GL_TEXTURE_2D_MULTISAMPLE, 177 GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 178 GL_TEXTURE_3D, 179 GL_TEXTURE_BUFFER, 180 GL_TEXTURE_CUBE_MAP, 181 GL_TEXTURE_CUBE_MAP_ARRAY, 182 GL_TEXTURE_RECTANGLE }; 183 const unsigned int n_valid_texture_targets = sizeof(valid_texture_targets) / sizeof(valid_texture_targets[0]); 184 185 /** Retrieves amount of components defined by user-specified internalformat. 186 * 187 * This function throws TestError exception if @param internalformat is not recognized. 188 * 189 * @param internalformat Internalformat to use for the query. 190 * 191 * @return Requested value. 192 **/ 193 unsigned int TextureViewUtilities::getAmountOfComponentsForInternalformat(const glw::GLenum internalformat) 194 { 195 unsigned int result = 0; 196 197 switch (internalformat) 198 { 199 case GL_COMPRESSED_RGBA_BPTC_UNORM: 200 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 201 case GL_RGB10_A2: 202 case GL_RGB10_A2UI: 203 case GL_RGB5_A1: 204 case GL_RGBA16F: 205 case GL_RGBA16I: 206 case GL_RGBA16UI: 207 case GL_RGBA16: 208 case GL_RGBA16_SNORM: 209 case GL_RGBA32F: 210 case GL_RGBA32I: 211 case GL_RGBA32UI: 212 case GL_RGBA4: 213 case GL_RGBA8I: 214 case GL_RGBA8UI: 215 case GL_RGBA8: 216 case GL_RGBA8_SNORM: 217 case GL_SRGB8_ALPHA8: 218 { 219 result = 4; 220 221 break; 222 } 223 224 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 225 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 226 case GL_R11F_G11F_B10F: 227 case GL_RGB16_SNORM: 228 case GL_RGB16F: 229 case GL_RGB16I: 230 case GL_RGB16UI: 231 case GL_RGB16: 232 case GL_RGB32F: 233 case GL_RGB32I: 234 case GL_RGB32UI: 235 case GL_RGB565: 236 case GL_RGB8: 237 case GL_RGB8_SNORM: 238 case GL_RGB8I: 239 case GL_RGB8UI: 240 case GL_RGB9_E5: 241 case GL_SRGB8: 242 { 243 result = 3; 244 245 break; 246 } 247 248 case GL_COMPRESSED_RG_RGTC2: 249 case GL_COMPRESSED_SIGNED_RG_RGTC2: 250 case GL_RG16: 251 case GL_RG16F: 252 case GL_RG16I: 253 case GL_RG16UI: 254 case GL_RG16_SNORM: 255 case GL_RG32F: 256 case GL_RG32I: 257 case GL_RG32UI: 258 case GL_RG8: 259 case GL_RG8_SNORM: 260 case GL_RG8I: 261 case GL_RG8UI: 262 { 263 result = 2; 264 265 break; 266 } 267 268 case GL_COMPRESSED_RED_RGTC1: 269 case GL_COMPRESSED_SIGNED_RED_RGTC1: 270 case GL_DEPTH_COMPONENT16: 271 case GL_DEPTH_COMPONENT24: 272 case GL_DEPTH32F_STENCIL8: /* only one piece of information can be retrieved at a time */ 273 case GL_DEPTH24_STENCIL8: /* only one piece of information can be retrieved at a time */ 274 case GL_R16: 275 case GL_R16_SNORM: 276 case GL_R16F: 277 case GL_R16I: 278 case GL_R16UI: 279 case GL_R32F: 280 case GL_R32I: 281 case GL_R32UI: 282 case GL_R8_SNORM: 283 case GL_R8: 284 case GL_R8I: 285 case GL_R8UI: 286 { 287 result = 1; 288 289 break; 290 } 291 292 default: 293 { 294 TCU_FAIL("Unrecognized internalformat"); 295 } 296 } /* switch (interalformat) */ 297 298 return result; 299 } 300 301 /** Retrieves block size used by user-specified compressed internalformat. 302 * 303 * Throws TestError exception if @param internalformat is not recognized. 304 * 305 * @param internalformat Compressed internalformat to use for the query. 306 * 307 * @return Requested information (in bytes). 308 **/ 309 unsigned int TextureViewUtilities::getBlockSizeForCompressedInternalformat(const glw::GLenum internalformat) 310 { 311 unsigned int result = 0; 312 313 switch (internalformat) 314 { 315 case GL_COMPRESSED_RED_RGTC1: 316 case GL_COMPRESSED_SIGNED_RED_RGTC1: 317 { 318 result = 8; 319 320 break; 321 } 322 323 case GL_COMPRESSED_RG_RGTC2: 324 case GL_COMPRESSED_SIGNED_RG_RGTC2: 325 case GL_COMPRESSED_RGBA_BPTC_UNORM: 326 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 327 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 328 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 329 { 330 result = 16; 331 332 break; 333 } 334 335 default: 336 { 337 TCU_FAIL("Unrecognized internalformat"); 338 } 339 } /* switch (internalformat) */ 340 341 return result; 342 } 343 344 /** Retrieves amount of bits used for R/G/B/A components by user-specified 345 * *non-compressed* internalformat. 346 * 347 * Throws TestError exception if @param internalformat is not recognized. 348 * 349 * @param internalformat Internalformat to use for the query. Must not describe 350 * compressed internalformat. 351 * @param out_rgba_size Must be spacious enough to hold 4 ints. Deref will be 352 * used to store requested information for R/G/B/A channels. 353 * Must not be NULL. 354 **/ 355 void TextureViewUtilities::getComponentSizeForInternalformat(const glw::GLenum internalformat, 356 unsigned int* out_rgba_size) 357 { 358 /* Note: Compressed textures are not supported by this function */ 359 360 /* Reset all the values before we continue. */ 361 memset(out_rgba_size, 0, 4 /* rgba */ * sizeof(unsigned int)); 362 363 /* Depending on the user-specified internalformat, update relevant arguments */ 364 switch (internalformat) 365 { 366 case GL_RGBA32F: 367 case GL_RGBA32I: 368 case GL_RGBA32UI: 369 { 370 out_rgba_size[0] = 32; 371 out_rgba_size[1] = 32; 372 out_rgba_size[2] = 32; 373 out_rgba_size[3] = 32; 374 375 break; 376 } 377 378 case GL_RGBA16F: 379 case GL_RGBA16I: 380 case GL_RGBA16UI: 381 case GL_RGBA16: 382 case GL_RGBA16_SNORM: 383 { 384 out_rgba_size[0] = 16; 385 out_rgba_size[1] = 16; 386 out_rgba_size[2] = 16; 387 out_rgba_size[3] = 16; 388 389 break; 390 } 391 392 case GL_RGBA8I: 393 case GL_RGBA8UI: 394 case GL_RGBA8: 395 case GL_RGBA8_SNORM: 396 case GL_SRGB8_ALPHA8: 397 { 398 out_rgba_size[0] = 8; 399 out_rgba_size[1] = 8; 400 out_rgba_size[2] = 8; 401 out_rgba_size[3] = 8; 402 403 break; 404 } 405 406 case GL_RGB10_A2: 407 case GL_RGB10_A2UI: 408 { 409 out_rgba_size[0] = 10; 410 out_rgba_size[1] = 10; 411 out_rgba_size[2] = 10; 412 out_rgba_size[3] = 2; 413 414 break; 415 } 416 417 case GL_RGB5_A1: 418 { 419 out_rgba_size[0] = 5; 420 out_rgba_size[1] = 5; 421 out_rgba_size[2] = 5; 422 out_rgba_size[3] = 1; 423 424 break; 425 } 426 427 case GL_RGBA4: 428 { 429 out_rgba_size[0] = 4; 430 out_rgba_size[1] = 4; 431 out_rgba_size[2] = 4; 432 out_rgba_size[3] = 4; 433 434 break; 435 } 436 437 case GL_RGB9_E5: 438 { 439 out_rgba_size[0] = 9; 440 out_rgba_size[1] = 9; 441 out_rgba_size[2] = 9; 442 out_rgba_size[3] = 5; 443 444 break; 445 } 446 447 case GL_R11F_G11F_B10F: 448 { 449 out_rgba_size[0] = 11; 450 out_rgba_size[1] = 11; 451 out_rgba_size[2] = 10; 452 453 break; 454 } 455 456 case GL_RGB565: 457 { 458 out_rgba_size[0] = 5; 459 out_rgba_size[1] = 6; 460 out_rgba_size[2] = 5; 461 462 break; 463 } 464 465 case GL_RGB32F: 466 case GL_RGB32I: 467 case GL_RGB32UI: 468 { 469 out_rgba_size[0] = 32; 470 out_rgba_size[1] = 32; 471 out_rgba_size[2] = 32; 472 473 break; 474 } 475 476 case GL_RGB16_SNORM: 477 case GL_RGB16F: 478 case GL_RGB16I: 479 case GL_RGB16UI: 480 case GL_RGB16: 481 { 482 out_rgba_size[0] = 16; 483 out_rgba_size[1] = 16; 484 out_rgba_size[2] = 16; 485 486 break; 487 } 488 489 case GL_RGB8_SNORM: 490 case GL_RGB8: 491 case GL_RGB8I: 492 case GL_RGB8UI: 493 case GL_SRGB8: 494 { 495 out_rgba_size[0] = 8; 496 out_rgba_size[1] = 8; 497 out_rgba_size[2] = 8; 498 499 break; 500 } 501 502 case GL_RG32F: 503 case GL_RG32I: 504 case GL_RG32UI: 505 { 506 out_rgba_size[0] = 32; 507 out_rgba_size[1] = 32; 508 509 break; 510 } 511 512 case GL_RG16: 513 case GL_RG16F: 514 case GL_RG16I: 515 case GL_RG16UI: 516 case GL_RG16_SNORM: 517 { 518 out_rgba_size[0] = 16; 519 out_rgba_size[1] = 16; 520 521 break; 522 } 523 524 case GL_RG8: 525 case GL_RG8I: 526 case GL_RG8UI: 527 case GL_RG8_SNORM: 528 { 529 out_rgba_size[0] = 8; 530 out_rgba_size[1] = 8; 531 532 break; 533 } 534 535 case GL_R32F: 536 case GL_R32I: 537 case GL_R32UI: 538 { 539 out_rgba_size[0] = 32; 540 541 break; 542 } 543 544 case GL_R16F: 545 case GL_R16I: 546 case GL_R16UI: 547 case GL_R16: 548 case GL_R16_SNORM: 549 case GL_DEPTH_COMPONENT16: 550 { 551 out_rgba_size[0] = 16; 552 553 break; 554 } 555 556 case GL_R8: 557 case GL_R8I: 558 case GL_R8UI: 559 case GL_R8_SNORM: 560 { 561 out_rgba_size[0] = 8; 562 563 break; 564 } 565 566 case GL_DEPTH_COMPONENT24: 567 { 568 out_rgba_size[0] = 24; 569 570 break; 571 } 572 573 case GL_DEPTH32F_STENCIL8: 574 { 575 out_rgba_size[0] = 32; 576 out_rgba_size[1] = 8; 577 578 break; 579 } 580 581 case GL_DEPTH24_STENCIL8: 582 { 583 out_rgba_size[0] = 24; 584 out_rgba_size[1] = 8; 585 586 break; 587 } 588 589 default: 590 { 591 TCU_FAIL("Unrecognized internalformat"); 592 } 593 } /* switch (interalformat) */ 594 } 595 596 /** Tells how many bits per components should be used to define input data with 597 * user-specified type. 598 * 599 * Throws TestError exception if @param type is not recognized. 600 * 601 * @param type Type to use for the query. 602 * @param out_rgba_size Deref will be used to store requested information. Must 603 * not be NULL. Must be capacious enough to hold 4 ints. 604 * 605 **/ 606 void TextureViewUtilities::getComponentSizeForType(const glw::GLenum type, unsigned int* out_rgba_size) 607 { 608 memset(out_rgba_size, 0, sizeof(unsigned int) * 4 /* rgba */); 609 610 switch (type) 611 { 612 case GL_BYTE: 613 case GL_UNSIGNED_BYTE: 614 { 615 out_rgba_size[0] = 8; 616 out_rgba_size[1] = 8; 617 out_rgba_size[2] = 8; 618 out_rgba_size[3] = 8; 619 620 break; 621 } 622 623 case GL_FLOAT: 624 case GL_UNSIGNED_INT: 625 case GL_INT: 626 { 627 out_rgba_size[0] = 32; 628 out_rgba_size[1] = 32; 629 out_rgba_size[2] = 32; 630 out_rgba_size[3] = 32; 631 632 break; 633 } 634 635 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 636 { 637 out_rgba_size[0] = 8; 638 out_rgba_size[1] = 24; 639 out_rgba_size[2] = 32; 640 out_rgba_size[3] = 0; 641 642 break; 643 } 644 645 case GL_HALF_FLOAT: 646 case GL_UNSIGNED_SHORT: 647 case GL_SHORT: 648 { 649 out_rgba_size[0] = 16; 650 out_rgba_size[1] = 16; 651 out_rgba_size[2] = 16; 652 out_rgba_size[3] = 16; 653 654 break; 655 } 656 657 case GL_UNSIGNED_INT_10_10_10_2: 658 { 659 out_rgba_size[0] = 10; 660 out_rgba_size[1] = 10; 661 out_rgba_size[2] = 10; 662 out_rgba_size[3] = 2; 663 664 break; 665 } 666 667 case GL_UNSIGNED_INT_10F_11F_11F_REV: 668 { 669 out_rgba_size[0] = 11; 670 out_rgba_size[1] = 11; 671 out_rgba_size[2] = 10; 672 673 break; 674 } 675 676 case GL_UNSIGNED_INT_24_8: 677 { 678 out_rgba_size[0] = 24; 679 out_rgba_size[1] = 8; 680 out_rgba_size[2] = 0; 681 out_rgba_size[3] = 0; 682 683 break; 684 } 685 686 case GL_UNSIGNED_INT_2_10_10_10_REV: 687 { 688 out_rgba_size[0] = 10; 689 out_rgba_size[1] = 10; 690 out_rgba_size[2] = 10; 691 out_rgba_size[3] = 2; 692 693 break; 694 } 695 696 case GL_UNSIGNED_INT_5_9_9_9_REV: 697 { 698 out_rgba_size[0] = 9; 699 out_rgba_size[1] = 9; 700 out_rgba_size[2] = 9; 701 out_rgba_size[3] = 5; 702 703 break; 704 } 705 706 default: 707 { 708 TCU_FAIL("Unrecognized type"); 709 } 710 } /* switch (type) */ 711 } 712 713 /** Returns strings naming GL error codes. 714 * 715 * @param error_code GL error code. 716 * 717 * @return Requested strings or "[?]" if @param error_code was not 718 * recognized. 719 **/ 720 const char* TextureViewUtilities::getErrorCodeString(const glw::GLint error_code) 721 { 722 switch (error_code) 723 { 724 case GL_INVALID_ENUM: 725 return "GL_INVALID_ENUM"; 726 case GL_INVALID_FRAMEBUFFER_OPERATION: 727 return "GL_INVALID_FRAMEBUFFER_OPERATION"; 728 case GL_INVALID_OPERATION: 729 return "GL_INVALID_OPERATION"; 730 case GL_INVALID_VALUE: 731 return "GL_INVALID_VALUE"; 732 case GL_NO_ERROR: 733 return "GL_NO_ERROR"; 734 case GL_OUT_OF_MEMORY: 735 return "GL_OUT_OF_MEMORY"; 736 case GL_STACK_OVERFLOW: 737 return "GL_STACK_OVERFLOW"; 738 case GL_STACK_UNDERFLOW: 739 return "GL_STACK_UNDERFLOW"; 740 default: 741 return "[?]"; 742 } 743 } 744 745 /** Tells what the format of user-specified internalformat is (eg. whether it's a FP, 746 * unorm, snorm, etc.). Note: this is NOT the GL-speak format. 747 * 748 * Supports both compressed and non-compressed internalformats. 749 * Throws TestError exception if @param internalformat is not recognized. 750 * 751 * @param internalformat Internalformat to use for the query. 752 * 753 * @return Requested information. 754 * 755 **/ 756 _format TextureViewUtilities::getFormatOfInternalformat(const glw::GLenum internalformat) 757 { 758 _format result = FORMAT_UNDEFINED; 759 760 switch (internalformat) 761 { 762 case GL_COMPRESSED_RG_RGTC2: 763 case GL_COMPRESSED_RGBA_BPTC_UNORM: 764 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 765 case GL_COMPRESSED_RED_RGTC1: 766 case GL_RGBA16: 767 case GL_RGBA4: 768 case GL_RGBA8: 769 case GL_RGB10_A2: 770 case GL_RGB16: 771 case GL_RGB5_A1: 772 case GL_RGB565: 773 case GL_RGB8: 774 case GL_RG16: 775 case GL_RG8: 776 case GL_R16: 777 case GL_R8: 778 case GL_SRGB8: 779 case GL_SRGB8_ALPHA8: 780 { 781 result = FORMAT_UNORM; 782 783 break; 784 } 785 786 case GL_COMPRESSED_SIGNED_RED_RGTC1: 787 case GL_COMPRESSED_SIGNED_RG_RGTC2: 788 case GL_RGBA16_SNORM: 789 case GL_RGBA8_SNORM: 790 case GL_RGB16_SNORM: 791 case GL_RGB8_SNORM: 792 case GL_RG16_SNORM: 793 case GL_RG8_SNORM: 794 case GL_R16_SNORM: 795 case GL_R8_SNORM: 796 { 797 result = FORMAT_SNORM; 798 799 break; 800 } 801 802 case GL_RGB10_A2UI: 803 case GL_RGBA16UI: 804 case GL_RGBA32UI: 805 case GL_RGBA8UI: 806 case GL_RGB16UI: 807 case GL_RGB32UI: 808 case GL_RGB8UI: 809 case GL_RG16UI: 810 case GL_RG32UI: 811 case GL_RG8UI: 812 case GL_R16UI: 813 case GL_R32UI: 814 case GL_R8UI: 815 { 816 result = FORMAT_UNSIGNED_INTEGER; 817 818 break; 819 } 820 821 case GL_RGB9_E5: 822 { 823 result = FORMAT_RGBE; 824 825 break; 826 } 827 828 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 829 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 830 case GL_DEPTH_COMPONENT16: 831 case GL_DEPTH_COMPONENT24: 832 case GL_DEPTH_COMPONENT32F: 833 case GL_R11F_G11F_B10F: 834 case GL_RGBA16F: 835 case GL_RGBA32F: 836 case GL_RGB16F: 837 case GL_RGB32F: 838 case GL_RG16F: 839 case GL_RG32F: 840 case GL_R16F: 841 case GL_R32F: 842 { 843 result = FORMAT_FLOAT; 844 845 break; 846 } 847 848 case GL_RGBA16I: 849 case GL_RGBA32I: 850 case GL_RGBA8I: 851 case GL_RGB16I: 852 case GL_RGB32I: 853 case GL_RGB8I: 854 case GL_RG16I: 855 case GL_RG32I: 856 case GL_RG8I: 857 case GL_R16I: 858 case GL_R32I: 859 case GL_R8I: 860 { 861 result = FORMAT_SIGNED_INTEGER; 862 863 break; 864 } 865 866 default: 867 { 868 TCU_FAIL("Unrecognized internalformat"); 869 } 870 } /* switch (interalformat) */ 871 872 return result; 873 } 874 875 /** Returns GL format that is compatible with user-specified internalformat. 876 * 877 * Throws TestError exception if @param internalformat is not recognized. 878 * 879 * @param internalformat Internalformat to use for the query. 880 * 881 * @return Requested information. 882 **/ 883 glw::GLenum TextureViewUtilities::getGLFormatOfInternalformat(const glw::GLenum internalformat) 884 { 885 glw::GLenum result = FORMAT_UNDEFINED; 886 887 switch (internalformat) 888 { 889 case GL_COMPRESSED_RGBA_BPTC_UNORM: 890 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 891 case GL_COMPRESSED_RGBA8_ETC2_EAC: 892 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 893 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 894 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 895 { 896 result = GL_COMPRESSED_RGBA; 897 898 break; 899 } 900 901 case GL_RGB10_A2: 902 case GL_RGB5_A1: 903 case GL_RGBA16: 904 case GL_RGBA16F: 905 case GL_RGBA16_SNORM: 906 case GL_RGBA32F: 907 case GL_RGBA4: 908 case GL_RGBA8: 909 case GL_RGBA8_SNORM: 910 case GL_SRGB8_ALPHA8: 911 { 912 result = GL_RGBA; 913 914 break; 915 } 916 917 case GL_RGB10_A2UI: 918 case GL_RGBA16I: 919 case GL_RGBA16UI: 920 case GL_RGBA32I: 921 case GL_RGBA32UI: 922 case GL_RGBA8I: 923 case GL_RGBA8UI: 924 { 925 result = GL_RGBA_INTEGER; 926 927 break; 928 } 929 930 case GL_COMPRESSED_RGB8_ETC2: 931 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 932 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 933 case GL_COMPRESSED_SRGB8_ETC2: 934 { 935 result = GL_COMPRESSED_RGB; 936 937 break; 938 } 939 940 case GL_R11F_G11F_B10F: 941 case GL_RGB16: 942 case GL_RGB16_SNORM: 943 case GL_RGB16F: 944 case GL_RGB32F: 945 case GL_RGB565: 946 case GL_RGB8: 947 case GL_RGB8_SNORM: 948 case GL_RGB9_E5: 949 case GL_SRGB8: 950 { 951 result = GL_RGB; 952 953 break; 954 } 955 956 case GL_RGB16I: 957 case GL_RGB16UI: 958 case GL_RGB32I: 959 case GL_RGB32UI: 960 case GL_RGB8I: 961 case GL_RGB8UI: 962 { 963 result = GL_RGB_INTEGER; 964 965 break; 966 } 967 968 case GL_COMPRESSED_RG_RGTC2: 969 case GL_COMPRESSED_RG11_EAC: 970 case GL_COMPRESSED_SIGNED_RG_RGTC2: 971 case GL_COMPRESSED_SIGNED_RG11_EAC: 972 { 973 result = GL_COMPRESSED_RG; 974 975 break; 976 } 977 978 case GL_RG16: 979 case GL_RG16_SNORM: 980 case GL_RG16F: 981 case GL_RG32F: 982 case GL_RG8: 983 case GL_RG8_SNORM: 984 { 985 result = GL_RG; 986 987 break; 988 } 989 990 case GL_RG16I: 991 case GL_RG16UI: 992 case GL_RG32I: 993 case GL_RG32UI: 994 case GL_RG8I: 995 case GL_RG8UI: 996 { 997 result = GL_RG_INTEGER; 998 999 break; 1000 } 1001 1002 case GL_COMPRESSED_R11_EAC: 1003 case GL_COMPRESSED_RED_RGTC1: 1004 case GL_COMPRESSED_SIGNED_R11_EAC: 1005 case GL_COMPRESSED_SIGNED_RED_RGTC1: 1006 { 1007 result = GL_COMPRESSED_RED; 1008 1009 break; 1010 } 1011 1012 case GL_R16: 1013 case GL_R16F: 1014 case GL_R16_SNORM: 1015 case GL_R32F: 1016 case GL_R8: 1017 case GL_R8_SNORM: 1018 { 1019 result = GL_RED; 1020 1021 break; 1022 } 1023 1024 case GL_R16I: 1025 case GL_R16UI: 1026 case GL_R32I: 1027 case GL_R32UI: 1028 case GL_R8I: 1029 case GL_R8UI: 1030 { 1031 result = GL_RED_INTEGER; 1032 1033 break; 1034 } 1035 1036 case GL_DEPTH_COMPONENT16: 1037 case GL_DEPTH_COMPONENT24: 1038 case GL_DEPTH_COMPONENT32F: 1039 { 1040 result = GL_DEPTH_COMPONENT; 1041 1042 break; 1043 } 1044 1045 case GL_DEPTH24_STENCIL8: 1046 case GL_DEPTH32F_STENCIL8: 1047 { 1048 result = GL_DEPTH_STENCIL; 1049 1050 break; 1051 } 1052 1053 default: 1054 { 1055 TCU_FAIL("Unrecognized internalformat"); 1056 } 1057 } /* switch (internalformat) */ 1058 1059 return result; 1060 } 1061 1062 /** Returns a string that corresponds to a GLSL type that can act as input to user-specified 1063 * sampler type, and which can hold user-specified amount of components. 1064 * 1065 * Throws TestError exception if either of the arguments was found invalid. 1066 * 1067 * @param sampler_type Type of the sampler to use for the query. 1068 * @param n_components Amount of components to use for the query. 1069 * 1070 * @return Requested string. 1071 **/ 1072 const char* TextureViewUtilities::getGLSLDataTypeForSamplerType(const _sampler_type sampler_type, 1073 const unsigned int n_components) 1074 { 1075 const char* result = ""; 1076 1077 switch (sampler_type) 1078 { 1079 case SAMPLER_TYPE_FLOAT: 1080 { 1081 switch (n_components) 1082 { 1083 case 1: 1084 result = "float"; 1085 break; 1086 case 2: 1087 result = "vec2"; 1088 break; 1089 case 3: 1090 result = "vec3"; 1091 break; 1092 case 4: 1093 result = "vec4"; 1094 break; 1095 1096 default: 1097 { 1098 TCU_FAIL("Unsupported number of components"); 1099 } 1100 } /* switch (n_components) */ 1101 1102 break; 1103 } 1104 1105 case SAMPLER_TYPE_SIGNED_INTEGER: 1106 { 1107 switch (n_components) 1108 { 1109 case 1: 1110 result = "int"; 1111 break; 1112 case 2: 1113 result = "ivec2"; 1114 break; 1115 case 3: 1116 result = "ivec3"; 1117 break; 1118 case 4: 1119 result = "ivec4"; 1120 break; 1121 1122 default: 1123 { 1124 TCU_FAIL("Unsupported number of components"); 1125 } 1126 } /* switch (n_components) */ 1127 1128 break; 1129 } 1130 1131 case SAMPLER_TYPE_UNSIGNED_INTEGER: 1132 { 1133 switch (n_components) 1134 { 1135 case 1: 1136 result = "uint"; 1137 break; 1138 case 2: 1139 result = "uvec2"; 1140 break; 1141 case 3: 1142 result = "uvec3"; 1143 break; 1144 case 4: 1145 result = "uvec4"; 1146 break; 1147 1148 default: 1149 { 1150 TCU_FAIL("Unsupported number of components"); 1151 } 1152 } /* switch (n_components) */ 1153 1154 break; 1155 } 1156 1157 default: 1158 { 1159 TCU_FAIL("Unrecognized sampler type"); 1160 } 1161 } /* switch (sampler_type) */ 1162 1163 return result; 1164 } 1165 1166 /** Retrieves a string defining a sampler type in GLSL which corresponds to user-specified internal 1167 * sampler type. 1168 * 1169 * Throws TestError exception if @param sampler_type was not recognized. 1170 * 1171 * @param sampler_type Internal sampler type to use for the query. 1172 * 1173 * @return Requested string. 1174 **/ 1175 const char* TextureViewUtilities::getGLSLTypeForSamplerType(const _sampler_type sampler_type) 1176 { 1177 const char* result = ""; 1178 1179 switch (sampler_type) 1180 { 1181 case SAMPLER_TYPE_FLOAT: 1182 result = "sampler2D"; 1183 break; 1184 case SAMPLER_TYPE_SIGNED_INTEGER: 1185 result = "isampler2D"; 1186 break; 1187 case SAMPLER_TYPE_UNSIGNED_INTEGER: 1188 result = "usampler2D"; 1189 break; 1190 1191 default: 1192 { 1193 TCU_FAIL("Unrecognized sampler type"); 1194 } 1195 } /* switch (sampler_type) */ 1196 1197 return result; 1198 } 1199 1200 /** Returns a vector of texture+view internalformat combinations that are known to be incompatible. 1201 * 1202 * @return Requested information. 1203 **/ 1204 TextureViewUtilities::_incompatible_internalformat_pairs TextureViewUtilities:: 1205 getIllegalTextureAndViewInternalformatCombinations() 1206 { 1207 TextureViewUtilities::_incompatible_internalformat_pairs result; 1208 1209 /* Iterate in two loops over the set of supported internalformats */ 1210 for (int n_texture_internalformat = 0; 1211 n_texture_internalformat < 1212 (n_internalformat_view_compatibility_array_entries / 2); /* the array stores two values per entry */ 1213 ++n_texture_internalformat) 1214 { 1215 glw::GLenum src_internalformat = internalformat_view_compatibility_array[(n_texture_internalformat * 2) + 0]; 1216 _view_class src_view_class = 1217 (_view_class)internalformat_view_compatibility_array[(n_texture_internalformat * 2) + 1]; 1218 1219 for (int n_view_internalformat = n_texture_internalformat + 1; 1220 n_view_internalformat < (n_internalformat_view_compatibility_array_entries >> 1); ++n_view_internalformat) 1221 { 1222 glw::GLenum view_internalformat = internalformat_view_compatibility_array[(n_view_internalformat * 2) + 0]; 1223 _view_class view_view_class = 1224 (_view_class)internalformat_view_compatibility_array[(n_view_internalformat * 2) + 1]; 1225 1226 if (src_view_class != view_view_class) 1227 { 1228 result.push_back(_internalformat_pair(src_internalformat, view_internalformat)); 1229 } 1230 } /* for (all internalformats we can use for the texture view) */ 1231 } /* for (all internalformats we can use for the parent texture) */ 1232 1233 return result; 1234 } 1235 1236 /** Returns a vector of texture+view target texture combinations that are known to be incompatible. 1237 * 1238 * @return Requested information. 1239 **/ 1240 TextureViewUtilities::_incompatible_texture_target_pairs TextureViewUtilities:: 1241 getIllegalTextureAndViewTargetCombinations() 1242 { 1243 _incompatible_texture_target_pairs result; 1244 1245 /* Iterate through all combinations of texture targets and store those that are 1246 * reported as invalid 1247 */ 1248 for (unsigned int n_parent_texture_target = 0; n_parent_texture_target < n_valid_texture_targets; 1249 ++n_parent_texture_target) 1250 { 1251 glw::GLenum parent_texture_target = valid_texture_targets[n_parent_texture_target]; 1252 1253 for (unsigned int n_view_texture_target = 0; n_view_texture_target < n_valid_texture_targets; 1254 ++n_view_texture_target) 1255 { 1256 glw::GLenum view_texture_target = valid_texture_targets[n_view_texture_target]; 1257 1258 if (!isLegalTextureTargetForTextureView(parent_texture_target, view_texture_target)) 1259 { 1260 result.push_back(_internalformat_pair(parent_texture_target, view_texture_target)); 1261 } 1262 } /* for (all texture targets considered for views) */ 1263 } /* for (all texture targets considered for parent texture) */ 1264 1265 return result; 1266 } 1267 1268 /** Returns internalformats associated with user-specified view class. 1269 * 1270 * @param view_class View class to use for the query. 1271 * 1272 * @return Requested information. 1273 **/ 1274 TextureViewUtilities::_internalformats TextureViewUtilities::getInternalformatsFromViewClass(_view_class view_class) 1275 { 1276 _internalformats result; 1277 1278 /* Iterate over the data array and push those internalformats that match the requested view class */ 1279 const unsigned int n_array_elements = n_internalformat_view_compatibility_array_entries; 1280 1281 for (unsigned int n_array_pair = 0; n_array_pair < (n_array_elements >> 1); ++n_array_pair) 1282 { 1283 const glw::GLenum internalformat = internalformat_view_compatibility_array[n_array_pair * 2 + 0]; 1284 const _view_class current_view_class = 1285 (_view_class)internalformat_view_compatibility_array[n_array_pair * 2 + 1]; 1286 1287 if (current_view_class == view_class) 1288 { 1289 result.push_back(internalformat); 1290 } 1291 } /* for (all pairs in the data array) */ 1292 1293 return result; 1294 } 1295 1296 /** Returns a string defining user-specified internalformat. 1297 * 1298 * Throws a TestError exception if @param internalformat was not recognized. 1299 * 1300 * @param internalformat Internalformat to use for the query. 1301 * 1302 * @return Requested string. 1303 **/ 1304 const char* TextureViewUtilities::getInternalformatString(const glw::GLenum internalformat) 1305 { 1306 const char* result = "[?]"; 1307 1308 switch (internalformat) 1309 { 1310 case GL_RGBA32F: 1311 result = "GL_RGBA32F"; 1312 break; 1313 case GL_RGBA32I: 1314 result = "GL_RGBA32I"; 1315 break; 1316 case GL_RGBA32UI: 1317 result = "GL_RGBA32UI"; 1318 break; 1319 case GL_RGBA16: 1320 result = "GL_RGBA16"; 1321 break; 1322 case GL_RGBA16F: 1323 result = "GL_RGBA16F"; 1324 break; 1325 case GL_RGBA16I: 1326 result = "GL_RGBA16I"; 1327 break; 1328 case GL_RGBA16UI: 1329 result = "GL_RGBA16UI"; 1330 break; 1331 case GL_RGBA8: 1332 result = "GL_RGBA8"; 1333 break; 1334 case GL_RGBA8I: 1335 result = "GL_RGBA8I"; 1336 break; 1337 case GL_RGBA8UI: 1338 result = "GL_RGBA8UI"; 1339 break; 1340 case GL_SRGB8_ALPHA8: 1341 result = "GL_SRGB8_ALPHA8"; 1342 break; 1343 case GL_RGB10_A2: 1344 result = "GL_RGB10_A2"; 1345 break; 1346 case GL_RGB10_A2UI: 1347 result = "GL_RGB10_A2UI"; 1348 break; 1349 case GL_RGB5_A1: 1350 result = "GL_RGB5_A1"; 1351 break; 1352 case GL_RGBA4: 1353 result = "GL_RGBA4"; 1354 break; 1355 case GL_R11F_G11F_B10F: 1356 result = "GL_R11F_G11F_B10F"; 1357 break; 1358 case GL_RGB565: 1359 result = "GL_RGB565"; 1360 break; 1361 case GL_RG32F: 1362 result = "GL_RG32F"; 1363 break; 1364 case GL_RG32I: 1365 result = "GL_RG32I"; 1366 break; 1367 case GL_RG32UI: 1368 result = "GL_RG32UI"; 1369 break; 1370 case GL_RG16: 1371 result = "GL_RG16"; 1372 break; 1373 case GL_RG16F: 1374 result = "GL_RG16F"; 1375 break; 1376 case GL_RG16I: 1377 result = "GL_RG16I"; 1378 break; 1379 case GL_RG16UI: 1380 result = "GL_RG16UI"; 1381 break; 1382 case GL_RG8: 1383 result = "GL_RG8"; 1384 break; 1385 case GL_RG8I: 1386 result = "GL_RG8I"; 1387 break; 1388 case GL_RG8UI: 1389 result = "GL_RG8UI"; 1390 break; 1391 case GL_R32F: 1392 result = "GL_R32F"; 1393 break; 1394 case GL_R32I: 1395 result = "GL_R32I"; 1396 break; 1397 case GL_R32UI: 1398 result = "GL_R32UI"; 1399 break; 1400 case GL_R16F: 1401 result = "GL_R16F"; 1402 break; 1403 case GL_R16I: 1404 result = "GL_R16I"; 1405 break; 1406 case GL_R16UI: 1407 result = "GL_R16UI"; 1408 break; 1409 case GL_R16: 1410 result = "GL_R16"; 1411 break; 1412 case GL_R8: 1413 result = "GL_R8"; 1414 break; 1415 case GL_R8I: 1416 result = "GL_R8I"; 1417 break; 1418 case GL_R8UI: 1419 result = "GL_R8UI"; 1420 break; 1421 case GL_RGBA16_SNORM: 1422 result = "GL_RGBA16_SNORM"; 1423 break; 1424 case GL_RGBA8_SNORM: 1425 result = "GL_RGBA8_SNORM"; 1426 break; 1427 case GL_RGB32F: 1428 result = "GL_RGB32F"; 1429 break; 1430 case GL_RGB32I: 1431 result = "GL_RGB32I"; 1432 break; 1433 case GL_RGB32UI: 1434 result = "GL_RGB32UI"; 1435 break; 1436 case GL_RGB16_SNORM: 1437 result = "GL_RGB16_SNORM"; 1438 break; 1439 case GL_RGB16F: 1440 result = "GL_RGB16F"; 1441 break; 1442 case GL_RGB16I: 1443 result = "GL_RGB16I"; 1444 break; 1445 case GL_RGB16UI: 1446 result = "GL_RGB16UI"; 1447 break; 1448 case GL_RGB16: 1449 result = "GL_RGB16"; 1450 break; 1451 case GL_RGB8_SNORM: 1452 result = "GL_RGB8_SNORM"; 1453 break; 1454 case GL_RGB8: 1455 result = "GL_RGB8"; 1456 break; 1457 case GL_RGB8I: 1458 result = "GL_RGB8I"; 1459 break; 1460 case GL_RGB8UI: 1461 result = "GL_RGB8UI"; 1462 break; 1463 case GL_SRGB8: 1464 result = "GL_SRGB8"; 1465 break; 1466 case GL_RGB9_E5: 1467 result = "GL_RGB9_E5"; 1468 break; 1469 case GL_RG16_SNORM: 1470 result = "GL_RG16_SNORM"; 1471 break; 1472 case GL_RG8_SNORM: 1473 result = "GL_RG8_SNORM"; 1474 break; 1475 case GL_R16_SNORM: 1476 result = "GL_R16_SNORM"; 1477 break; 1478 case GL_R8_SNORM: 1479 result = "GL_R8_SNORM"; 1480 break; 1481 case GL_DEPTH_COMPONENT32F: 1482 result = "GL_DEPTH_COMPONENT32F"; 1483 break; 1484 case GL_DEPTH_COMPONENT24: 1485 result = "GL_DEPTH_COMPONENT24"; 1486 break; 1487 case GL_DEPTH_COMPONENT16: 1488 result = "GL_DEPTH_COMPONENT16"; 1489 break; 1490 case GL_DEPTH32F_STENCIL8: 1491 result = "GL_DEPTH32F_STENCIL8"; 1492 break; 1493 case GL_DEPTH24_STENCIL8: 1494 result = "GL_DEPTH24_STENCIL8"; 1495 break; 1496 case GL_COMPRESSED_RED_RGTC1: 1497 result = "GL_COMPRESSED_RED_RGTC1"; 1498 break; 1499 case GL_COMPRESSED_SIGNED_RED_RGTC1: 1500 result = "GL_COMPRESSED_SIGNED_RED_RGTC1"; 1501 break; 1502 case GL_COMPRESSED_RG_RGTC2: 1503 result = "GL_COMPRESSED_RG_RGTC2"; 1504 break; 1505 case GL_COMPRESSED_SIGNED_RG_RGTC2: 1506 result = "GL_COMPRESSED_SIGNED_RG_RGTC2"; 1507 break; 1508 case GL_COMPRESSED_RGBA_BPTC_UNORM: 1509 result = "GL_COMPRESSED_RGBA_BPTC_UNORM"; 1510 break; 1511 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 1512 result = "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM"; 1513 break; 1514 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 1515 result = "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT"; 1516 break; 1517 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 1518 result = "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT"; 1519 break; 1520 case GL_COMPRESSED_RGB8_ETC2: 1521 result = "GL_COMPRESSED_RGB8_ETC2"; 1522 break; 1523 case GL_COMPRESSED_SRGB8_ETC2: 1524 result = "GL_COMPRESSED_SRGB8_ETC2"; 1525 break; 1526 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 1527 result = "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; 1528 break; 1529 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 1530 result = "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; 1531 break; 1532 case GL_COMPRESSED_RGBA8_ETC2_EAC: 1533 result = "GL_COMPRESSED_RGBA8_ETC2_EAC"; 1534 break; 1535 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 1536 result = "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; 1537 break; 1538 case GL_COMPRESSED_R11_EAC: 1539 result = "GL_COMPRESSED_R11_EAC"; 1540 break; 1541 case GL_COMPRESSED_SIGNED_R11_EAC: 1542 result = "GL_COMPRESSED_SIGNED_R11_EAC"; 1543 break; 1544 case GL_COMPRESSED_RG11_EAC: 1545 result = "GL_COMPRESSED_RG11_EAC"; 1546 break; 1547 case GL_COMPRESSED_SIGNED_RG11_EAC: 1548 result = "GL_COMPRESSED_SIGNED_RG11_EAC"; 1549 break; 1550 1551 default: 1552 TCU_FAIL("Unrecognized internalformat"); 1553 } 1554 1555 return result; 1556 } 1557 1558 /** Returns all texture+view internalformat pairs that are valid in light of GL_ARB_texture_view specification. 1559 * 1560 * @return As described. 1561 **/ 1562 TextureViewUtilities::_compatible_internalformat_pairs TextureViewUtilities:: 1563 getLegalTextureAndViewInternalformatCombinations() 1564 { 1565 _compatible_internalformat_pairs result; 1566 1567 /* Iterate over all view classes */ 1568 for (int current_view_class_it = static_cast<int>(VIEW_CLASS_FIRST); 1569 current_view_class_it != static_cast<int>(VIEW_CLASS_COUNT); current_view_class_it++) 1570 { 1571 _view_class current_view_class = static_cast<_view_class>(current_view_class_it); 1572 _internalformats view_class_internalformats = getInternalformatsFromViewClass(current_view_class); 1573 1574 /* Store all combinations in the result vector */ 1575 for (_internalformats_const_iterator left_iterator = view_class_internalformats.begin(); 1576 left_iterator != view_class_internalformats.end(); left_iterator++) 1577 { 1578 for (_internalformats_const_iterator right_iterator = view_class_internalformats.begin(); 1579 right_iterator != view_class_internalformats.end(); ++right_iterator) 1580 { 1581 result.push_back(_internalformat_pair(*left_iterator, *right_iterator)); 1582 } /* for (all internalformats to be used as right-side values) */ 1583 } /* for (all internalformats to be used as left-side values) */ 1584 } /* for (all view classes) */ 1585 1586 return result; 1587 } 1588 1589 /** Returns all valid texture+view texture targets pairs. 1590 * 1591 * @return As per description. 1592 **/ 1593 TextureViewUtilities::_compatible_texture_target_pairs TextureViewUtilities::getLegalTextureAndViewTargetCombinations() 1594 { 1595 _compatible_texture_target_pairs result; 1596 1597 /* Iterate over all texture targets valid for a glTextureView() call. Consider each one of them as 1598 * original texture target. 1599 */ 1600 for (unsigned int n_original_texture_target = 0; n_original_texture_target < n_valid_texture_targets; 1601 ++n_original_texture_target) 1602 { 1603 const glw::GLenum original_texture_target = valid_texture_targets[n_original_texture_target]; 1604 1605 /* Iterate again, but this time consider each texture target as a valid new target */ 1606 for (unsigned int n_compatible_texture_target = 0; n_compatible_texture_target < n_valid_texture_targets; 1607 ++n_compatible_texture_target) 1608 { 1609 const glw::GLenum view_texture_target = valid_texture_targets[n_compatible_texture_target]; 1610 1611 if (TextureViewUtilities::isLegalTextureTargetForTextureView(original_texture_target, view_texture_target)) 1612 { 1613 result.push_back(_texture_target_pair(original_texture_target, view_texture_target)); 1614 } 1615 } /* for (all texture targets that are potentially compatible) */ 1616 } /* for (all original texture targets) */ 1617 1618 return result; 1619 } 1620 1621 /** Returns major & minor version for user-specified CTS rendering context type. 1622 * 1623 * @param context_type CTS rendering context type. 1624 * @param out_major_version Deref will be used to store major version. Must not be NULL. 1625 * @param out_minor_version Deref will be used to store minor version. Must not be NULL. 1626 * 1627 **/ 1628 void TextureViewUtilities::getMajorMinorVersionFromContextVersion(const glu::ContextType& context_type, 1629 glw::GLint* out_major_version, 1630 glw::GLint* out_minor_version) 1631 { 1632 if (context_type.getAPI() == glu::ApiType::core(4, 0)) 1633 { 1634 *out_major_version = 4; 1635 *out_minor_version = 0; 1636 } 1637 else if (context_type.getAPI() == glu::ApiType::core(4, 1)) 1638 { 1639 *out_major_version = 4; 1640 *out_minor_version = 1; 1641 } 1642 else if (context_type.getAPI() == glu::ApiType::core(4, 2)) 1643 { 1644 *out_major_version = 4; 1645 *out_minor_version = 2; 1646 } 1647 else if (context_type.getAPI() == glu::ApiType::core(4, 3)) 1648 { 1649 *out_major_version = 4; 1650 *out_minor_version = 3; 1651 } 1652 else if (context_type.getAPI() == glu::ApiType::core(4, 4)) 1653 { 1654 *out_major_version = 4; 1655 *out_minor_version = 4; 1656 } 1657 else if (context_type.getAPI() == glu::ApiType::core(4, 5)) 1658 { 1659 *out_major_version = 4; 1660 *out_minor_version = 5; 1661 } 1662 else if (context_type.getAPI() == glu::ApiType::core(4, 6)) 1663 { 1664 *out_major_version = 4; 1665 *out_minor_version = 6; 1666 } 1667 else 1668 { 1669 TCU_FAIL("Unrecognized rendering context version"); 1670 } 1671 } 1672 1673 /** Tells which sampler can be used to sample a texture defined with user-specified 1674 * internalformat. 1675 * 1676 * Supports both compressed and non-compressed internalformats. 1677 * Throws TestError exception if @param internalformat was not recognized. 1678 * 1679 * @param internalformat Internalformat to use for the query. 1680 * 1681 * @return Requested information. 1682 **/ 1683 _sampler_type TextureViewUtilities::getSamplerTypeForInternalformat(const glw::GLenum internalformat) 1684 { 1685 _sampler_type result = SAMPLER_TYPE_UNDEFINED; 1686 1687 /* Compressed internalformats not supported at the moment */ 1688 1689 switch (internalformat) 1690 { 1691 case GL_COMPRESSED_RED_RGTC1: 1692 case GL_COMPRESSED_SIGNED_RED_RGTC1: 1693 case GL_COMPRESSED_RG_RGTC2: 1694 case GL_COMPRESSED_SIGNED_RG_RGTC2: 1695 case GL_COMPRESSED_RGBA_BPTC_UNORM: 1696 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 1697 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 1698 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 1699 case GL_DEPTH_COMPONENT16: 1700 case GL_DEPTH_COMPONENT24: 1701 case GL_DEPTH_COMPONENT32F: 1702 case GL_RGBA16: 1703 case GL_RGBA16_SNORM: 1704 case GL_RGBA16F: 1705 case GL_RGBA32F: 1706 case GL_RGBA4: 1707 case GL_RGBA8: 1708 case GL_RGBA8_SNORM: 1709 case GL_RGB10_A2: 1710 case GL_RGB16: 1711 case GL_RGB16_SNORM: 1712 case GL_RGB16F: 1713 case GL_RGB32F: 1714 case GL_RGB5_A1: 1715 case GL_RGB565: 1716 case GL_RGB8: 1717 case GL_RGB8_SNORM: 1718 case GL_RGB9_E5: 1719 case GL_RG16: 1720 case GL_RG16_SNORM: 1721 case GL_RG16F: 1722 case GL_RG32F: 1723 case GL_RG8: 1724 case GL_RG8_SNORM: 1725 case GL_R11F_G11F_B10F: 1726 case GL_R16: 1727 case GL_R16F: 1728 case GL_R16_SNORM: 1729 case GL_R32F: 1730 case GL_R8: 1731 case GL_R8_SNORM: 1732 case GL_SRGB8_ALPHA8: 1733 case GL_SRGB8: 1734 { 1735 result = SAMPLER_TYPE_FLOAT; 1736 1737 break; 1738 } 1739 1740 case GL_RGB10_A2UI: 1741 case GL_RGBA32UI: 1742 case GL_RGBA16UI: 1743 case GL_RGBA8UI: 1744 case GL_RGB16UI: 1745 case GL_RGB32UI: 1746 case GL_RGB8UI: 1747 case GL_RG16UI: 1748 case GL_RG32UI: 1749 case GL_RG8UI: 1750 case GL_R16UI: 1751 case GL_R32UI: 1752 case GL_R8UI: 1753 { 1754 result = SAMPLER_TYPE_UNSIGNED_INTEGER; 1755 1756 break; 1757 } 1758 1759 case GL_RGBA16I: 1760 case GL_RGBA32I: 1761 case GL_RGBA8I: 1762 case GL_RGB16I: 1763 case GL_RGB32I: 1764 case GL_RGB8I: 1765 case GL_RG16I: 1766 case GL_RG32I: 1767 case GL_RG8I: 1768 case GL_R16I: 1769 case GL_R32I: 1770 case GL_R8I: 1771 { 1772 result = SAMPLER_TYPE_SIGNED_INTEGER; 1773 1774 break; 1775 } 1776 1777 default: 1778 { 1779 TCU_FAIL("Unrecognized internalformat"); 1780 } 1781 } /* switch (interalformat) */ 1782 1783 return result; 1784 } 1785 1786 /** Tells how many bytes are required to define a texture mip-map using 1787 * user-specified internalformat and type, assuming user-defined mip-map 1788 * resolution. Compressed internalformats are NOT supported. 1789 * 1790 * Throws TestError exception if @param internalformat or @param type are 1791 * found invalid. 1792 * 1793 * @param internalformat Internalformat to use for the query. 1794 * @param type Type to use for the query. 1795 * @param width Mip-map width to use for the query. 1796 * @param height Mip-map height to use for the query. 1797 * 1798 * @return Requested information. 1799 **/ 1800 unsigned int TextureViewUtilities::getTextureDataSize(const glw::GLenum internalformat, const glw::GLenum type, 1801 const unsigned int width, const unsigned int height) 1802 { 1803 unsigned int internalformat_rgba_size[4] = { 0 }; 1804 unsigned int type_rgba_size[4] = { 0 }; 1805 unsigned int texel_size = 0; 1806 1807 TextureViewUtilities::getComponentSizeForInternalformat(internalformat, internalformat_rgba_size); 1808 TextureViewUtilities::getComponentSizeForType(type, type_rgba_size); 1809 1810 if (internalformat_rgba_size[0] == 0) 1811 { 1812 type_rgba_size[0] = 0; 1813 } 1814 1815 if (internalformat_rgba_size[1] == 0) 1816 { 1817 type_rgba_size[1] = 0; 1818 } 1819 1820 if (internalformat_rgba_size[2] == 0) 1821 { 1822 type_rgba_size[2] = 0; 1823 } 1824 1825 if (internalformat_rgba_size[3] == 0) 1826 { 1827 type_rgba_size[3] = 0; 1828 } 1829 1830 texel_size = type_rgba_size[0] + type_rgba_size[1] + type_rgba_size[2] + type_rgba_size[3]; 1831 1832 /* Current implementation assumes we do not need to use bit resolution when 1833 * preparing texel data. Make extra sure we're not wrong. */ 1834 DE_ASSERT((texel_size % 8) == 0); 1835 1836 texel_size /= 8; /* bits per byte */ 1837 1838 return texel_size * width * height; 1839 } 1840 1841 /** Returns a string corresponding to a GL enum describing a texture target. 1842 * 1843 * @return As per description or "[?]" if the enum was not recognized. 1844 **/ 1845 const char* TextureViewUtilities::getTextureTargetString(const glw::GLenum texture_target) 1846 { 1847 const char* result = "[?]"; 1848 1849 switch (texture_target) 1850 { 1851 case GL_TEXTURE_1D: 1852 result = "GL_TEXTURE_1D"; 1853 break; 1854 case GL_TEXTURE_1D_ARRAY: 1855 result = "GL_TEXTURE_1D_ARRAY"; 1856 break; 1857 case GL_TEXTURE_2D: 1858 result = "GL_TEXTURE_2D"; 1859 break; 1860 case GL_TEXTURE_2D_ARRAY: 1861 result = "GL_TEXTURE_2D_ARRAY"; 1862 break; 1863 case GL_TEXTURE_2D_MULTISAMPLE: 1864 result = "GL_TEXTURE_2D_MULTISAMPLE"; 1865 break; 1866 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1867 result = "GL_TEXTURE_2D_MULTISAMPLE_ARRAY"; 1868 break; 1869 case GL_TEXTURE_3D: 1870 result = "GL_TEXTURE_3D"; 1871 break; 1872 case GL_TEXTURE_BUFFER: 1873 result = "GL_TEXTURE_BUFFER"; 1874 break; 1875 case GL_TEXTURE_CUBE_MAP: 1876 result = "GL_TEXTURE_CUBE_MAP"; 1877 break; 1878 case GL_TEXTURE_CUBE_MAP_ARRAY: 1879 result = "GL_TEXTURE_CUBE_MAP_ARRAY"; 1880 break; 1881 case GL_TEXTURE_RECTANGLE: 1882 result = "GL_TEXTURE_RECTANGLE"; 1883 break; 1884 } 1885 1886 return result; 1887 } 1888 1889 /** Returns GL type that can be used to define a texture mip-map defined 1890 * with an internalformat of @param internalformat. 1891 * 1892 * Throws TestError exception if @param internalformat was found to be invalid. 1893 * 1894 * @param internalformat Internalformat to use for the query. 1895 * 1896 * @return Requested information. 1897 **/ 1898 glw::GLenum TextureViewUtilities::getTypeCompatibleWithInternalformat(const glw::GLenum internalformat) 1899 { 1900 glw::GLenum result = GL_NONE; 1901 1902 /* Compressed internalformats not supported at the moment */ 1903 1904 switch (internalformat) 1905 { 1906 case GL_RGBA8_SNORM: 1907 case GL_RGB8_SNORM: 1908 case GL_RG8_SNORM: 1909 case GL_R8_SNORM: 1910 case GL_RGBA8I: 1911 case GL_RGB8I: 1912 case GL_RG8I: 1913 case GL_R8I: 1914 { 1915 result = GL_BYTE; 1916 1917 break; 1918 } 1919 1920 case GL_DEPTH24_STENCIL8: 1921 { 1922 result = GL_UNSIGNED_INT_24_8; 1923 1924 break; 1925 } 1926 1927 case GL_DEPTH32F_STENCIL8: 1928 { 1929 result = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; 1930 1931 break; 1932 } 1933 1934 case GL_RGBA16F: 1935 case GL_RGB16F: 1936 case GL_RG16F: 1937 case GL_R16F: 1938 { 1939 result = GL_HALF_FLOAT; 1940 1941 break; 1942 } 1943 1944 case GL_DEPTH_COMPONENT32F: 1945 case GL_RGBA32F: 1946 case GL_RGB32F: 1947 case GL_RG32F: 1948 case GL_R11F_G11F_B10F: 1949 case GL_R32F: 1950 { 1951 result = GL_FLOAT; 1952 1953 break; 1954 } 1955 1956 case GL_RGBA16_SNORM: 1957 case GL_RGB16_SNORM: 1958 case GL_RG16_SNORM: 1959 case GL_R16_SNORM: 1960 { 1961 result = GL_SHORT; 1962 1963 break; 1964 } 1965 1966 case GL_RGBA4: 1967 case GL_RGBA8: 1968 case GL_RGB10_A2: 1969 case GL_RGB5_A1: 1970 case GL_RGB565: 1971 case GL_RGB8: 1972 case GL_RGB9_E5: 1973 case GL_RG8: 1974 case GL_R8: 1975 case GL_SRGB8_ALPHA8: 1976 case GL_SRGB8: 1977 case GL_RGBA8UI: 1978 case GL_RGB8UI: 1979 case GL_RG8UI: 1980 case GL_R8UI: 1981 { 1982 result = GL_UNSIGNED_BYTE; 1983 1984 break; 1985 } 1986 1987 case GL_R16I: 1988 case GL_RGBA16I: 1989 case GL_RGB16I: 1990 case GL_RG16I: 1991 { 1992 result = GL_SHORT; 1993 1994 break; 1995 } 1996 1997 case GL_DEPTH_COMPONENT16: 1998 case GL_RGBA16: 1999 case GL_RGB16: 2000 case GL_RG16: 2001 case GL_R16: 2002 case GL_RGBA16UI: 2003 case GL_RGB16UI: 2004 case GL_RG16UI: 2005 case GL_R16UI: 2006 { 2007 result = GL_UNSIGNED_SHORT; 2008 2009 break; 2010 } 2011 2012 case GL_RGBA32I: 2013 case GL_RGB32I: 2014 case GL_RG32I: 2015 case GL_R32I: 2016 { 2017 result = GL_INT; 2018 2019 break; 2020 } 2021 2022 case GL_DEPTH_COMPONENT24: 2023 case GL_RGBA32UI: 2024 case GL_RGB32UI: 2025 case GL_RG32UI: 2026 case GL_R32UI: 2027 { 2028 result = GL_UNSIGNED_INT; 2029 2030 break; 2031 } 2032 2033 case GL_RGB10_A2UI: 2034 { 2035 result = GL_UNSIGNED_INT_2_10_10_10_REV; 2036 2037 break; 2038 } 2039 2040 default: 2041 { 2042 TCU_FAIL("Unrecognized internalformat"); 2043 } 2044 } /* switch (interalformat) */ 2045 2046 return result; 2047 } 2048 2049 /** Tells what view class is the user-specified internalformat associated with. 2050 * 2051 * Implements Table 8.21 from OpenGL Specification 4.3 2052 * 2053 * @param internalformat Internalformat to use for the query. 2054 * 2055 * @return Requested information or VIEW_CLASS_UNDEFINED if @param internalformat 2056 * has not been recognized. 2057 **/ 2058 _view_class TextureViewUtilities::getViewClassForInternalformat(const glw::GLenum internalformat) 2059 { 2060 _view_class result = VIEW_CLASS_UNDEFINED; 2061 2062 /* Note that n_internalformat_view_compatibility_array_entries needs to be divided by 2 2063 * because the value refers to a total number of entries in the array, not to the number 2064 * of pairs that can be read. 2065 */ 2066 for (int n_entry = 0; n_entry < (n_internalformat_view_compatibility_array_entries >> 1); n_entry++) 2067 { 2068 glw::GLenum array_internalformat = internalformat_view_compatibility_array[(n_entry * 2) + 0]; 2069 _view_class view_class = (_view_class)internalformat_view_compatibility_array[(n_entry * 2) + 1]; 2070 2071 if (array_internalformat == internalformat) 2072 { 2073 result = view_class; 2074 2075 break; 2076 } 2077 } /* for (all pairs in data array) */ 2078 2079 return result; 2080 } 2081 2082 /** Initializes texture storage for either an immutable or mutable texture object, 2083 * depending on configuration of the test run the storage is to be initialized for. 2084 * 2085 * @param gl GL entry-points to use for storage initialization. 2086 * @param init_mutable_to true if a mutable texture storage should be initialized, 2087 * false to initialize immutable texture storage. 2088 * @param texture_target Texture target to be used. 2089 * @param texture_depth Depth to be used for texture storage. Only used 2090 * for texture targets that use the depth information. 2091 * @param texture_height Height to be used for texture storage. Only used 2092 * for texture targets that use the height information. 2093 * @param texture_width Width to be used for texture storage. 2094 * @param texture_internalformat Internalformat to be used for texture storage. 2095 * @param texture_format Format to be used for texture storage. 2096 * @param texture_type Type to be used for texture storage. 2097 * @param n_levels_needed Amount of mip-map levels that should be used for texture storage. 2098 * Only used for texture targets that support mip-maps. 2099 * @param n_cubemaps_needed Amount of cube-maps to be used for initialization of cube map 2100 * array texture storage. Only used if @param texture_internalformat 2101 * is set to GL_TEXTURE_CUBE_MAP_ARRAY. 2102 * @param bo_id ID of a buffer object to be used for initialization of 2103 * buffer texture storage. Only used if @param texture_internalformat 2104 * is set to GL_TEXTURE_BUFFEER. 2105 * 2106 **/ 2107 void TextureViewUtilities::initTextureStorage(const glw::Functions& gl, bool init_mutable_to, 2108 glw::GLenum texture_target, glw::GLint texture_depth, 2109 glw::GLint texture_height, glw::GLint texture_width, 2110 glw::GLenum texture_internalformat, glw::GLenum texture_format, 2111 glw::GLenum texture_type, unsigned int n_levels_needed, 2112 unsigned int n_cubemaps_needed, glw::GLint bo_id) 2113 { 2114 const glw::GLenum cubemap_texture_targets[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 2115 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 2116 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; 2117 const unsigned int n_cubemap_texture_targets = sizeof(cubemap_texture_targets) / sizeof(cubemap_texture_targets[0]); 2118 2119 /* If we're going to be initializing a multisample texture object, 2120 * determine how many samples can be used for GL_RGBA8 internalformat, 2121 * given texture target that is of our interest */ 2122 glw::GLint gl_max_color_texture_samples_value = 0; 2123 2124 gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &gl_max_color_texture_samples_value); 2125 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES"); 2126 2127 if (texture_target == GL_TEXTURE_BUFFER) 2128 { 2129 gl.texBuffer(GL_TEXTURE_BUFFER, texture_internalformat, bo_id); 2130 2131 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexBuffer() call failed for GL_TEXTURE_BUFFER target"); 2132 } 2133 else if (init_mutable_to) 2134 { 2135 for (unsigned int n_level = 0; n_level < n_levels_needed; ++n_level) 2136 { 2137 /* If level != 0 and we're trying to initialize a texture target which 2138 * only accepts a single level, leave now 2139 */ 2140 if (n_level != 0 && 2141 (texture_target == GL_TEXTURE_RECTANGLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE || 2142 texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || texture_target == GL_TEXTURE_BUFFER)) 2143 { 2144 break; 2145 } 2146 2147 /* Initialize mutable texture storage */ 2148 switch (texture_target) 2149 { 2150 case GL_TEXTURE_1D: 2151 { 2152 gl.texImage1D(texture_target, n_level, texture_internalformat, texture_width >> n_level, 0, /* border */ 2153 texture_format, texture_type, DE_NULL); /* pixels */ 2154 2155 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D() call failed for GL_TEXTURE_1D texture target"); 2156 2157 break; 2158 } 2159 2160 case GL_TEXTURE_1D_ARRAY: 2161 case GL_TEXTURE_2D: 2162 case GL_TEXTURE_RECTANGLE: 2163 { 2164 gl.texImage2D(texture_target, n_level, texture_internalformat, texture_width >> n_level, 2165 texture_height >> n_level, 0, /* border */ 2166 texture_format, texture_type, DE_NULL); /* pixels */ 2167 2168 GLU_EXPECT_NO_ERROR(gl.getError(), 2169 (texture_target == GL_TEXTURE_1D_ARRAY) ? 2170 "glTexImage2D() call failed for GL_TEXTURE_1D_ARRAY texture target" : 2171 (texture_target == GL_TEXTURE_2D) ? 2172 "glTexImage2D() call failed for GL_TEXTURE_2D texture target" : 2173 "glTexImage2D() call failed for GL_TEXTURE_RECTANGLE texture target"); 2174 2175 break; 2176 } 2177 2178 case GL_TEXTURE_2D_ARRAY: 2179 case GL_TEXTURE_3D: 2180 { 2181 gl.texImage3D(texture_target, n_level, texture_internalformat, texture_width >> n_level, 2182 texture_height >> n_level, texture_depth >> n_level, 0, /* border */ 2183 texture_format, texture_type, DE_NULL); /* pixels */ 2184 2185 GLU_EXPECT_NO_ERROR(gl.getError(), 2186 (texture_target == GL_TEXTURE_2D_ARRAY) ? 2187 "glTexImage3D() call failed for GL_TEXTURE_2D_ARRAY texture target" : 2188 "glTexImage3D() call failed for GL_TEXTURE_3D texture target"); 2189 2190 break; 2191 } 2192 2193 case GL_TEXTURE_2D_MULTISAMPLE: 2194 { 2195 gl.texImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_color_texture_samples_value, 2196 texture_internalformat, texture_width >> n_level, texture_height >> n_level, 2197 GL_TRUE); /* fixedsamplelocations */ 2198 2199 GLU_EXPECT_NO_ERROR( 2200 gl.getError(), 2201 "glTexImage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target"); 2202 2203 break; 2204 } 2205 2206 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 2207 { 2208 gl.texImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, gl_max_color_texture_samples_value, 2209 texture_internalformat, texture_width >> n_level, texture_height >> n_level, 2210 texture_depth >> n_level, GL_TRUE); /* fixedsamplelocations */ 2211 2212 GLU_EXPECT_NO_ERROR( 2213 gl.getError(), 2214 "glTexImage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY texture target"); 2215 2216 break; 2217 } 2218 2219 case GL_TEXTURE_CUBE_MAP: 2220 { 2221 for (unsigned int n_cubemap_texture_target = 0; n_cubemap_texture_target < n_cubemap_texture_targets; 2222 ++n_cubemap_texture_target) 2223 { 2224 glw::GLenum cubemap_texture_target = cubemap_texture_targets[n_cubemap_texture_target]; 2225 2226 gl.texImage2D(cubemap_texture_target, n_level, texture_internalformat, texture_width >> n_level, 2227 texture_height >> n_level, 0, /* border */ 2228 texture_format, texture_type, DE_NULL); /* pixels */ 2229 2230 GLU_EXPECT_NO_ERROR(gl.getError(), 2231 "glTexImage2D() call failed for one of the cube-map texture targets"); 2232 2233 break; 2234 } /* for (all cube-map texture targets) */ 2235 2236 break; 2237 } 2238 2239 case GL_TEXTURE_CUBE_MAP_ARRAY: 2240 { 2241 gl.texImage3D(texture_target, n_level, texture_internalformat, texture_width >> n_level, 2242 texture_height >> n_level, 6 /* layer-faces */ * n_cubemaps_needed, 0, /* border */ 2243 texture_format, texture_type, DE_NULL); /* pixels */ 2244 2245 GLU_EXPECT_NO_ERROR(gl.getError(), 2246 "glTexImage3D() call failed for GL_TEXTURE_CUBE_MAP_ARRAY texture target"); 2247 2248 break; 2249 } 2250 2251 default: 2252 { 2253 TCU_FAIL("Unrecognized texture target"); 2254 } 2255 } /* switch (texture_target) */ 2256 } /* for (all levels) */ 2257 } /* if (texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT) */ 2258 else 2259 { 2260 /* Initialize immutable texture storage */ 2261 switch (texture_target) 2262 { 2263 case GL_TEXTURE_1D: 2264 { 2265 gl.texStorage1D(texture_target, n_levels_needed, texture_internalformat, texture_width); 2266 2267 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed for GL_TEXTURE_1D texture target"); 2268 2269 break; 2270 } 2271 2272 case GL_TEXTURE_1D_ARRAY: 2273 case GL_TEXTURE_2D: 2274 case GL_TEXTURE_CUBE_MAP: 2275 case GL_TEXTURE_RECTANGLE: 2276 { 2277 const unsigned n_levels = (texture_target == GL_TEXTURE_RECTANGLE) ? 1 : n_levels_needed; 2278 2279 gl.texStorage2D(texture_target, n_levels, texture_internalformat, texture_width, texture_height); 2280 2281 GLU_EXPECT_NO_ERROR(gl.getError(), 2282 (texture_target == GL_TEXTURE_1D_ARRAY) ? 2283 "glTexStorage2D() call failed for GL_TEXTURE_1D_ARRAY texture target" : 2284 (texture_target == GL_TEXTURE_2D) ? 2285 "glTexStorage2D() call failed for GL_TEXTURE_2D texture target" : 2286 (texture_target == GL_TEXTURE_CUBE_MAP) ? 2287 "glTexStorage2D() call failed for GL_TEXTURE_CUBE_MAP texture target" : 2288 "glTexStorage2D() call failed for GL_TEXTURE_RECTANGLE texture target"); 2289 2290 break; 2291 } 2292 2293 case GL_TEXTURE_2D_ARRAY: 2294 case GL_TEXTURE_3D: 2295 { 2296 gl.texStorage3D(texture_target, n_levels_needed, texture_internalformat, texture_width, texture_height, 2297 texture_depth); 2298 2299 GLU_EXPECT_NO_ERROR(gl.getError(), 2300 (texture_target == GL_TEXTURE_2D_ARRAY) ? 2301 "glTexStorage3D() call failed for GL_TEXTURE_2D_ARRAY texture target" : 2302 "glTexStorage3D() call failed for GL_TEXTURE_3D texture target"); 2303 2304 break; 2305 } 2306 2307 case GL_TEXTURE_2D_MULTISAMPLE: 2308 { 2309 gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_color_texture_samples_value, 2310 texture_internalformat, texture_width, texture_height, 2311 GL_TRUE); /* fixedsamplelocations */ 2312 2313 GLU_EXPECT_NO_ERROR(gl.getError(), 2314 "glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target"); 2315 2316 break; 2317 } 2318 2319 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 2320 { 2321 gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, gl_max_color_texture_samples_value, 2322 texture_internalformat, texture_width, texture_height, texture_depth, 2323 GL_TRUE); /* fixedsamplelocations */ 2324 2325 GLU_EXPECT_NO_ERROR( 2326 gl.getError(), 2327 "glTexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY texture target"); 2328 2329 break; 2330 } 2331 2332 case GL_TEXTURE_CUBE_MAP_ARRAY: 2333 { 2334 const unsigned int actual_texture_depth = 6 /* layer-faces */ * n_cubemaps_needed; 2335 2336 gl.texStorage3D(texture_target, n_levels_needed, texture_internalformat, texture_width, texture_height, 2337 actual_texture_depth); 2338 2339 GLU_EXPECT_NO_ERROR(gl.getError(), 2340 "glTexStorage3D() call failed for GL_TEXTURE_CUBE_MAP_ARRAY texture target"); 2341 2342 break; 2343 } 2344 2345 default: 2346 { 2347 TCU_FAIL("Unrecognized texture target"); 2348 } 2349 } /* switch (texture_target) */ 2350 } 2351 } 2352 2353 /** Tells whether a parent texture object, storage of which uses @param original_internalformat 2354 * internalformat, can be used to generate a texture view using @param view_internalformat 2355 * internalformat. 2356 * 2357 * @param original_internalformat Internalformat used for parent texture object storage. 2358 * @param view_internalformat Internalformat to be used for view texture object storage. 2359 * 2360 * @return true if the internalformats are compatible, false otherwise. 2361 **/ 2362 bool TextureViewUtilities::isInternalformatCompatibleForTextureView(glw::GLenum original_internalformat, 2363 glw::GLenum view_internalformat) 2364 { 2365 const _view_class original_internalformat_view_class = getViewClassForInternalformat(original_internalformat); 2366 const _view_class view_internalformat_view_class = getViewClassForInternalformat(view_internalformat); 2367 2368 return (original_internalformat_view_class == view_internalformat_view_class); 2369 } 2370 2371 /** Tells whether user-specified internalformat is compressed. 2372 * 2373 * @param internalformat Internalformat to use for the query. 2374 * 2375 * @return true if @param internalformat is a known compressed internalformat, 2376 * false otherwise. 2377 **/ 2378 bool TextureViewUtilities::isInternalformatCompressed(const glw::GLenum internalformat) 2379 { 2380 bool result = false; 2381 2382 switch (internalformat) 2383 { 2384 case GL_COMPRESSED_RED_RGTC1: 2385 case GL_COMPRESSED_SIGNED_RED_RGTC1: 2386 case GL_COMPRESSED_RG_RGTC2: 2387 case GL_COMPRESSED_SIGNED_RG_RGTC2: 2388 case GL_COMPRESSED_RGBA_BPTC_UNORM: 2389 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 2390 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 2391 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 2392 case GL_COMPRESSED_RGB8_ETC2: 2393 case GL_COMPRESSED_SRGB8_ETC2: 2394 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 2395 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 2396 case GL_COMPRESSED_RGBA8_ETC2_EAC: 2397 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 2398 case GL_COMPRESSED_R11_EAC: 2399 case GL_COMPRESSED_SIGNED_R11_EAC: 2400 case GL_COMPRESSED_RG11_EAC: 2401 case GL_COMPRESSED_SIGNED_RG11_EAC: 2402 { 2403 result = true; 2404 2405 break; 2406 } 2407 } /* switch (internalformat) */ 2408 2409 return result; 2410 } 2411 2412 /** Tells whether user-specified internalformat operates in sRGB color space. 2413 * 2414 * @param internalformat Internalformat to use for the query. 2415 * 2416 * @return true if @param internalformat is a known sRGB internalformat, 2417 * false otherwise. 2418 **/ 2419 bool TextureViewUtilities::isInternalformatSRGB(const glw::GLenum internalformat) 2420 { 2421 return (internalformat == GL_SRGB8 || internalformat == GL_SRGB8_ALPHA8 || 2422 internalformat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM); 2423 } 2424 2425 /** Tells whether user-specified internalformat is supported by OpenGL of a given version. 2426 * 2427 * @param internalformat Internalformat to use for the query. 2428 * @param major_version Major version of the rendering context. 2429 * @param minor_version Minor version of the rendering context. 2430 * 2431 * @return true if the internalformat is supported, false otherwise. 2432 **/ 2433 bool TextureViewUtilities::isInternalformatSupported(glw::GLenum internalformat, const glw::GLint major_version, 2434 const glw::GLint minor_version) 2435 { 2436 (void)major_version; 2437 /* NOTE: This function, as it stands right now, does not consider OpenGL contexts 2438 * lesser than 4. 2439 **/ 2440 glw::GLint minimum_minor_version = 0; 2441 2442 DE_ASSERT(major_version >= 4); 2443 2444 switch (internalformat) 2445 { 2446 /* >= OpenGL 4.0 */ 2447 case GL_RGBA32F: 2448 case GL_RGBA32I: 2449 case GL_RGBA32UI: 2450 case GL_RGBA16: 2451 case GL_RGBA16F: 2452 case GL_RGBA16I: 2453 case GL_RGBA16UI: 2454 case GL_RGBA8: 2455 case GL_RGBA8I: 2456 case GL_RGBA8UI: 2457 case GL_SRGB8_ALPHA8: 2458 case GL_RGB10_A2: 2459 case GL_RGB10_A2UI: 2460 case GL_RGB5_A1: 2461 case GL_RGBA4: 2462 case GL_R11F_G11F_B10F: 2463 case GL_RG32F: 2464 case GL_RG32I: 2465 case GL_RG32UI: 2466 case GL_RG16: 2467 case GL_RG16F: 2468 case GL_RG16I: 2469 case GL_RG16UI: 2470 case GL_RG8: 2471 case GL_RG8I: 2472 case GL_RG8UI: 2473 case GL_R32F: 2474 case GL_R32I: 2475 case GL_R32UI: 2476 case GL_R16F: 2477 case GL_R16I: 2478 case GL_R16UI: 2479 case GL_R16: 2480 case GL_R8: 2481 case GL_R8I: 2482 case GL_R8UI: 2483 case GL_RGBA16_SNORM: 2484 case GL_RGBA8_SNORM: 2485 case GL_RGB32F: 2486 case GL_RGB32I: 2487 case GL_RGB32UI: 2488 case GL_RGB16_SNORM: 2489 case GL_RGB16F: 2490 case GL_RGB16I: 2491 case GL_RGB16UI: 2492 case GL_RGB16: 2493 case GL_RGB8_SNORM: 2494 case GL_RGB8: 2495 case GL_RGB8I: 2496 case GL_RGB8UI: 2497 case GL_SRGB8: 2498 case GL_RGB9_E5: 2499 case GL_RG16_SNORM: 2500 case GL_RG8_SNORM: 2501 case GL_R16_SNORM: 2502 case GL_R8_SNORM: 2503 case GL_DEPTH_COMPONENT32F: 2504 case GL_DEPTH_COMPONENT24: 2505 case GL_DEPTH_COMPONENT16: 2506 case GL_DEPTH32F_STENCIL8: 2507 case GL_DEPTH24_STENCIL8: 2508 case GL_COMPRESSED_RED_RGTC1: 2509 case GL_COMPRESSED_SIGNED_RED_RGTC1: 2510 case GL_COMPRESSED_RG_RGTC2: 2511 case GL_COMPRESSED_SIGNED_RG_RGTC2: 2512 { 2513 /* Already covered by default value of minimum_minor_version */ 2514 2515 break; 2516 } 2517 2518 /* >= OpenGL 4.2 */ 2519 case GL_RGB565: 2520 case GL_COMPRESSED_RGBA_BPTC_UNORM: 2521 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 2522 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 2523 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 2524 { 2525 minimum_minor_version = 2; 2526 2527 break; 2528 } 2529 2530 /* >= OpenGL 4.3 */ 2531 case GL_COMPRESSED_RGB8_ETC2: 2532 case GL_COMPRESSED_SRGB8_ETC2: 2533 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 2534 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 2535 case GL_COMPRESSED_RGBA8_ETC2_EAC: 2536 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 2537 case GL_COMPRESSED_R11_EAC: 2538 case GL_COMPRESSED_SIGNED_R11_EAC: 2539 case GL_COMPRESSED_RG11_EAC: 2540 case GL_COMPRESSED_SIGNED_RG11_EAC: 2541 { 2542 minimum_minor_version = 3; 2543 2544 break; 2545 } 2546 2547 default: 2548 TCU_FAIL("Unrecognized internalformat"); 2549 } 2550 2551 return (minor_version >= minimum_minor_version); 2552 } 2553 2554 /** Tells whether a parent texture object using @param original_texture_target texture target 2555 * can be used to generate a texture view of @param view_texture_target texture target. 2556 * 2557 * @param original_texture_target Texture target used by parent texture; 2558 * @param view_texture_target Texture target to be used for view texture; 2559 * 2560 * @return true if the texture targets are compatible, false otherwise. 2561 **/ 2562 bool TextureViewUtilities::isLegalTextureTargetForTextureView(glw::GLenum original_texture_target, 2563 glw::GLenum view_texture_target) 2564 { 2565 bool result = false; 2566 2567 switch (original_texture_target) 2568 { 2569 case GL_TEXTURE_1D: 2570 { 2571 result = (view_texture_target == GL_TEXTURE_1D || view_texture_target == GL_TEXTURE_1D_ARRAY); 2572 2573 break; 2574 } 2575 2576 case GL_TEXTURE_2D: 2577 { 2578 result = (view_texture_target == GL_TEXTURE_2D || view_texture_target == GL_TEXTURE_2D_ARRAY); 2579 2580 break; 2581 } 2582 2583 case GL_TEXTURE_3D: 2584 { 2585 result = (view_texture_target == GL_TEXTURE_3D); 2586 2587 break; 2588 } 2589 2590 case GL_TEXTURE_CUBE_MAP: 2591 { 2592 result = (view_texture_target == GL_TEXTURE_CUBE_MAP || view_texture_target == GL_TEXTURE_2D || 2593 view_texture_target == GL_TEXTURE_2D_ARRAY || view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 2594 2595 break; 2596 } 2597 2598 case GL_TEXTURE_RECTANGLE: 2599 { 2600 result = (view_texture_target == GL_TEXTURE_RECTANGLE); 2601 2602 break; 2603 } 2604 2605 case GL_TEXTURE_BUFFER: 2606 { 2607 /* No targets supported */ 2608 2609 break; 2610 } 2611 2612 case GL_TEXTURE_1D_ARRAY: 2613 { 2614 result = (view_texture_target == GL_TEXTURE_1D_ARRAY || view_texture_target == GL_TEXTURE_1D); 2615 2616 break; 2617 } 2618 2619 case GL_TEXTURE_2D_ARRAY: 2620 { 2621 result = (view_texture_target == GL_TEXTURE_2D_ARRAY || view_texture_target == GL_TEXTURE_2D || 2622 view_texture_target == GL_TEXTURE_CUBE_MAP || view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 2623 2624 break; 2625 } 2626 2627 case GL_TEXTURE_CUBE_MAP_ARRAY: 2628 { 2629 result = (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY || view_texture_target == GL_TEXTURE_2D_ARRAY || 2630 view_texture_target == GL_TEXTURE_2D || view_texture_target == GL_TEXTURE_CUBE_MAP); 2631 2632 break; 2633 } 2634 2635 case GL_TEXTURE_2D_MULTISAMPLE: 2636 { 2637 result = (view_texture_target == GL_TEXTURE_2D_MULTISAMPLE || 2638 view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 2639 2640 break; 2641 } 2642 2643 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 2644 { 2645 result = (view_texture_target == GL_TEXTURE_2D_MULTISAMPLE || 2646 view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 2647 2648 break; 2649 } 2650 } /* switch (original_texture_target) */ 2651 2652 return result; 2653 } 2654 2655 /** Constructor. 2656 * 2657 * @param context Rendering context. 2658 **/ 2659 TextureViewTestGetTexParameter::TextureViewTestGetTexParameter(deqp::Context& context) 2660 : TestCase(context, "gettexparameter", "Verifies glGetTexParameterfv() and glGetTexParameteriv() " 2661 "work as specified") 2662 { 2663 /* Left blank on purpose */ 2664 } 2665 2666 /** De-initializes all GL objects created for the test. */ 2667 void TextureViewTestGetTexParameter::deinit() 2668 { 2669 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2670 2671 /* Deinitialize all test runs */ 2672 for (_test_runs_iterator it = m_test_runs.begin(); it != m_test_runs.end(); ++it) 2673 { 2674 _test_run& test_run = *it; 2675 2676 if (test_run.parent_texture_object_id != 0) 2677 { 2678 gl.deleteTextures(1, &test_run.parent_texture_object_id); 2679 2680 test_run.parent_texture_object_id = 0; 2681 } 2682 2683 if (test_run.texture_view_object_created_from_immutable_to_id != 0) 2684 { 2685 gl.deleteTextures(1, &test_run.texture_view_object_created_from_immutable_to_id); 2686 2687 test_run.texture_view_object_created_from_immutable_to_id = 0; 2688 } 2689 2690 if (test_run.texture_view_object_created_from_view_to_id != 0) 2691 { 2692 gl.deleteTextures(1, &test_run.texture_view_object_created_from_view_to_id); 2693 2694 test_run.texture_view_object_created_from_view_to_id = 0; 2695 } 2696 } 2697 m_test_runs.clear(); 2698 } 2699 2700 /** Initializes test run descriptors used by the test. This also includes 2701 * all GL objects used by all the iterations. 2702 **/ 2703 void TextureViewTestGetTexParameter::initTestRuns() 2704 { 2705 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2706 const int n_cubemaps_needed = 4; /* only used for GL_TEXTURE_CUBE_MAP_ARRAY */ 2707 const int texture_depth = 16; 2708 const int texture_height = 32; 2709 const int texture_width = 64; 2710 2711 const glw::GLenum texture_targets[] = { 2712 GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D, 2713 GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 2714 GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY, 2715 GL_TEXTURE_RECTANGLE 2716 }; 2717 const _test_texture_type texture_types[] = { TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED, 2718 TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT, 2719 TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT, 2720 TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT, 2721 TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW }; 2722 const unsigned int n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]); 2723 const unsigned int n_texture_types = sizeof(texture_types) / sizeof(texture_types[0]); 2724 2725 /* Iterate through all texture types supported by the test */ 2726 for (unsigned int n_texture_type = 0; n_texture_type < n_texture_types; ++n_texture_type) 2727 { 2728 const _test_texture_type texture_type = texture_types[n_texture_type]; 2729 2730 /* Iterate through all texture targets supported by the test */ 2731 for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target) 2732 { 2733 _test_run new_test_run; 2734 const glw::GLenum texture_target = texture_targets[n_texture_target]; 2735 2736 /* Texture buffers are neither immutable nor mutable. In order to avoid testing 2737 * them in both cases, let's assume they are immutable objects */ 2738 if (texture_target == GL_TEXTURE_BUFFER && texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT) 2739 { 2740 continue; 2741 } 2742 2743 /* Set up test run properties. Since we're only testing a single 2744 * configuration, we can set these to predefined values.. 2745 */ 2746 const int n_levels_needed = 6; 2747 glw::GLint n_min_layer = 1; 2748 glw::GLint n_num_layers = 2; 2749 glw::GLint n_min_level = 2; 2750 glw::GLint n_num_levels = 3; 2751 int parent_texture_depth = texture_depth; 2752 int parent_texture_height = texture_height; 2753 int parent_texture_width = texture_width; 2754 2755 new_test_run.texture_target = texture_target; 2756 new_test_run.texture_type = texture_type; 2757 2758 /* Take note of target-specific restrictions */ 2759 if (texture_target == GL_TEXTURE_CUBE_MAP || texture_target == GL_TEXTURE_CUBE_MAP_ARRAY) 2760 { 2761 n_num_layers = 6 /* layer-faces */ * 2; /* as per spec */ 2762 2763 /* Make sure that cube face width matches its height */ 2764 parent_texture_height = 64; 2765 parent_texture_width = 64; 2766 2767 /* Also change the depth so that there's at least a few layers 2768 * we can use in the test for GL_TEXTURE_CUBE_MAP_ARRAY case 2769 */ 2770 parent_texture_depth = 64; 2771 } 2772 2773 if (texture_target == GL_TEXTURE_CUBE_MAP) 2774 { 2775 /* Texture views created from a cube map texture should always 2776 * use a minimum layer of zero 2777 */ 2778 n_min_layer = 0; 2779 n_num_layers = 6; 2780 } 2781 2782 if (texture_target == GL_TEXTURE_CUBE_MAP_ARRAY) 2783 { 2784 /* Slightly modify the values we'll use for <minlayer> 2785 * and <numlayers> arguments passed to glTextureView() calls 2786 * so that we can test the "view from view from texture" case 2787 */ 2788 n_min_layer = 0; 2789 } 2790 2791 if (texture_target == GL_TEXTURE_1D || texture_target == GL_TEXTURE_2D || 2792 texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_3D || 2793 texture_target == GL_TEXTURE_RECTANGLE) 2794 { 2795 /* All these texture targets are single-layer only. glTextureView() 2796 * also requires <numlayers> argument to be set to 1 for them, so 2797 * take this into account. 2798 **/ 2799 n_min_layer = 0; 2800 n_num_layers = 1; 2801 } 2802 2803 if (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || 2804 texture_target == GL_TEXTURE_RECTANGLE) 2805 { 2806 /* All these texture targets do not support mip-maps */ 2807 n_min_level = 0; 2808 } 2809 2810 /* Initialize parent texture object */ 2811 gl.genTextures(1, &new_test_run.parent_texture_object_id); 2812 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed"); 2813 2814 gl.bindTexture(texture_target, new_test_run.parent_texture_object_id); 2815 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 2816 2817 if (texture_type != TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED) 2818 { 2819 TextureViewUtilities::initTextureStorage(gl, (texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT), 2820 texture_target, parent_texture_depth, parent_texture_height, 2821 parent_texture_width, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 2822 n_levels_needed, n_cubemaps_needed, 0); /* bo_id */ 2823 } 2824 2825 /* Update expected view-specific property values to include interactions 2826 * with immutable textures. */ 2827 if (texture_type == TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT || 2828 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT || 2829 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) 2830 { 2831 /* Set expected GL_TEXTURE_IMMUTABLE_LEVELS property value to the number 2832 * of levels we'll be using for the immutable texture storage. For selected 2833 * texture targets that do no take <levels> argument, we'll change this 2834 * value on a case-by-case basis. 2835 */ 2836 new_test_run.expected_n_immutable_levels = n_levels_needed; 2837 2838 /* Set expected GL_TEXTURE_VIEW_NUM_LAYERS property value to 1, as per GL spec. 2839 * This value will be modified for selected texture targets */ 2840 new_test_run.expected_n_num_layers = 1; 2841 2842 /* Configured expected GL_TEXTURE_VIEW_NUM_LEVELS value as per GL spec */ 2843 new_test_run.expected_n_num_levels = n_levels_needed; 2844 2845 /* Initialize immutable texture storage */ 2846 switch (texture_target) 2847 { 2848 case GL_TEXTURE_1D_ARRAY: 2849 { 2850 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */ 2851 new_test_run.expected_n_num_layers = texture_height; 2852 2853 break; 2854 } 2855 2856 case GL_TEXTURE_CUBE_MAP: 2857 { 2858 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */ 2859 new_test_run.expected_n_num_layers = 6; 2860 2861 break; 2862 } 2863 2864 case GL_TEXTURE_RECTANGLE: 2865 { 2866 new_test_run.expected_n_immutable_levels = 1; 2867 new_test_run.expected_n_num_levels = 1; 2868 2869 break; 2870 } 2871 2872 case GL_TEXTURE_2D_ARRAY: 2873 { 2874 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */ 2875 new_test_run.expected_n_num_layers = texture_depth; 2876 2877 break; 2878 } 2879 2880 case GL_TEXTURE_2D_MULTISAMPLE: 2881 { 2882 /* 2D multisample texture are not mip-mapped, so update 2883 * expected GL_TEXTURE_IMMUTABLE_LEVELS and GL_TEXTURE_VIEW_NUM_LEVELS 2884 * value accordingly */ 2885 new_test_run.expected_n_immutable_levels = 1; 2886 new_test_run.expected_n_num_levels = 1; 2887 2888 break; 2889 } 2890 2891 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 2892 { 2893 /* 2D multisample array textures are not mip-mapped, so update 2894 * expected GL_TEXTURE_IMMUTABLE_LEVELS and GL_TEXTURE_VIEW_NUM_LEVELS 2895 * values accordingly */ 2896 new_test_run.expected_n_immutable_levels = 1; 2897 new_test_run.expected_n_num_levels = 1; 2898 2899 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */ 2900 new_test_run.expected_n_num_layers = texture_depth; 2901 2902 break; 2903 } 2904 2905 case GL_TEXTURE_CUBE_MAP_ARRAY: 2906 { 2907 const unsigned int actual_texture_depth = 6 /* layer-faces */ * n_cubemaps_needed; 2908 2909 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */ 2910 new_test_run.expected_n_num_layers = actual_texture_depth; 2911 2912 break; 2913 } 2914 } /* switch (texture_target) */ 2915 } 2916 2917 /* Initialize the view(s) */ 2918 if (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT || 2919 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) 2920 { 2921 const unsigned int n_iterations = 2922 (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) ? 2 : 1; 2923 2924 for (unsigned int n_iteration = 0; n_iteration < n_iterations; ++n_iteration) 2925 { 2926 glw::GLuint* parent_id_ptr = (n_iteration == 0) ? 2927 &new_test_run.parent_texture_object_id : 2928 &new_test_run.texture_view_object_created_from_immutable_to_id; 2929 glw::GLuint* view_id_ptr = (n_iteration == 0) ? 2930 &new_test_run.texture_view_object_created_from_immutable_to_id : 2931 &new_test_run.texture_view_object_created_from_view_to_id; 2932 2933 gl.genTextures(1, view_id_ptr); 2934 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed"); 2935 2936 gl.textureView(*view_id_ptr, new_test_run.texture_target, *parent_id_ptr, 2937 GL_RGBA8, /* use the parent texture object's internalformat */ 2938 n_min_level, n_num_levels, n_min_layer, n_num_layers); 2939 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed"); 2940 2941 /* Query parent object's properties */ 2942 glw::GLint parent_min_level = -1; 2943 glw::GLint parent_min_layer = -1; 2944 glw::GLint parent_num_layers = -1; 2945 glw::GLint parent_num_levels = -1; 2946 glw::GLint parent_n_immutable_levels = -1; 2947 2948 gl.bindTexture(texture_target, *parent_id_ptr); 2949 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 2950 2951 gl.getTexParameteriv(texture_target, GL_TEXTURE_IMMUTABLE_LEVELS, &parent_n_immutable_levels); 2952 GLU_EXPECT_NO_ERROR( 2953 gl.getError(), 2954 "glGetTexParameteriv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname queried for parent object"); 2955 2956 gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_MIN_LAYER, &parent_min_layer); 2957 GLU_EXPECT_NO_ERROR( 2958 gl.getError(), 2959 "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname queried for parent object"); 2960 2961 gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_MIN_LEVEL, &parent_min_level); 2962 GLU_EXPECT_NO_ERROR( 2963 gl.getError(), 2964 "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname queried for parent object"); 2965 2966 gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_NUM_LAYERS, &parent_num_layers); 2967 GLU_EXPECT_NO_ERROR( 2968 gl.getError(), 2969 "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname queried for parent object"); 2970 2971 gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_NUM_LEVELS, &parent_num_levels); 2972 GLU_EXPECT_NO_ERROR( 2973 gl.getError(), 2974 "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname queried for parent object"); 2975 2976 /* Update test run-specific expected values as per GL_ARB_texture_view extension specification */ 2977 /* 2978 * - TEXTURE_IMMUTABLE_LEVELS is set to the value of TEXTURE_IMMUTABLE_LEVELS 2979 * from the original texture. 2980 */ 2981 new_test_run.expected_n_immutable_levels = parent_n_immutable_levels; 2982 2983 /* 2984 * - TEXTURE_VIEW_MIN_LEVEL is set to <minlevel> plus the value of 2985 * TEXTURE_VIEW_MIN_LEVEL from the original texture. 2986 */ 2987 new_test_run.expected_n_min_level = n_min_level + parent_min_level; 2988 2989 /* 2990 * - TEXTURE_VIEW_MIN_LAYER is set to <minlayer> plus the value of 2991 * TEXTURE_VIEW_MIN_LAYER from the original texture. 2992 */ 2993 new_test_run.expected_n_min_layer = n_min_layer + parent_min_layer; 2994 2995 /* 2996 * - TEXTURE_VIEW_NUM_LAYERS is set to the lesser of <numlayers> and the 2997 * value of TEXTURE_VIEW_NUM_LAYERS from the original texture minus 2998 * <minlayer>. 2999 * 3000 */ 3001 if ((parent_num_layers - n_min_layer) < n_num_layers) 3002 { 3003 new_test_run.expected_n_num_layers = parent_num_layers - n_min_layer; 3004 } 3005 else 3006 { 3007 new_test_run.expected_n_num_layers = n_num_layers; 3008 } 3009 3010 /* 3011 * - TEXTURE_VIEW_NUM_LEVELS is set to the lesser of <numlevels> and the 3012 * value of TEXTURE_VIEW_NUM_LEVELS from the original texture minus 3013 * <minlevels>. 3014 * 3015 */ 3016 if ((parent_num_levels - n_min_level) < n_num_levels) 3017 { 3018 new_test_run.expected_n_num_levels = parent_num_levels - n_min_level; 3019 } 3020 else 3021 { 3022 new_test_run.expected_n_num_levels = n_num_levels; 3023 } 3024 } /* for (all iterations) */ 3025 } /* if (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT || 3026 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) */ 3027 3028 /* Store the descriptor */ 3029 m_test_runs.push_back(new_test_run); 3030 } /* for (all texture targets) */ 3031 } /* for (all texture types) */ 3032 } 3033 3034 /** Executes test iteration. 3035 * 3036 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 3037 */ 3038 tcu::TestNode::IterateResult TextureViewTestGetTexParameter::iterate() 3039 { 3040 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3041 3042 /* Make sure GL_ARB_texture_view is reported as supported before carrying on 3043 * with actual execution */ 3044 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions(); 3045 3046 if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end()) 3047 { 3048 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported"); 3049 } 3050 3051 /* Initialize all objects necessary to execute the test */ 3052 initTestRuns(); 3053 3054 /* Iterate through all test runs and issue the queries */ 3055 for (_test_runs_const_iterator test_run_iterator = m_test_runs.begin(); test_run_iterator != m_test_runs.end(); 3056 test_run_iterator++) 3057 { 3058 glw::GLfloat query_texture_immutable_levels_value_float = -1.0f; 3059 glw::GLint query_texture_immutable_levels_value_int = -1; 3060 glw::GLfloat query_texture_view_min_layer_value_float = -1.0f; 3061 glw::GLint query_texture_view_min_layer_value_int = -1; 3062 glw::GLfloat query_texture_view_min_level_value_float = -1.0f; 3063 glw::GLint query_texture_view_min_level_value_int = -1; 3064 glw::GLfloat query_texture_view_num_layers_value_float = -1.0f; 3065 glw::GLint query_texture_view_num_layers_value_int = -1; 3066 glw::GLfloat query_texture_view_num_levels_value_float = -1.0f; 3067 glw::GLint query_texture_view_num_levels_value_int = -1; 3068 const _test_run& test_run = *test_run_iterator; 3069 glw::GLint texture_object_id = 0; 3070 3071 switch (test_run.texture_type) 3072 { 3073 case TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT: 3074 texture_object_id = test_run.parent_texture_object_id; 3075 break; 3076 case TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT: 3077 texture_object_id = test_run.parent_texture_object_id; 3078 break; 3079 case TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED: 3080 texture_object_id = test_run.parent_texture_object_id; 3081 break; 3082 case TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT: 3083 texture_object_id = test_run.texture_view_object_created_from_immutable_to_id; 3084 break; 3085 case TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW: 3086 texture_object_id = test_run.texture_view_object_created_from_view_to_id; 3087 break; 3088 3089 default: 3090 { 3091 TCU_FAIL("Unrecognized texture type"); 3092 } 3093 } 3094 3095 /* Bind the texture object of our interest to the target */ 3096 gl.bindTexture(test_run.texture_target, texture_object_id); 3097 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3098 3099 /* Run all the queries */ 3100 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_IMMUTABLE_LEVELS, 3101 &query_texture_immutable_levels_value_float); 3102 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname"); 3103 3104 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_IMMUTABLE_LEVELS, 3105 &query_texture_immutable_levels_value_int); 3106 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexPrameteriv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname"); 3107 3108 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LAYER, 3109 &query_texture_view_min_layer_value_float); 3110 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname"); 3111 3112 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LAYER, 3113 &query_texture_view_min_layer_value_int); 3114 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname"); 3115 3116 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LEVEL, 3117 &query_texture_view_min_level_value_float); 3118 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname"); 3119 3120 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LEVEL, 3121 &query_texture_view_min_level_value_int); 3122 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname"); 3123 3124 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LAYERS, 3125 &query_texture_view_num_layers_value_float); 3126 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname"); 3127 3128 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LAYERS, 3129 &query_texture_view_num_layers_value_int); 3130 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname"); 3131 3132 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LEVELS, 3133 &query_texture_view_num_levels_value_float); 3134 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname"); 3135 3136 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LEVELS, 3137 &query_texture_view_num_levels_value_int); 3138 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname"); 3139 3140 /* Verify the results */ 3141 const float epsilon = 1e-5f; 3142 3143 if (de::abs(query_texture_immutable_levels_value_float - (float)test_run.expected_n_immutable_levels) > epsilon) 3144 { 3145 m_testCtx.getLog() << tcu::TestLog::Message 3146 << "Invalid floating-point value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname " 3147 << "(expected: " << test_run.expected_n_immutable_levels 3148 << " found: " << query_texture_immutable_levels_value_float << ")." 3149 << tcu::TestLog::EndMessage; 3150 3151 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname"); 3152 } 3153 3154 if (query_texture_immutable_levels_value_int != test_run.expected_n_immutable_levels) 3155 { 3156 m_testCtx.getLog() << tcu::TestLog::Message 3157 << "Invalid integer value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname " 3158 << "(expected: " << test_run.expected_n_immutable_levels 3159 << " found: " << query_texture_immutable_levels_value_int << ")." 3160 << tcu::TestLog::EndMessage; 3161 3162 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname"); 3163 } 3164 3165 if (de::abs(query_texture_view_min_layer_value_float - (float)test_run.expected_n_min_layer) > epsilon) 3166 { 3167 m_testCtx.getLog() << tcu::TestLog::Message 3168 << "Invalid floating-point value reported for GL_TEXTURE_VIEW_MIN_LAYER pname " 3169 << "(expected: " << test_run.expected_n_min_layer 3170 << " found: " << query_texture_view_min_layer_value_float << ")." 3171 << tcu::TestLog::EndMessage; 3172 3173 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LAYER pname"); 3174 } 3175 3176 if (query_texture_view_min_layer_value_int != test_run.expected_n_min_layer) 3177 { 3178 m_testCtx.getLog() << tcu::TestLog::Message 3179 << "Invalid integer value reported for GL_TEXTURE_VIEW_MIN_LAYER pname " 3180 << "(expected: " << test_run.expected_n_min_layer 3181 << " found: " << query_texture_view_min_layer_value_int << ")." 3182 << tcu::TestLog::EndMessage; 3183 3184 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LAYER pname"); 3185 } 3186 3187 if (de::abs(query_texture_view_min_level_value_float - (float)test_run.expected_n_min_level) > epsilon) 3188 { 3189 m_testCtx.getLog() << tcu::TestLog::Message 3190 << "Invalid floating-point value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname " 3191 << "(expected: " << test_run.expected_n_min_level 3192 << " found: " << query_texture_view_min_level_value_float << ")." 3193 << tcu::TestLog::EndMessage; 3194 3195 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname"); 3196 } 3197 3198 if (query_texture_view_min_level_value_int != test_run.expected_n_min_level) 3199 { 3200 m_testCtx.getLog() << tcu::TestLog::Message 3201 << "Invalid integer value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname " 3202 << "(expected: " << test_run.expected_n_min_level 3203 << " found: " << query_texture_view_min_level_value_int << ")." 3204 << tcu::TestLog::EndMessage; 3205 3206 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname"); 3207 } 3208 3209 if (de::abs(query_texture_view_num_layers_value_float - (float)test_run.expected_n_num_layers) > epsilon) 3210 { 3211 m_testCtx.getLog() << tcu::TestLog::Message 3212 << "Invalid floating-point value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname " 3213 << "(expected: " << test_run.expected_n_num_layers 3214 << " found: " << query_texture_view_num_layers_value_float << ")." 3215 << tcu::TestLog::EndMessage; 3216 3217 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname"); 3218 } 3219 3220 if (query_texture_view_num_layers_value_int != test_run.expected_n_num_layers) 3221 { 3222 m_testCtx.getLog() << tcu::TestLog::Message 3223 << "Invalid integer value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname " 3224 << "(expected: " << test_run.expected_n_num_layers 3225 << " found: " << query_texture_view_num_layers_value_int << ")." 3226 << tcu::TestLog::EndMessage; 3227 3228 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname"); 3229 } 3230 3231 if (de::abs(query_texture_view_num_levels_value_float - (float)test_run.expected_n_num_levels) > epsilon) 3232 { 3233 m_testCtx.getLog() << tcu::TestLog::Message 3234 << "Invalid floating-point value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname " 3235 << "(expected: " << test_run.expected_n_num_levels 3236 << " found: " << query_texture_view_num_levels_value_float << ")." 3237 << tcu::TestLog::EndMessage; 3238 3239 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname"); 3240 } 3241 3242 if (query_texture_view_num_levels_value_int != test_run.expected_n_num_levels) 3243 { 3244 m_testCtx.getLog() << tcu::TestLog::Message 3245 << "Invalid integer value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname " 3246 << "(expected: " << test_run.expected_n_num_levels 3247 << " found: " << query_texture_view_num_levels_value_int << ")." 3248 << tcu::TestLog::EndMessage; 3249 3250 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname"); 3251 } 3252 } /* for (all test runs) */ 3253 3254 /* Test case passed */ 3255 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3256 3257 return STOP; 3258 } 3259 3260 /** Constructor. 3261 * 3262 * @param context Rendering context 3263 **/ 3264 TextureViewTestErrors::TextureViewTestErrors(deqp::Context& context) 3265 : TestCase(context, "errors", "test_description") 3266 , m_bo_id(0) 3267 , m_reference_immutable_to_1d_id(0) 3268 , m_reference_immutable_to_2d_id(0) 3269 , m_reference_immutable_to_2d_array_id(0) 3270 , m_reference_immutable_to_2d_array_32_by_33_id(0) 3271 , m_reference_immutable_to_2d_multisample_id(0) 3272 , m_reference_immutable_to_3d_id(0) 3273 , m_reference_immutable_to_cube_map_id(0) 3274 , m_reference_immutable_to_cube_map_array_id(0) 3275 , m_reference_immutable_to_rectangle_id(0) 3276 , m_reference_mutable_to_2d_id(0) 3277 , m_test_modified_to_id_1(0) 3278 , m_test_modified_to_id_2(0) 3279 , m_test_modified_to_id_3(0) 3280 , m_view_bound_to_id(0) 3281 , m_view_never_bound_to_id(0) 3282 { 3283 /* Left blank on purpose */ 3284 } 3285 3286 /** Deinitializes all GL objects that may have been generated for the test. */ 3287 void TextureViewTestErrors::deinit() 3288 { 3289 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3290 3291 if (m_bo_id != 0) 3292 { 3293 gl.deleteBuffers(1, &m_bo_id); 3294 3295 m_bo_id = 0; 3296 } 3297 3298 if (m_reference_immutable_to_1d_id != 0) 3299 { 3300 gl.deleteTextures(1, &m_reference_immutable_to_1d_id); 3301 3302 m_reference_immutable_to_1d_id = 0; 3303 } 3304 3305 if (m_reference_immutable_to_2d_id != 0) 3306 { 3307 gl.deleteTextures(1, &m_reference_immutable_to_2d_id); 3308 3309 m_reference_immutable_to_2d_id = 0; 3310 } 3311 3312 if (m_reference_immutable_to_2d_array_id != 0) 3313 { 3314 gl.deleteTextures(1, &m_reference_immutable_to_2d_array_id); 3315 3316 m_reference_immutable_to_2d_array_id = 0; 3317 } 3318 3319 if (m_reference_immutable_to_2d_array_32_by_33_id != 0) 3320 { 3321 gl.deleteTextures(1, &m_reference_immutable_to_2d_array_32_by_33_id); 3322 3323 m_reference_immutable_to_2d_array_32_by_33_id = 0; 3324 } 3325 3326 if (m_reference_immutable_to_2d_multisample_id != 0) 3327 { 3328 gl.deleteTextures(1, &m_reference_immutable_to_2d_multisample_id); 3329 3330 m_reference_immutable_to_2d_multisample_id = 0; 3331 } 3332 3333 if (m_reference_immutable_to_3d_id != 0) 3334 { 3335 gl.deleteTextures(1, &m_reference_immutable_to_3d_id); 3336 3337 m_reference_immutable_to_3d_id = 0; 3338 } 3339 3340 if (m_reference_immutable_to_cube_map_id != 0) 3341 { 3342 gl.deleteTextures(1, &m_reference_immutable_to_cube_map_id); 3343 3344 m_reference_immutable_to_cube_map_id = 0; 3345 } 3346 3347 if (m_reference_immutable_to_cube_map_array_id != 0) 3348 { 3349 gl.deleteTextures(1, &m_reference_immutable_to_cube_map_array_id); 3350 3351 m_reference_immutable_to_cube_map_array_id = 0; 3352 } 3353 3354 if (m_reference_immutable_to_rectangle_id != 0) 3355 { 3356 gl.deleteTextures(1, &m_reference_immutable_to_rectangle_id); 3357 3358 m_reference_immutable_to_rectangle_id = 0; 3359 } 3360 3361 if (m_reference_mutable_to_2d_id != 0) 3362 { 3363 gl.deleteTextures(1, &m_reference_mutable_to_2d_id); 3364 3365 m_reference_mutable_to_2d_id = 0; 3366 } 3367 3368 if (m_test_modified_to_id_1 != 0) 3369 { 3370 gl.deleteTextures(1, &m_test_modified_to_id_1); 3371 3372 m_test_modified_to_id_1 = 0; 3373 } 3374 3375 if (m_test_modified_to_id_2 != 0) 3376 { 3377 gl.deleteTextures(1, &m_test_modified_to_id_2); 3378 3379 m_test_modified_to_id_2 = 0; 3380 } 3381 3382 if (m_test_modified_to_id_3 != 0) 3383 { 3384 gl.deleteTextures(1, &m_test_modified_to_id_3); 3385 3386 m_test_modified_to_id_3 = 0; 3387 } 3388 3389 if (m_view_bound_to_id != 0) 3390 { 3391 gl.deleteTextures(1, &m_view_bound_to_id); 3392 3393 m_view_bound_to_id = 0; 3394 } 3395 3396 if (m_view_never_bound_to_id != 0) 3397 { 3398 gl.deleteTextures(1, &m_view_never_bound_to_id); 3399 3400 m_view_never_bound_to_id = 0; 3401 } 3402 } 3403 3404 /** Executes test iteration. 3405 * 3406 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 3407 */ 3408 tcu::TestNode::IterateResult TextureViewTestErrors::iterate() 3409 { 3410 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3411 3412 /* Make sure GL_ARB_texture_view is reported as supported before carrying on 3413 * with actual execution */ 3414 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions(); 3415 3416 if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end()) 3417 { 3418 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported"); 3419 } 3420 3421 /* Create a buffer object that we'll need to use to define storage of 3422 * buffer textures */ 3423 gl.genBuffers(1, &m_bo_id); 3424 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed"); 3425 3426 gl.bindBuffer(GL_TEXTURE_BUFFER, m_bo_id); 3427 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed"); 3428 3429 gl.bufferData(GL_TEXTURE_BUFFER, 123, /* arbitrary size */ 3430 DE_NULL, /* data */ 3431 GL_STATIC_DRAW); 3432 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed"); 3433 3434 /* Create reference texture objects */ 3435 const glw::GLint reference_bo_id = m_bo_id; 3436 const glw::GLint reference_to_depth = 2; 3437 const glw::GLenum reference_to_format = GL_RGBA; 3438 const glw::GLint reference_to_height = 64; 3439 const glw::GLenum reference_to_internalformat = GL_RGBA32F; 3440 const glw::GLint reference_n_cubemaps = 1; 3441 const glw::GLint reference_n_levels = 1; 3442 const glw::GLenum reference_to_type = GL_FLOAT; 3443 const glw::GLint reference_to_width = 64; 3444 3445 gl.genTextures(1, &m_reference_immutable_to_1d_id); 3446 gl.genTextures(1, &m_reference_immutable_to_2d_id); 3447 gl.genTextures(1, &m_reference_immutable_to_2d_array_id); 3448 gl.genTextures(1, &m_reference_immutable_to_2d_array_32_by_33_id); 3449 gl.genTextures(1, &m_reference_immutable_to_2d_multisample_id); 3450 gl.genTextures(1, &m_reference_immutable_to_3d_id); 3451 gl.genTextures(1, &m_reference_immutable_to_cube_map_id); 3452 gl.genTextures(1, &m_reference_immutable_to_cube_map_array_id); 3453 gl.genTextures(1, &m_reference_immutable_to_rectangle_id); 3454 gl.genTextures(1, &m_reference_mutable_to_2d_id); 3455 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed"); 3456 3457 /* Retrieve GL_SAMPLES value - we'll need it to initialize multisample storage */ 3458 glw::GLint gl_max_samples_value = 0; 3459 3460 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, reference_to_internalformat, GL_SAMPLES, 3461 1 /* bufSize - first result */, &gl_max_samples_value); 3462 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_SAMPLES pname"); 3463 3464 /* Set up texture storage for single-dimensional texture object */ 3465 gl.bindTexture(GL_TEXTURE_1D, m_reference_immutable_to_1d_id); 3466 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3467 3468 gl.texStorage1D(GL_TEXTURE_1D, reference_n_levels, reference_to_internalformat, reference_to_width); 3469 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed"); 3470 3471 /* Set up immutable texture storage for two-dimensional texture object */ 3472 gl.bindTexture(GL_TEXTURE_2D, m_reference_immutable_to_2d_id); 3473 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3474 3475 gl.texStorage2D(GL_TEXTURE_2D, reference_n_levels, reference_to_internalformat, reference_to_width, 3476 reference_to_height); 3477 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed"); 3478 3479 /* Set up immutable texture storage for two-dimensional array texture object */ 3480 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_id); 3481 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3482 3483 gl.texStorage3D(GL_TEXTURE_2D_ARRAY, reference_n_levels, reference_to_internalformat, reference_to_width, 3484 reference_to_height, reference_to_depth); 3485 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed"); 3486 3487 /* Set up immutable texture storage for two-dimensional array texture object, base 3488 * level of which uses a resolution of 32x33. We'll need it to check case r) */ 3489 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_32_by_33_id); 3490 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3491 3492 gl.texStorage3D(GL_TEXTURE_2D_ARRAY, reference_n_levels, reference_to_internalformat, 32, /* width */ 3493 33, /* height */ 3494 6); /* depth - 6 layers so that a cube-map/cube-map array view can be created from this texture */ 3495 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed"); 3496 3497 /* Set up immutable texture storage for two-dimensional multisample texture object */ 3498 gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_reference_immutable_to_2d_multisample_id); 3499 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3500 3501 gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_samples_value, reference_to_internalformat, 3502 reference_to_width, reference_to_height, GL_TRUE); /* fixedsamplelocations */ 3503 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed"); 3504 3505 /* Set up immutable texture storage for three-dimensional texture object */ 3506 gl.bindTexture(GL_TEXTURE_3D, m_reference_immutable_to_3d_id); 3507 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3508 3509 gl.texStorage3D(GL_TEXTURE_3D, reference_n_levels, reference_to_internalformat, reference_to_width, 3510 reference_to_height, reference_to_depth); 3511 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed"); 3512 3513 /* Set up immutable texture storage for cube-map texture object */ 3514 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_cube_map_id); 3515 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3516 3517 gl.texStorage2D(GL_TEXTURE_CUBE_MAP, reference_n_levels, reference_to_internalformat, reference_to_width, 3518 reference_to_height); 3519 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed"); 3520 3521 /* Set up immutable texture storage for cube-map array texture object */ 3522 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_cube_map_array_id); 3523 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3524 3525 gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, reference_n_levels, reference_to_internalformat, reference_to_width, 3526 reference_to_height, 6 /* layer-faces */ * reference_to_depth); 3527 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed"); 3528 3529 /* Set up immutable texture storage for rectangular texture object */ 3530 gl.bindTexture(GL_TEXTURE_RECTANGLE, m_reference_immutable_to_rectangle_id); 3531 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3532 3533 gl.texStorage2D(GL_TEXTURE_RECTANGLE, reference_n_levels, reference_to_internalformat, reference_to_width, 3534 reference_to_height); 3535 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed"); 3536 3537 /* Set up mutable texture storage for two-dimensional texture object */ 3538 gl.bindTexture(GL_TEXTURE_2D, m_reference_mutable_to_2d_id); 3539 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3540 3541 for (glw::GLint n_level = 0; n_level < reference_n_levels; ++n_level) 3542 { 3543 gl.texImage2D(GL_TEXTURE_2D, n_level, reference_to_internalformat, reference_to_width << n_level, 3544 reference_to_height << n_level, 0, /* border */ 3545 reference_to_format, reference_to_type, DE_NULL); /* pixels */ 3546 3547 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() call failed"); 3548 } 3549 3550 /* Create texture objects we'll be attempting to define as texture views */ 3551 gl.genTextures(1, &m_view_bound_to_id); 3552 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed"); 3553 3554 gl.genTextures(1, &m_view_never_bound_to_id); 3555 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed"); 3556 3557 gl.bindTexture(GL_TEXTURE_2D, m_view_bound_to_id); 3558 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3559 3560 /* a) GL_INVALID_VALUE should be generated if <texture> is 0. */ 3561 glw::GLint error_code = GL_NO_ERROR; 3562 3563 gl.textureView(0, /* texture */ 3564 GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat, 0, /* minlevel */ 3565 reference_n_levels, 0, /* minlayer */ 3566 1); /* numlayers */ 3567 3568 error_code = gl.getError(); 3569 if (error_code != GL_INVALID_VALUE) 3570 { 3571 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3572 << "]" 3573 " error generated when passing <texture> argument of 0" 3574 " to a glTextureView(), whereas GL_INVALID_VALUE was " 3575 "expected." 3576 << tcu::TestLog::EndMessage; 3577 3578 TCU_FAIL("GL_INVALID_VALUE not generated when passing 0 as <texture> argument to a " 3579 "glTextureView() call."); 3580 } 3581 3582 /* b) GL_INVALID_OPERATION should be generated if <texture> is not 3583 * a valid name returned by glGenTextures(). 3584 */ 3585 const glw::GLint invalid_to_id = 0xFFFFFFFF; 3586 3587 gl.textureView(invalid_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat, 3588 0, /* minlevel */ 3589 reference_n_levels, 0, /* minlayer */ 3590 1); /* numlayers */ 3591 3592 error_code = gl.getError(); 3593 if (error_code != GL_INVALID_OPERATION) 3594 { 3595 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3596 << "]" 3597 " error generated when passing <texture> argument of" 3598 " value that does not correspond to a valid texture " 3599 "object ID, whereas GL_INVALID_OPERATION was expected." 3600 << tcu::TestLog::EndMessage; 3601 3602 TCU_FAIL("GL_INVALID_OPERATION not generated when passing 0xFFFFFFFF as <texture> " 3603 "argument to a glTextureView() call."); 3604 } 3605 3606 /* c) GL_INVALID_OPERATION should be generated if <texture> has 3607 * already been bound and given a target. 3608 */ 3609 gl.textureView(m_view_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat, 3610 0, /* minlevel */ 3611 reference_n_levels, 0, /* minlayer */ 3612 1); /* numlayers */ 3613 3614 error_code = gl.getError(); 3615 if (error_code != GL_INVALID_OPERATION) 3616 { 3617 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3618 << "]" 3619 " error generated when passing <texture> argument " 3620 " that refers to an ID of a texture object that has " 3621 "already been bound to a texture target, whereas " 3622 "GL_INVALID_OPERATION was expected." 3623 << tcu::TestLog::EndMessage; 3624 3625 TCU_FAIL("GL_INVALID_OPERATION not generated when passing <texture> set" 3626 " to an ID of a texture object, that has already been bound to" 3627 " a texture target, to a glTextureView() call."); 3628 } 3629 3630 /* d) GL_INVALID_VALUE should be generated if <origtexture> is not 3631 * the name of a texture object. 3632 */ 3633 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, invalid_to_id, reference_to_internalformat, 3634 0, /* minlevel */ 3635 reference_n_levels, 0, /* minlayer */ 3636 1); /* numlayers */ 3637 3638 error_code = gl.getError(); 3639 if (error_code != GL_INVALID_VALUE) 3640 { 3641 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3642 << "]" 3643 " error generated when passing <origtexture> argument " 3644 " of value 0xFFFFFFFF, whereas GL_INVALID_VALUE was " 3645 "expected." 3646 << tcu::TestLog::EndMessage; 3647 3648 TCU_FAIL("GL_INVALID_VALUE not generated when passing an invalid ID of a texture " 3649 "object to <origtexture> argument."); 3650 } 3651 3652 /* e) GL_INVALID_OPERATION error should be generated if <origtexture> 3653 * is a mutable texture object. 3654 */ 3655 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_mutable_to_2d_id, reference_to_internalformat, 3656 0, /* minlevel */ 3657 reference_n_levels, 0, /* minlayer */ 3658 1); /* numlayers */ 3659 3660 error_code = gl.getError(); 3661 if (error_code != GL_INVALID_OPERATION) 3662 { 3663 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3664 << "]" 3665 " error generated when passing <origtexture> argument " 3666 " set to refer to a mutable texture object, whereas " 3667 "GL_INVALID_OPERATION was expected." 3668 << tcu::TestLog::EndMessage; 3669 3670 TCU_FAIL("GL_INVALID_OPERATION not generated when passing an ID of a mutable " 3671 "texture object through <origtexture> argument."); 3672 } 3673 3674 /* f) GL_INVALID_OPERATION error should be generated whenever the 3675 * application tries to generate a texture view for a target 3676 * that is incompatible with original texture's target. (as per 3677 * table 8.20 from OpenGL 4.3 specification) 3678 * 3679 * NOTE: All invalid original+view texture target combinations 3680 * should be checked. 3681 */ 3682 TextureViewUtilities::_incompatible_texture_target_pairs incompatible_texture_target_pairs = 3683 TextureViewUtilities::getIllegalTextureAndViewTargetCombinations(); 3684 3685 for (TextureViewUtilities::_incompatible_texture_target_pairs_const_iterator pair_iterator = 3686 incompatible_texture_target_pairs.begin(); 3687 pair_iterator != incompatible_texture_target_pairs.end(); pair_iterator++) 3688 { 3689 TextureViewUtilities::_internalformat_pair texture_target_pair = *pair_iterator; 3690 glw::GLenum original_texture_target = texture_target_pair.first; 3691 glw::GLenum view_texture_target = texture_target_pair.second; 3692 3693 /* Generate texture IDs */ 3694 gl.genTextures(1, &m_test_modified_to_id_1); 3695 gl.genTextures(1, &m_test_modified_to_id_2); 3696 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed"); 3697 3698 /* Configure reference texture object storage */ 3699 gl.bindTexture(original_texture_target, m_test_modified_to_id_1); 3700 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3701 3702 TextureViewUtilities::initTextureStorage(gl, true, /* create mutable parent texture */ 3703 original_texture_target, reference_to_depth, reference_to_height, 3704 reference_to_width, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 3705 reference_n_levels, reference_n_cubemaps, reference_bo_id); 3706 3707 /* Attempt to create the invalid view */ 3708 gl.textureView(m_test_modified_to_id_2, /* texture */ 3709 view_texture_target, m_test_modified_to_id_1, /* origtexture */ 3710 reference_to_internalformat, 0, /* minlevel */ 3711 reference_n_levels, 0, /* minlayer */ 3712 1); /* numlayers */ 3713 3714 error_code = gl.getError(); 3715 if (error_code != GL_INVALID_OPERATION) 3716 { 3717 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3718 << "]" 3719 " error generated when passing <origtexture> argument " 3720 " set to refer to a mutable texture object, whereas " 3721 "GL_INVALID_OPERATION was expected." 3722 << tcu::TestLog::EndMessage; 3723 3724 TCU_FAIL("GL_INVALID_OPERATION not generated when passing an ID of a mutable " 3725 "texture object through <origtexture> argument."); 3726 } 3727 3728 /* Release the texture IDs */ 3729 gl.deleteTextures(1, &m_test_modified_to_id_1); 3730 m_test_modified_to_id_1 = 0; 3731 3732 gl.deleteTextures(1, &m_test_modified_to_id_2); 3733 m_test_modified_to_id_2 = 0; 3734 3735 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed"); 3736 } /* for (all incompatible texture target pairs) */ 3737 3738 /* g) GL_INVALID_OPERATION error should be generated whenever the 3739 * application tries to create a texture view, internal format 3740 * of which can be found in table 8.21 of OpenGL 4.4 3741 * specification, and the texture view's internal format is 3742 * incompatible with parent object's internal format. Both 3743 * textures and views should be used as parent objects for the 3744 * purpose of the test. 3745 * 3746 * NOTE: All invalid texture view internal formats should be 3747 * checked for all applicable original object's internal 3748 * formats 3749 */ 3750 glw::GLint context_major_version = 0; 3751 glw::GLint context_minor_version = 0; 3752 3753 TextureViewUtilities::getMajorMinorVersionFromContextVersion(m_context.getRenderContext().getType(), 3754 &context_major_version, &context_minor_version); 3755 3756 TextureViewUtilities::_incompatible_internalformat_pairs internalformat_pairs = 3757 TextureViewUtilities::getIllegalTextureAndViewInternalformatCombinations(); 3758 3759 for (TextureViewUtilities::_incompatible_internalformat_pairs::const_iterator pair_iterator = 3760 internalformat_pairs.begin(); 3761 pair_iterator != internalformat_pairs.end(); pair_iterator++) 3762 { 3763 glw::GLenum src_internalformat = pair_iterator->first; 3764 glw::GLenum view_internalformat = pair_iterator->second; 3765 3766 /* Only run the test for internalformats supported by the tested OpenGL implementation */ 3767 if (!TextureViewUtilities::isInternalformatSupported(src_internalformat, context_major_version, 3768 context_minor_version) || 3769 !TextureViewUtilities::isInternalformatSupported(view_internalformat, context_major_version, 3770 context_minor_version)) 3771 { 3772 /* Next iteration, please */ 3773 continue; 3774 } 3775 3776 /* Generate texture IDs */ 3777 gl.genTextures(1, &m_test_modified_to_id_1); 3778 gl.genTextures(1, &m_test_modified_to_id_2); 3779 gl.genTextures(1, &m_test_modified_to_id_3); 3780 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed"); 3781 3782 /* Configure reference texture object storage */ 3783 gl.bindTexture(GL_TEXTURE_2D, m_test_modified_to_id_1); 3784 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3785 3786 TextureViewUtilities::initTextureStorage( 3787 gl, false, /* views require immutable parent texture objects */ 3788 GL_TEXTURE_2D, 0, /* texture_depth */ 3789 reference_to_height, reference_to_width, src_internalformat, 3790 GL_NONE, /* texture_format - not needed for immutable texture objects */ 3791 GL_NONE, /* texture_type - not needed for immutable texture objects */ 3792 reference_n_levels, 0, /* n_cubemaps_needed */ 3793 0); /* bo_id */ 3794 3795 /* Attempt to create an invalid view */ 3796 gl.textureView(m_test_modified_to_id_2, /* texture */ 3797 GL_TEXTURE_2D, m_test_modified_to_id_1, /* origtexture */ 3798 view_internalformat, 0, /* minlevel */ 3799 reference_n_levels, 0, /* minlayer */ 3800 1); /* numlayers */ 3801 3802 error_code = gl.getError(); 3803 if (error_code != GL_INVALID_OPERATION) 3804 { 3805 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3806 << "]" 3807 " error generated when requesting a view that uses " 3808 " an internalformat that is incompatible with parent " 3809 " texture object's, whereas GL_INVALID_OPERATION was " 3810 "expected." 3811 << tcu::TestLog::EndMessage; 3812 3813 TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view that " 3814 "uses an internalformat which is incompatible with parent texture's."); 3815 } 3816 3817 /* Create a valid view now */ 3818 gl.textureView(m_test_modified_to_id_2, /* texture */ 3819 GL_TEXTURE_2D, m_test_modified_to_id_1, /* origtexture */ 3820 src_internalformat, 0, /* minlevel */ 3821 reference_n_levels, 0, /* minlayer */ 3822 1); /* numlayers */ 3823 3824 GLU_EXPECT_NO_ERROR(gl.getError(), "A valid glTextureView() call failed"); 3825 3826 /* Attempt to create an invalid view, using the view we've just created 3827 * as a parent */ 3828 gl.textureView(m_test_modified_to_id_3, /* texture */ 3829 GL_TEXTURE_2D, m_test_modified_to_id_2, /* origtexture */ 3830 view_internalformat, 0, /* minlevel */ 3831 reference_n_levels, 0, /* minlayer */ 3832 1); /* numlayers */ 3833 3834 error_code = gl.getError(); 3835 if (error_code != GL_INVALID_OPERATION) 3836 { 3837 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3838 << "]" 3839 " error generated when requesting a view that uses " 3840 " an internalformat that is incompatible with parent " 3841 " view's, whereas GL_INVALID_OPERATION was expected." 3842 << tcu::TestLog::EndMessage; 3843 3844 TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view that " 3845 "uses an internalformat which is incompatible with parent view's."); 3846 } 3847 3848 /* Release the texture IDs */ 3849 gl.deleteTextures(1, &m_test_modified_to_id_1); 3850 m_test_modified_to_id_1 = 0; 3851 3852 gl.deleteTextures(1, &m_test_modified_to_id_2); 3853 m_test_modified_to_id_2 = 0; 3854 3855 gl.deleteTextures(1, &m_test_modified_to_id_3); 3856 m_test_modified_to_id_3 = 0; 3857 3858 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed"); 3859 } /* for (all incompatible texture+view internalformat pairs) */ 3860 3861 /* h) GL_INVALID_OPERATION error should be generated whenever the 3862 * application tries to create a texture view using an internal 3863 * format that does not match the original texture's, and the 3864 * original texture's internalformat cannot be found in table 3865 * 8.21 of OpenGL 4.3 specification. 3866 * 3867 * NOTE: All required base, sized and compressed texture internal 3868 * formats (as described in section 8.5.1 and table 8.14 3869 * of OpenGL 4.3 specification) that cannot be found in 3870 * table 8.21 should be considered for the purpose of this 3871 * test. 3872 */ 3873 for (int n_gl_internalformat = 0; n_gl_internalformat < n_valid_gl_internalformats; ++n_gl_internalformat) 3874 { 3875 glw::GLenum parent_texture_internalformat = valid_gl_internalformats[n_gl_internalformat]; 3876 3877 /* Only run the test for internalformats supported by the tested OpenGL implementation */ 3878 if (!TextureViewUtilities::isInternalformatSupported(parent_texture_internalformat, context_major_version, 3879 context_minor_version)) 3880 { 3881 /* Iterate the loop */ 3882 continue; 3883 } 3884 3885 /* For the purpose of the test, only consider internalformats that 3886 * are not associated with any view class */ 3887 if (TextureViewUtilities::getViewClassForInternalformat(parent_texture_internalformat) == VIEW_CLASS_UNDEFINED) 3888 { 3889 /* Initialize parent texture object */ 3890 gl.genTextures(1, &m_test_modified_to_id_1); 3891 gl.genTextures(1, &m_test_modified_to_id_2); 3892 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed"); 3893 3894 /* Configure reference texture object storage */ 3895 gl.bindTexture(GL_TEXTURE_2D, m_test_modified_to_id_1); 3896 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 3897 3898 TextureViewUtilities::initTextureStorage( 3899 gl, false, /* views require immutable parent texture objects */ 3900 GL_TEXTURE_2D, 0, /* texture_depth */ 3901 reference_to_height, reference_to_width, parent_texture_internalformat, 3902 GL_NONE, /* texture_format - not needed for immutable texture objects */ 3903 GL_NONE, /* texture_type - not needed for immutable texture objects */ 3904 reference_n_levels, 0, /* n_cubemaps_needed */ 3905 0); /* bo_id */ 3906 3907 /* Attempt to create the invalid view */ 3908 gl.textureView(m_test_modified_to_id_2, /* texture */ 3909 GL_TEXTURE_2D, m_test_modified_to_id_1, /* origtexture */ 3910 (parent_texture_internalformat != GL_RGBA32F) ? GL_RGBA32F : GL_RGB32F, 0, /* minlevel */ 3911 reference_n_levels, 0, /* minlayer */ 3912 1); /* numlayers */ 3913 3914 error_code = gl.getError(); 3915 if (error_code != GL_INVALID_OPERATION) 3916 { 3917 m_testCtx.getLog() << tcu::TestLog::Message << "[" 3918 << TextureViewUtilities::getErrorCodeString(error_code) 3919 << "]" 3920 " error generated when requesting a view that uses " 3921 " an internalformat different than the one used by " 3922 "parent texture object: " 3923 "[" 3924 << parent_texture_internalformat 3925 << "] " 3926 " and the parent texture's internalformat is not " 3927 "associated with any view class; GL_INVALID_OPERATION " 3928 "was expected" 3929 << tcu::TestLog::EndMessage; 3930 3931 TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view for " 3932 "a parent texture, internalformat of which is not associated with any " 3933 "view class, when the view's internalformat is different than the one " 3934 "used for parent texture."); 3935 } 3936 3937 /* Release the texture IDs */ 3938 gl.deleteTextures(1, &m_test_modified_to_id_1); 3939 m_test_modified_to_id_1 = 0; 3940 3941 gl.deleteTextures(1, &m_test_modified_to_id_2); 3942 m_test_modified_to_id_2 = 0; 3943 3944 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed"); 3945 } /* if (parent texture internalformat is not associated with a view class) */ 3946 } /* for (all valid GL internalformats) */ 3947 3948 /* i) GL_INVALID_VALUE error should be generated if <minlevel> is 3949 * larger than the greatest level of <origtexture>. 3950 */ 3951 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat, 3952 reference_n_levels, /* minlevel */ 3953 1, /* numlevels */ 3954 0, /* minlayer */ 3955 1); /* numlayers */ 3956 3957 error_code = gl.getError(); 3958 if (error_code != GL_INVALID_VALUE) 3959 { 3960 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3961 << "]" 3962 " error generated when passing <minlevel> argument " 3963 " larger than the greatest level of <origtexture>, whereas " 3964 "GL_INVALID_VALUE was expected." 3965 << tcu::TestLog::EndMessage; 3966 3967 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of <minlevel> " 3968 "larger than the greatest level defined for <origtexture>"); 3969 } 3970 3971 /* j) GL_INVALID_VALUE error should be generated if <minlayer> is 3972 * larger than the greatest layer of <origtexture>. 3973 */ 3974 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_id, 3975 reference_to_internalformat, 0, /* minlevel */ 3976 reference_n_levels, /* numlevels */ 3977 reference_to_depth, /* minlayer */ 3978 1); /* numlayers */ 3979 3980 error_code = gl.getError(); 3981 if (error_code != GL_INVALID_VALUE) 3982 { 3983 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 3984 << "]" 3985 " error generated when passing <minlayer> argument " 3986 " larger than the greatest layer of <origtexture>, whereas " 3987 "GL_INVALID_VALUE was expected." 3988 << tcu::TestLog::EndMessage; 3989 3990 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of <minlayer> " 3991 "larger than the greatest layer defined for <origtexture>"); 3992 } 3993 3994 /* k) GL_INVALID_VALUE error should be generated if <target> is 3995 * GL_TEXTURE_CUBE_MAP and <numlayers> is not 6. 3996 */ 3997 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_cube_map_id, 3998 reference_to_internalformat, 0, /* minlevel */ 3999 1, /* numlevels */ 4000 0, /* minlayer */ 4001 5); /* numlayers - invalid argument value */ 4002 4003 error_code = gl.getError(); 4004 if (error_code != GL_INVALID_VALUE) 4005 { 4006 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4007 << "]" 4008 " error generated when passing <numlayers> argument of value " 4009 "5 instead of 6 for GL_TEXTURE_CUBE_MAP texture target, whereas " 4010 "GL_INVALID_VALUE was expected." 4011 << tcu::TestLog::EndMessage; 4012 4013 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 5 to <minlayer>" 4014 "argument"); 4015 } 4016 4017 /* l) GL_INVALID_VALUE error should be generated if <target> is 4018 * GL_TEXTURE_CUBE_MAP_ARRAY and <numlayers> is not a multiple 4019 * of 6. 4020 */ 4021 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_cube_map_array_id, 4022 reference_to_internalformat, 0, /* minlevel */ 4023 1, /* numlevels */ 4024 0, /* minlayer */ 4025 1); /* numlayers - invalid argument value */ 4026 4027 error_code = gl.getError(); 4028 if (error_code != GL_INVALID_VALUE) 4029 { 4030 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4031 << "]" 4032 " error generated when passing <numlayers> argument of value " 4033 "1 instead of a multiple of 6 for GL_TEXTURE_CUBE_MAP_ARRAY " 4034 "texture target, whereas GL_INVALID_VALUE was expected." 4035 << tcu::TestLog::EndMessage; 4036 4037 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 1 to <minlayer>" 4038 "argument for a GL_TEXTURE_CUBE_MAP_ARRAY texture target"); 4039 } 4040 4041 /* m) GL_INVALID_VALUE error should be generated if <target> is 4042 * GL_TEXTURE_1D and <numlayers> is not 1; 4043 */ 4044 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_1D, m_reference_immutable_to_1d_id, reference_to_internalformat, 4045 0, /* minlevel */ 4046 1, /* numlevels */ 4047 0, /* minlayer */ 4048 2); /* numlayers - invalid argument value */ 4049 4050 error_code = gl.getError(); 4051 if (error_code != GL_INVALID_VALUE) 4052 { 4053 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4054 << "]" 4055 " error generated when passing <numlayers> argument of value " 4056 "2 instead of 1 for GL_TEXTURE_1D texture target, whereas " 4057 "GL_INVALID_VALUE was expected." 4058 << tcu::TestLog::EndMessage; 4059 4060 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>" 4061 "argument for a GL_TEXTURE_1D texture target"); 4062 } 4063 4064 /* n) GL_INVALID_VALUE error should be generated if <target> is 4065 * GL_TEXTURE_2D and <numlayers> is not 1; 4066 */ 4067 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat, 4068 0, /* minlevel */ 4069 1, /* numlevels */ 4070 0, /* minlayer */ 4071 2); /* numlayers - invalid argument value */ 4072 4073 error_code = gl.getError(); 4074 if (error_code != GL_INVALID_VALUE) 4075 { 4076 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4077 << "]" 4078 " error generated when passing <numlayers> argument of value " 4079 "2 instead of 1 for GL_TEXTURE_2D texture target, whereas " 4080 "GL_INVALID_VALUE was expected." 4081 << tcu::TestLog::EndMessage; 4082 4083 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>" 4084 "argument for a GL_TEXTURE_2D texture target"); 4085 } 4086 4087 /* o) GL_INVALID_VALUE error should be generated if <target> is 4088 * GL_TEXTURE_3D and <numlayers> is not 1; 4089 */ 4090 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_3D, m_reference_immutable_to_3d_id, reference_to_internalformat, 4091 0, /* minlevel */ 4092 1, /* numlevels */ 4093 0, /* minlayer */ 4094 2); /* numlayers - invalid argument value */ 4095 4096 error_code = gl.getError(); 4097 if (error_code != GL_INVALID_VALUE) 4098 { 4099 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4100 << "]" 4101 " error generated when passing <numlayers> argument of value " 4102 "2 instead of 1 for GL_TEXTURE_3D texture target, whereas " 4103 "GL_INVALID_VALUE was expected." 4104 << tcu::TestLog::EndMessage; 4105 4106 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>" 4107 "argument for a GL_TEXTURE_3D texture target"); 4108 } 4109 4110 /* p) GL_INVALID_VALUE error should be generated if <target> is 4111 * GL_TEXTURE_RECTANGLE and <numlayers> is not 1; 4112 */ 4113 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_RECTANGLE, m_reference_immutable_to_rectangle_id, 4114 reference_to_internalformat, 0, /* minlevel */ 4115 1, /* numlevels */ 4116 0, /* minlayer */ 4117 2); /* numlayers - invalid argument value */ 4118 4119 error_code = gl.getError(); 4120 if (error_code != GL_INVALID_VALUE) 4121 { 4122 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4123 << "]" 4124 " error generated when passing <numlayers> argument of value " 4125 "2 instead of 1 for GL_TEXTURE_RECTANGLE texture target, whereas " 4126 "GL_INVALID_VALUE was expected." 4127 << tcu::TestLog::EndMessage; 4128 4129 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>" 4130 "argument for a GL_TEXTURE_RECTANGLE texture target"); 4131 } 4132 4133 /* q) GL_INVALID_VALUE error should be generated if <target> is 4134 * GL_TEXTURE_2D_MULTISAMPLE and <numlayers> is not 1; 4135 */ 4136 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D_MULTISAMPLE, m_reference_immutable_to_2d_multisample_id, 4137 reference_to_internalformat, 0, /* minlevel */ 4138 1, /* numlevels */ 4139 0, /* minlayer */ 4140 2); /* numlayers - invalid argument value */ 4141 4142 error_code = gl.getError(); 4143 if (error_code != GL_INVALID_VALUE) 4144 { 4145 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4146 << "]" 4147 " error generated when passing <numlayers> argument of value " 4148 "2 instead of 1 for GL_TEXTURE_2D_MULTISAMPLE texture target, whereas " 4149 "GL_INVALID_VALUE was expected." 4150 << tcu::TestLog::EndMessage; 4151 4152 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>" 4153 "argument for a GL_TEXTURE_2D_MULTISAMPLE texture target"); 4154 } 4155 4156 /* r) GL_INVALID_OPERATION error should be generated if <target> is 4157 * GL_TEXTURE_CUBE_MAP and original texture's width does not 4158 * match original texture's height for all levels. 4159 */ 4160 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_2d_array_32_by_33_id, 4161 reference_to_internalformat, 0, /* minlevel */ 4162 1, /* numlevels */ 4163 0, /* minlayer */ 4164 6); /* numlayers */ 4165 4166 error_code = gl.getError(); 4167 if (error_code != GL_INVALID_OPERATION) 4168 { 4169 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4170 << "]" 4171 " error generated when using an immutable 2D array texture of 32x33x6 " 4172 "resolution to generate a GL_TEXTURE_CUBE_MAP view, whereas " 4173 "GL_INVALID_OPERATION was expected." 4174 << tcu::TestLog::EndMessage; 4175 4176 TCU_FAIL("GL_INVALID_OPERATION not generated when using an immutable 2D array texture of " 4177 "32x33x6 resolution to generate a GL_TEXTURE_CUBE_MAP view"); 4178 } 4179 4180 /* s) GL_INVALID_OPERATION error should be generated if <target> is 4181 * GL_TEXTURE_CUBE_MAP_ARRAY and original texture's width does 4182 * not match original texture's height for all levels. 4183 */ 4184 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_2d_array_32_by_33_id, 4185 reference_to_internalformat, 0, /* minlevel */ 4186 1, /* numlevels */ 4187 0, /* minlayer */ 4188 6); /* numlayers */ 4189 4190 error_code = gl.getError(); 4191 if (error_code != GL_INVALID_OPERATION) 4192 { 4193 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code) 4194 << "]" 4195 " error generated when using an immutable 2D array texture of 32x33x6 " 4196 "resolution to generate a GL_TEXTURE_CUBE_MAP_ARRAY view, whereas " 4197 "GL_INVALID_OPERATION was expected." 4198 << tcu::TestLog::EndMessage; 4199 4200 TCU_FAIL("GL_INVALID_OPERATION not generated when using an immutable 2D array texture of " 4201 "32x33x6 resolution to generate a GL_TEXTURE_CUBE_MAP_ARRAY view"); 4202 } 4203 4204 /* Test case passed */ 4205 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4206 4207 return STOP; 4208 } 4209 4210 /** Constructor. 4211 * 4212 * @param context Rendering context. 4213 **/ 4214 TextureViewTestViewSampling::TextureViewTestViewSampling(deqp::Context& context) 4215 : TestCase(context, "view_sampling", "Verify that sampling data from texture views, that use internal " 4216 "format which is compatible with the original texture's internal " 4217 "format, works correctly.") 4218 , m_bo_id(0) 4219 , m_fs_id(0) 4220 , m_gs_id(0) 4221 , m_po_id(0) 4222 , m_po_lod_location(-1) 4223 , m_po_n_face_location(-1) 4224 , m_po_reference_colors_location(-1) 4225 , m_po_texture_location(-1) 4226 , m_po_z_float_location(-1) 4227 , m_po_z_int_location(-1) 4228 , m_tc_id(0) 4229 , m_te_id(0) 4230 , m_vs_id(0) 4231 , m_per_sample_filler_fs_id(0) 4232 , m_per_sample_filler_gs_id(0) 4233 , m_per_sample_filler_po_id(0) 4234 , m_per_sample_filler_po_layer_id_location(-1) 4235 , m_per_sample_filler_po_reference_colors_location(-1) 4236 , m_per_sample_filler_vs_id(0) 4237 , m_result_to_id(0) 4238 , m_to_id(0) 4239 , m_view_to_id(0) 4240 , m_fbo_id(0) 4241 , m_vao_id(0) 4242 , m_max_color_texture_samples_gl_value(0) 4243 , m_iteration_parent_texture_depth(0) 4244 , m_iteration_parent_texture_height(0) 4245 , m_iteration_parent_texture_n_levels(0) 4246 , m_iteration_parent_texture_n_samples(0) 4247 , m_iteration_parent_texture_target(GL_NONE) 4248 , m_iteration_parent_texture_width(0) 4249 , m_iteration_view_texture_minlayer(0) 4250 , m_iteration_view_texture_numlayers(0) 4251 , m_iteration_view_texture_minlevel(0) 4252 , m_iteration_view_texture_numlevels(0) 4253 , m_iteration_view_texture_target(GL_NONE) 4254 , m_reference_texture_depth(4) 4255 , m_reference_texture_height(4) 4256 , m_reference_texture_n_mipmaps(3) 4257 , m_reference_texture_width(4) 4258 , m_reference_color_storage(DE_NULL) 4259 , m_result_data(DE_NULL) 4260 { 4261 /* Left blank on purpose */ 4262 } 4263 4264 /** De-initializes all GL objects created for the test. */ 4265 void TextureViewTestViewSampling::deinit() 4266 { 4267 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4268 4269 deinitIterationSpecificProgramAndShaderObjects(); 4270 deinitPerSampleFillerProgramAndShaderObjects(); 4271 deinitTextureObjects(); 4272 4273 /* Make sure any buffers we may have allocated during the execution do not leak */ 4274 if (m_result_data != DE_NULL) 4275 { 4276 delete[] m_result_data; 4277 4278 m_result_data = DE_NULL; 4279 } 4280 4281 /* Deinitialize other objects that are not re-created every iteration */ 4282 if (m_bo_id != 0) 4283 { 4284 gl.deleteBuffers(1, &m_bo_id); 4285 4286 m_bo_id = 0; 4287 } 4288 4289 if (m_fbo_id != 0) 4290 { 4291 gl.deleteFramebuffers(1, &m_fbo_id); 4292 4293 m_fbo_id = 0; 4294 } 4295 4296 if (m_reference_color_storage != DE_NULL) 4297 { 4298 delete m_reference_color_storage; 4299 4300 m_reference_color_storage = DE_NULL; 4301 } 4302 4303 if (m_vao_id != 0) 4304 { 4305 gl.deleteVertexArrays(1, &m_vao_id); 4306 4307 m_vao_id = 0; 4308 } 4309 4310 /* Restore default GL state the test may have modified */ 4311 gl.patchParameteri(GL_PATCH_VERTICES, 3); 4312 gl.pixelStorei(GL_PACK_ALIGNMENT, 4); 4313 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4); 4314 } 4315 4316 /** De-initializes program and shader objects created for each iteration. **/ 4317 void TextureViewTestViewSampling::deinitIterationSpecificProgramAndShaderObjects() 4318 { 4319 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4320 4321 if (m_fs_id != 0) 4322 { 4323 gl.deleteShader(m_fs_id); 4324 4325 m_fs_id = 0; 4326 } 4327 4328 if (m_gs_id != 0) 4329 { 4330 gl.deleteShader(m_gs_id); 4331 4332 m_gs_id = 0; 4333 } 4334 4335 if (m_po_id != 0) 4336 { 4337 gl.deleteProgram(m_po_id); 4338 4339 m_po_id = 0; 4340 } 4341 4342 if (m_tc_id != 0) 4343 { 4344 gl.deleteShader(m_tc_id); 4345 4346 m_tc_id = 0; 4347 } 4348 4349 if (m_te_id != 0) 4350 { 4351 gl.deleteShader(m_te_id); 4352 4353 m_te_id = 0; 4354 } 4355 4356 if (m_vs_id != 0) 4357 { 4358 gl.deleteShader(m_vs_id); 4359 4360 m_vs_id = 0; 4361 } 4362 } 4363 4364 /** De-initializes shader and program objects providing the 'per-sample filling' 4365 * functionality. 4366 **/ 4367 void TextureViewTestViewSampling::deinitPerSampleFillerProgramAndShaderObjects() 4368 { 4369 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4370 4371 if (m_per_sample_filler_fs_id != 0) 4372 { 4373 gl.deleteShader(m_per_sample_filler_fs_id); 4374 4375 m_per_sample_filler_fs_id = 0; 4376 } 4377 4378 if (m_per_sample_filler_gs_id != 0) 4379 { 4380 gl.deleteShader(m_per_sample_filler_gs_id); 4381 4382 m_per_sample_filler_gs_id = 0; 4383 } 4384 4385 if (m_per_sample_filler_po_id != 0) 4386 { 4387 gl.deleteProgram(m_per_sample_filler_po_id); 4388 4389 m_per_sample_filler_po_id = 0; 4390 } 4391 4392 if (m_per_sample_filler_vs_id != 0) 4393 { 4394 gl.deleteShader(m_per_sample_filler_vs_id); 4395 4396 m_per_sample_filler_vs_id = 0; 4397 } 4398 } 4399 4400 /** De-initializes texture objects used by the test */ 4401 void TextureViewTestViewSampling::deinitTextureObjects() 4402 { 4403 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4404 4405 if (m_result_to_id != 0) 4406 { 4407 gl.deleteTextures(1, &m_result_to_id); 4408 4409 m_result_to_id = 0; 4410 } 4411 4412 if (m_to_id != 0) 4413 { 4414 gl.deleteTextures(1, &m_to_id); 4415 4416 m_to_id = 0; 4417 } 4418 4419 if (m_view_to_id != 0) 4420 { 4421 gl.deleteTextures(1, &m_view_to_id); 4422 4423 m_view_to_id = 0; 4424 } 4425 } 4426 4427 /** Executes a single test iteration. 4428 * 4429 * @return true if the iteration executed successfully, false otherwise. 4430 **/ 4431 bool TextureViewTestViewSampling::executeTest() 4432 { 4433 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4434 bool result = true; 4435 4436 /* Bind the view to zero texture unit */ 4437 gl.activeTexture(GL_TEXTURE0); 4438 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed."); 4439 4440 gl.bindTexture(m_iteration_view_texture_target, m_view_to_id); 4441 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 4442 4443 /* Bind the buffer object to zero TF binding point */ 4444 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id); 4445 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 4446 4447 /* Activate the test program */ 4448 gl.useProgram(m_po_id); 4449 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 4450 4451 /* Update draw framebuffer configuration so that the test's fragment shader draws 4452 * to the result texture */ 4453 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id); 4454 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed."); 4455 4456 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_result_to_id, 0); /* level */ 4457 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 4458 4459 /* Allocate enough space to hold reference color data for all sample s*/ 4460 float* reference_color_data = new float[m_iteration_parent_texture_n_samples * sizeof(float) * 4 /* rgba */]; 4461 4462 /* Iterate through the layer/face/mipmap hierarchy. For each iteration, we 4463 * potentially need to update relevant uniforms controlling the sampling process 4464 * the test program object performs. 4465 */ 4466 bool is_view_cm_cma = (m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP || 4467 m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 4468 4469 for (unsigned int n_current_layer = m_iteration_view_texture_minlayer; 4470 n_current_layer < (m_iteration_view_texture_minlayer + m_iteration_view_texture_numlayers) && result; 4471 n_current_layer++) 4472 { 4473 unsigned int n_texture_face = 0; 4474 unsigned int n_texture_layer = 0; 4475 unsigned int n_view_face = 0; 4476 unsigned int n_view_layer = 0; 4477 4478 if (is_view_cm_cma) 4479 { 4480 n_texture_face = n_current_layer % 6; /* faces */ 4481 n_texture_layer = n_current_layer / 6; /* faces */ 4482 n_view_face = (n_current_layer - m_iteration_view_texture_minlayer) % 6; /* faces */ 4483 n_view_layer = (n_current_layer - m_iteration_view_texture_minlayer) / 6; /* faces */ 4484 } 4485 else 4486 { 4487 /* Only cube-map and cube-map array textures consist of faces. */ 4488 n_texture_face = 0; 4489 n_texture_layer = n_current_layer; 4490 n_view_face = 0; 4491 n_view_layer = n_current_layer; 4492 } 4493 4494 if (m_po_z_float_location != -1) 4495 { 4496 float z = 0.0f; 4497 4498 if (((false == is_view_cm_cma) && (m_iteration_view_texture_numlayers > 1)) || 4499 ((true == is_view_cm_cma) && (m_iteration_view_texture_numlayers > 6))) 4500 { 4501 if (is_view_cm_cma) 4502 { 4503 z = float(n_view_layer) / float(m_iteration_view_texture_numlayers / 6 - 1); 4504 } 4505 else 4506 { 4507 if (m_iteration_view_texture_numlayers > 1) 4508 { 4509 /* The program will be sampling a view so make sure that layer the shader accesses 4510 * is relative to how our view was configured */ 4511 z = float(n_view_layer - m_iteration_view_texture_minlayer) / 4512 float(m_iteration_view_texture_numlayers - 1); 4513 } 4514 else 4515 { 4516 /* z should stay at 0 */ 4517 } 4518 } 4519 } 4520 else 4521 { 4522 /* z should stay at 0.0 */ 4523 } 4524 4525 gl.uniform1f(m_po_z_float_location, z); 4526 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed."); 4527 } 4528 4529 if (m_po_z_int_location != -1) 4530 { 4531 DE_ASSERT(!is_view_cm_cma); 4532 4533 gl.uniform1i(m_po_z_int_location, n_current_layer - m_iteration_view_texture_minlayer); 4534 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 4535 } 4536 4537 if (m_po_n_face_location != -1) 4538 { 4539 gl.uniform1i(m_po_n_face_location, n_view_face); 4540 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 4541 } 4542 4543 for (unsigned int n_mipmap = m_iteration_view_texture_minlevel; 4544 n_mipmap < (m_iteration_view_texture_minlevel + m_iteration_view_texture_numlevels) && result; n_mipmap++) 4545 { 4546 if (m_po_lod_location != -1) 4547 { 4548 /* The program will be sampling a view so make sure that LOD the shader accesses 4549 * is relative to how our view was configured. 4550 */ 4551 gl.uniform1f(m_po_lod_location, (float)(n_mipmap - m_iteration_view_texture_minlevel)); 4552 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 4553 } 4554 4555 /* Update local reference color data storage */ 4556 for (unsigned int n_sample = 0; n_sample < m_iteration_parent_texture_n_samples; ++n_sample) 4557 { 4558 tcu::Vec4 reference_color = getReferenceColor(n_texture_layer, n_texture_face, n_mipmap, n_sample); 4559 4560 reference_color_data[4 /* rgba */ * n_sample + 0] = reference_color.x(); 4561 reference_color_data[4 /* rgba */ * n_sample + 1] = reference_color.y(); 4562 reference_color_data[4 /* rgba */ * n_sample + 2] = reference_color.z(); 4563 reference_color_data[4 /* rgba */ * n_sample + 3] = reference_color.w(); 4564 } 4565 4566 /* Upload it to GPU */ 4567 gl.uniform4fv(m_po_reference_colors_location, m_iteration_parent_texture_n_samples, reference_color_data); 4568 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed."); 4569 4570 /* Bind the texture view to sample from */ 4571 gl.bindTexture(m_iteration_view_texture_target, m_view_to_id); 4572 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 4573 4574 /* Draw a single patch. Given the rendering pipeline we've defined in the 4575 * test program object, this should give us a nice full-screen quad, as well 4576 * as 6*4 ints XFBed out, describing whether the view was sampled correctly. 4577 */ 4578 gl.beginTransformFeedback(GL_TRIANGLES); 4579 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 4580 { 4581 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 4582 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 4583 } 4584 gl.endTransformFeedback(); 4585 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 4586 4587 /* In order to verify if the texel data was sampled correctly, we need to do two things: 4588 * 4589 * 1) Verify buffer object contents; 4590 * 2) Make sure that all texels of current render-target are vec4(1). 4591 * 4592 */ 4593 const int* bo_storage_ptr = (const int*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 4594 4595 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 4596 if (bo_storage_ptr == NULL) 4597 { 4598 TCU_FAIL("glMapBuffer() call succeeded but the pointer returned is NULL"); 4599 } 4600 4601 /* The rendering pipeline should have written 6 vertices * 4 ints to the BO. 4602 * The integers are set to 1 if the sampled texels were found valid, 0 otherwise, 4603 * and are arranged in the following order: 4604 * 4605 * 1) Result of sampling in vertex shader stage; 4606 * 2) Result of sampling in tessellation control shader stage; 4607 * 3) Result of sampling in tessellation evaluation shader stage; 4608 * 4) Result of sampling in geometry shader stage; 4609 */ 4610 for (unsigned int n_vertex = 0; n_vertex < 6 /* as per comment */ && result; ++n_vertex) 4611 { 4612 const int* vertex_data_ptr = bo_storage_ptr + n_vertex * 4 /* as per comment */; 4613 int vs_result = vertex_data_ptr[0]; 4614 int tc_result = vertex_data_ptr[1]; 4615 int te_result = vertex_data_ptr[2]; 4616 int gs_result = vertex_data_ptr[3]; 4617 4618 if (vs_result != 1) 4619 { 4620 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled in vertex shader stage." 4621 << tcu::TestLog::EndMessage; 4622 4623 result = false; 4624 } 4625 4626 if (tc_result != 1) 4627 { 4628 m_testCtx.getLog() << tcu::TestLog::Message 4629 << "Invalid data was sampled in tessellation control shader stage." 4630 << tcu::TestLog::EndMessage; 4631 4632 result = false; 4633 } 4634 4635 if (te_result != 1) 4636 { 4637 m_testCtx.getLog() << tcu::TestLog::Message 4638 << "Invalid data was sampled in tessellation evaluation shader stage." 4639 << tcu::TestLog::EndMessage; 4640 4641 result = false; 4642 } 4643 4644 if (gs_result != 1) 4645 { 4646 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled in geometry shader stage." 4647 << tcu::TestLog::EndMessage; 4648 4649 result = false; 4650 } 4651 } /* for (all vertices) */ 4652 4653 /* Unmap the BO */ 4654 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 4655 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 4656 4657 /* Read texels rendered by the fragment shader. The texture attached uses 4658 * GL_RGBA8 internalformat.*/ 4659 m_result_data = new unsigned char[m_reference_texture_width * m_reference_texture_height * 4 /* RGBA */]; 4660 4661 gl.bindTexture(GL_TEXTURE_2D, m_result_to_id); 4662 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed for GL_TEXTURE_2D texture target."); 4663 4664 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, GL_UNSIGNED_BYTE, m_result_data); 4665 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage() call failed."); 4666 4667 /* The test fails if any of the fragments is not equal to vec4(1) */ 4668 bool fs_result = true; 4669 4670 for (unsigned int y = 0; y < m_reference_texture_height && fs_result; ++y) 4671 { 4672 const unsigned char* row_ptr = m_result_data + m_reference_texture_width * y * 4 /* RGBA */; 4673 4674 for (unsigned int x = 0; x < m_reference_texture_width && fs_result; ++x) 4675 { 4676 const unsigned char* pixel_ptr = row_ptr + x * 4 /* RGBA */; 4677 4678 if (pixel_ptr[0] != 255 || pixel_ptr[1] != 255 || pixel_ptr[2] != 255 || pixel_ptr[3] != 255) 4679 { 4680 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled at (" << x << ", " << y 4681 << ") " 4682 "in fragment shader stage." 4683 << tcu::TestLog::EndMessage; 4684 4685 fs_result = false; 4686 } 4687 } /* for (all columns) */ 4688 } /* for (all rows) */ 4689 4690 if (!fs_result) 4691 { 4692 result = false; 4693 } 4694 4695 /* Done - we can release the buffer at this point */ 4696 delete[] m_result_data; 4697 m_result_data = DE_NULL; 4698 } /* for (all mip-maps) */ 4699 } /* for (all texture layers) */ 4700 4701 /* Release the reference color data buffer */ 4702 delete[] reference_color_data; 4703 reference_color_data = DE_NULL; 4704 4705 /* All done */ 4706 return result; 4707 } 4708 4709 /** Returns a different vec4 every time the function is called. Each component 4710 * is assigned a normalized value within <0, 1> range. 4711 * 4712 * @return As per description. 4713 **/ 4714 tcu::Vec4 TextureViewTestViewSampling::getRandomReferenceColor() 4715 { 4716 static unsigned int seed = 195; 4717 tcu::Vec4 result; 4718 4719 result = tcu::Vec4(float((seed) % 255) / 255.0f, float((seed << 3) % 255) / 255.0f, 4720 float((seed << 4) % 255) / 255.0f, float((seed << 5) % 255) / 255.0f); 4721 4722 seed += 17; 4723 4724 return result; 4725 } 4726 4727 /** Every test iteration is assigned a different set of so-called reference colors. 4728 * Depending on the texture target, each reference color corresponds to an unique color 4729 * used to build different layers/faces/mip-maps or even samples of tose. 4730 * 4731 * Once the reference color storage is initialized, this function can be used to retrieve 4732 * details of a color allocated a specific sample of a layer/face mip-map. 4733 * 4734 * This function will cause an assertion failure if an invalid layer/face/mipmap/sample is 4735 * requested, as well as if the reference color storage is not initialized at the time of the call. 4736 * 4737 * @param n_layer Layer index to use for the query. A value of 0 should be used for non-arrayed 4738 * texture targets. 4739 * @param n_face Face index to use for the query. A value of 0 should be used for non-CM texture 4740 * targets. Otherwise: 4741 * * 0 corresponds to +X; 4742 * * 1 corresponds to -X; 4743 * * 2 corresponds to +Y; 4744 * * 3 corresponds to -Y; 4745 * * 4 corresponds to +Z; 4746 * * 5 corresponds to -Z. 4747 * @param n_mipmap Mip-map index to use for the query. A value of 0 should be used for non-mipmapped 4748 * texture targets. 4749 * @param n_sample Sample index to use for the query. A value of 0 should be used for single-sampled 4750 * texture targets. 4751 * 4752 * @return Requested color data. 4753 **/ 4754 tcu::Vec4 TextureViewTestViewSampling::getReferenceColor(unsigned int n_layer, unsigned int n_face, 4755 unsigned int n_mipmap, unsigned int n_sample) 4756 { 4757 tcu::Vec4 result; 4758 4759 DE_ASSERT(m_reference_color_storage != DE_NULL); 4760 if (m_reference_color_storage != DE_NULL) 4761 { 4762 bool is_parent_texture_cm_cma = (m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP || 4763 m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 4764 bool is_view_texture_cm_cma = (m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP || 4765 m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 4766 4767 if (is_view_texture_cm_cma && !is_parent_texture_cm_cma) 4768 { 4769 /* Parent texture is not using faces. Compute layer index, as 4770 * if the texture was actually a CM or a CMA */ 4771 unsigned int temp = n_layer * 6 /* layer-faces per layer */ + n_face; 4772 4773 n_layer = temp; 4774 n_face = 0; 4775 } 4776 else if (!is_view_texture_cm_cma && is_parent_texture_cm_cma) 4777 { 4778 /* The other way around - assume the texture is a CM or CMA */ 4779 n_face = n_layer % 6; /* faces per cube-map layer */ 4780 n_layer = n_layer / 6; /* faces per cube-map layer */ 4781 } 4782 4783 DE_ASSERT(n_face < m_reference_color_storage->n_faces); 4784 DE_ASSERT(n_layer < m_reference_color_storage->n_layers); 4785 DE_ASSERT(n_mipmap < m_reference_color_storage->n_mipmaps); 4786 DE_ASSERT(n_sample < m_reference_color_storage->n_samples); 4787 4788 /* Hierarchy is: 4789 * 4790 * layers -> faces -> mipmaps -> samples */ 4791 const unsigned int index = 4792 n_layer * (m_reference_color_storage->n_faces * m_reference_color_storage->n_mipmaps * 4793 m_reference_color_storage->n_samples) + 4794 n_face * (m_reference_color_storage->n_mipmaps * m_reference_color_storage->n_samples) + 4795 n_mipmap * (m_reference_color_storage->n_samples) + n_sample; 4796 4797 result = m_reference_color_storage->data[index]; 4798 } 4799 4800 return result; 4801 } 4802 4803 /* Retrieve max conformant sample count when GL_NV_internalformat_sample_query is supported */ 4804 glw::GLint TextureViewTestViewSampling::getMaxConformantSampleCount(glw::GLenum target, glw::GLenum internalFormat) 4805 { 4806 (void)internalFormat; 4807 glw::GLint max_conformant_samples = 0; 4808 4809 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4810 4811 /* Return the max conformant sample count if extension is supported */ 4812 if (m_context.getContextInfo().isExtensionSupported("GL_NV_internalformat_sample_query")) 4813 { 4814 glw::GLint gl_sample_counts = 0; 4815 gl.getInternalformativ(target, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &gl_sample_counts); 4816 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_NUM_SAMPLE_COUNTS pname"); 4817 4818 /* Check and return the first conformant sample count */ 4819 glw::GLint* gl_supported_samples = new glw::GLint[gl_sample_counts]; 4820 if (gl_supported_samples) 4821 { 4822 gl.getInternalformativ(target, GL_RGBA8, GL_SAMPLES, gl_sample_counts, gl_supported_samples); 4823 4824 for (glw::GLint i = 0; i < gl_sample_counts; i++) 4825 { 4826 glw::GLint isConformant = 0; 4827 gl.getInternalformatSampleivNV(target, GL_RGBA8, gl_supported_samples[i], GL_CONFORMANT_NV, 1, 4828 &isConformant); 4829 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformatSampleivNV() call(s) failed"); 4830 4831 if (isConformant && gl_supported_samples[i] > max_conformant_samples) 4832 { 4833 max_conformant_samples = gl_supported_samples[i]; 4834 } 4835 } 4836 delete[] gl_supported_samples; 4837 } 4838 } 4839 else 4840 { 4841 /* Otherwise return GL_MAX_COLOR_TEXTURE_SAMPLES */ 4842 gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_conformant_samples); 4843 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname."); 4844 } 4845 4846 return max_conformant_samples; 4847 } 4848 4849 /** Initializes iteration-specific program object used to sample the texture data. */ 4850 void TextureViewTestViewSampling::initIterationSpecificProgramObject() 4851 { 4852 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4853 4854 /* Release shader/program objects that may have been initialized in previous 4855 * iterations. 4856 */ 4857 deinitIterationSpecificProgramAndShaderObjects(); 4858 4859 /* Create program and shader objects */ 4860 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 4861 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 4862 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER); 4863 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER); 4864 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 4865 4866 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 4867 4868 m_po_id = gl.createProgram(); 4869 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed."); 4870 4871 /* Prepare token replacement strings */ 4872 std::stringstream n_samples_sstream; 4873 std::string sampler_declarations_string; 4874 std::string sample_fetch_string; 4875 std::string sample_fetch_fs_string; 4876 std::size_t token_location = std::string::npos; 4877 const char* token_n_samples = "N_SAMPLES"; 4878 const char* token_sampler_declarations = "SAMPLER_DECLARATIONS"; 4879 const char* token_sample_fetch = "SAMPLE_FETCH"; 4880 4881 n_samples_sstream << m_iteration_parent_texture_n_samples; 4882 4883 switch (m_iteration_view_texture_target) 4884 { 4885 case GL_TEXTURE_1D: 4886 { 4887 sampler_declarations_string = "uniform sampler1D texture;"; 4888 sample_fetch_string = "vec4 current_sample = textureLod(texture, 0.5, lod);\n"; 4889 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, gs_fs_uv.x, lod);\n"; 4890 4891 break; 4892 } 4893 4894 case GL_TEXTURE_1D_ARRAY: 4895 { 4896 sampler_declarations_string = "uniform sampler1DArray texture;\n" 4897 "uniform float z_float;\n"; 4898 4899 sample_fetch_string = "vec4 current_sample = textureLod(texture, vec2(0.5, z_float), lod);\n"; 4900 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec2(gs_fs_uv.x, z_float), lod);\n"; 4901 4902 break; 4903 } 4904 4905 case GL_TEXTURE_2D: 4906 { 4907 sampler_declarations_string = "uniform sampler2D texture;"; 4908 sample_fetch_string = "vec4 current_sample = textureLod(texture, vec2(0.5), lod);\n"; 4909 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, gs_fs_uv, lod);\n"; 4910 4911 break; 4912 } 4913 4914 case GL_TEXTURE_2D_ARRAY: 4915 { 4916 sampler_declarations_string = "uniform float z_float;\n" 4917 "uniform sampler2DArray texture;"; 4918 4919 sample_fetch_string = "vec4 current_sample = textureLod(texture, vec3(vec2(0.5), z_float), lod);\n"; 4920 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec3(gs_fs_uv, z_float), lod);\n"; 4921 4922 break; 4923 } 4924 4925 case GL_TEXTURE_2D_MULTISAMPLE: 4926 { 4927 sampler_declarations_string = "uniform sampler2DMS texture;"; 4928 sample_fetch_string = "ivec2 texture_size = textureSize(texture);\n" 4929 "vec4 current_sample = texelFetch (texture,\n" 4930 " ivec2(texture_size.xy / ivec2(2)),\n" 4931 " n_sample);\n"; 4932 4933 sample_fetch_fs_string = "ivec2 texture_size = textureSize(texture);\n" 4934 "vec4 current_sample = texelFetch (texture,\n" 4935 " ivec2(gs_fs_uv * vec2(texture_size)),\n" 4936 " n_sample);\n"; 4937 4938 break; 4939 } 4940 4941 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 4942 { 4943 sampler_declarations_string = "uniform sampler2DMSArray texture;" 4944 "uniform int z_int;\n"; 4945 4946 sample_fetch_string = "ivec3 texture_size = textureSize(texture);\n" 4947 "vec4 current_sample = texelFetch (texture,\n" 4948 " ivec3(texture_size.xy / ivec2(2), z_int),\n" 4949 " n_sample);\n"; 4950 4951 sample_fetch_fs_string = 4952 "ivec3 texture_size = textureSize(texture);\n" 4953 "vec4 current_sample = texelFetch (texture,\n" 4954 " ivec3(ivec2(gs_fs_uv * vec2(texture_size).xy), z_int),\n" 4955 " n_sample);\n"; 4956 4957 break; 4958 } 4959 4960 case GL_TEXTURE_3D: 4961 { 4962 sampler_declarations_string = "uniform sampler3D texture;" 4963 "uniform float z_float;"; 4964 4965 sample_fetch_string = "vec4 current_sample = textureLod(texture, vec3(vec2(0.5), z_float), lod);\n"; 4966 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec3(gs_fs_uv, z_float), lod);\n"; 4967 4968 break; 4969 } 4970 4971 case GL_TEXTURE_CUBE_MAP: 4972 { 4973 sampler_declarations_string = "uniform samplerCube texture;\n" 4974 "uniform int n_face;"; 4975 4976 sample_fetch_string = "vec4 current_sample;\n" 4977 "\n" 4978 "switch (n_face)\n" 4979 "{\n" 4980 // GL_TEXTURE_CUBE_MAP_POSITIVE_X 4981 " case 0: current_sample = textureLod(texture, vec3( 1, 0, 0), lod); break;\n" 4982 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X 4983 " case 1: current_sample = textureLod(texture, vec3(-1, 0, 0), lod); break;\n" 4984 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y 4985 " case 2: current_sample = textureLod(texture, vec3( 0, 1, 0), lod); break;\n" 4986 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 4987 " case 3: current_sample = textureLod(texture, vec3( 0, -1, 0), lod); break;\n" 4988 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z 4989 " case 4: current_sample = textureLod(texture, vec3( 0, 0, 1), lod); break;\n" 4990 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 4991 " case 5: current_sample = textureLod(texture, vec3( 0, 0, -1), lod); break;\n" 4992 "}\n"; 4993 4994 sample_fetch_fs_string = 4995 "vec4 current_sample;\n" 4996 "\n" 4997 "switch (n_face)\n" 4998 "{\n" 4999 // GL_TEXTURE_CUBE_MAP_POSITIVE_X 5000 " case 0: current_sample = textureLod(texture, normalize(vec3( 1, gs_fs_uv.xy)), lod); break;\n" 5001 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X 5002 " case 1: current_sample = textureLod(texture, normalize(vec3(-1, gs_fs_uv.xy)), lod); break;\n" 5003 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y 5004 " case 2: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.x, 1, gs_fs_uv.y)), lod); " 5005 "break;\n" 5006 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 5007 " case 3: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.x, -1, gs_fs_uv.y)), lod); " 5008 "break;\n" 5009 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z 5010 " case 4: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.xy, 1)), lod); break;\n" 5011 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 5012 " case 5: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.xy, -1)), lod); break;\n" 5013 "}\n"; 5014 break; 5015 } 5016 5017 case GL_TEXTURE_CUBE_MAP_ARRAY: 5018 { 5019 sampler_declarations_string = "uniform samplerCubeArray texture;\n" 5020 "uniform int n_face;\n" 5021 "uniform float z_float;\n"; 5022 5023 sample_fetch_string = 5024 "vec4 current_sample;\n" 5025 "\n" 5026 "switch (n_face)\n" 5027 "{\n" 5028 // GL_TEXTURE_CUBE_MAP_POSITIVE_X 5029 " case 0: current_sample = textureLod(texture, vec4( 1, 0, 0, z_float), lod); break;\n" 5030 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X 5031 " case 1: current_sample = textureLod(texture, vec4(-1, 0, 0, z_float), lod); break;\n" 5032 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y 5033 " case 2: current_sample = textureLod(texture, vec4( 0, 1, 0, z_float), lod); break;\n" 5034 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 5035 " case 3: current_sample = textureLod(texture, vec4( 0, -1, 0, z_float), lod); break;\n" 5036 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z 5037 " case 4: current_sample = textureLod(texture, vec4( 0, 0, 1, z_float), lod); break;\n" 5038 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 5039 " case 5: current_sample = textureLod(texture, vec4( 0, 0, -1, z_float), lod); break;\n" 5040 "}\n"; 5041 5042 sample_fetch_fs_string = "vec4 current_sample;\n" 5043 "\n" 5044 "switch (n_face)\n" 5045 "{\n" 5046 // GL_TEXTURE_CUBE_MAP_POSITIVE_X 5047 " case 0: current_sample = textureLod(texture, vec4(normalize(vec3( 1, " 5048 "gs_fs_uv.xy)), z_float), lod); break;\n" 5049 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X 5050 " case 1: current_sample = textureLod(texture, vec4(normalize(vec3(-1, " 5051 "gs_fs_uv.xy)), z_float), lod); break;\n" 5052 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y 5053 " case 2: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.x, 1, " 5054 " gs_fs_uv.y)), z_float), lod); break;\n" 5055 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 5056 " case 3: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.x, " 5057 "-1, gs_fs_uv.y)), z_float), lod); break;\n" 5058 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z 5059 " case 4: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.xy, " 5060 "1)), z_float), lod); break;\n" 5061 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 5062 " case 5: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.xy, " 5063 "-1)), z_float), lod); break;\n" 5064 "}\n"; 5065 5066 break; 5067 } 5068 5069 case GL_TEXTURE_RECTANGLE: 5070 { 5071 sampler_declarations_string = "uniform sampler2DRect texture;"; 5072 sample_fetch_string = "ivec2 texture_size = textureSize(texture);\n" 5073 "vec4 current_sample = texelFetch (texture, texture_size / ivec2(2));\n"; 5074 5075 sample_fetch_fs_string = 5076 "ivec2 texture_size = textureSize(texture);\n" 5077 "vec4 current_sample = texelFetch (texture, ivec2(gs_fs_uv.xy * vec2(texture_size)));\n"; 5078 5079 break; 5080 } 5081 5082 default: 5083 { 5084 TCU_FAIL("Unrecognized texture target"); 5085 } 5086 } /* switch (m_iteration_view_texture_target) */ 5087 5088 /* Set vertex shader's body */ 5089 const char* vs_body = "#version 400\n" 5090 "\n" 5091 "uniform float lod;\n" 5092 "uniform vec4 reference_colors[N_SAMPLES];\n" 5093 "SAMPLER_DECLARATIONS\n" 5094 "\n" 5095 "out int vs_tc_vs_sampling_result;\n" 5096 "\n" 5097 "void main()\n" 5098 "{\n" 5099 " const float epsilon = 1.0 / 255.0;\n" 5100 "\n" 5101 " vs_tc_vs_sampling_result = 1;\n" 5102 "\n" 5103 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n" 5104 " {\n" 5105 " SAMPLE_FETCH;\n" 5106 "\n" 5107 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n" 5108 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n" 5109 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n" 5110 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n" 5111 " {\n" 5112 " vs_tc_vs_sampling_result = int(current_sample.x * 256.0);\n" 5113 "\n" 5114 " break;\n" 5115 " }\n" 5116 " }\n" 5117 "\n" 5118 " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n" 5119 "}\n"; 5120 std::string vs_string = vs_body; 5121 5122 while ((token_location = vs_string.find(token_n_samples)) != std::string::npos) 5123 { 5124 vs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str()); 5125 } 5126 5127 while ((token_location = vs_string.find(token_sampler_declarations)) != std::string::npos) 5128 { 5129 vs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string); 5130 } 5131 5132 while ((token_location = vs_string.find(token_sample_fetch)) != std::string::npos) 5133 { 5134 vs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string); 5135 } 5136 5137 /* Set tessellation control shader's body */ 5138 const char* tc_body = "#version 400\n" 5139 "\n" 5140 "layout(vertices = 1) out;\n" 5141 "\n" 5142 "uniform float lod;\n" 5143 "uniform vec4 reference_colors[N_SAMPLES];\n" 5144 "SAMPLER_DECLARATIONS\n" 5145 "\n" 5146 "in int vs_tc_vs_sampling_result[];\n" 5147 "out int tc_te_vs_sampling_result[];\n" 5148 "out int tc_te_tc_sampling_result[];\n" 5149 "\n" 5150 "void main()\n" 5151 "{\n" 5152 " const float epsilon = 1.0 / 255.0;\n" 5153 "\n" 5154 " tc_te_vs_sampling_result[gl_InvocationID] = vs_tc_vs_sampling_result[gl_InvocationID];\n" 5155 " tc_te_tc_sampling_result[gl_InvocationID] = 1;\n" 5156 "\n" 5157 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n" 5158 " {\n" 5159 " SAMPLE_FETCH\n" 5160 "\n" 5161 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n" 5162 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n" 5163 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n" 5164 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n" 5165 " {\n" 5166 " tc_te_tc_sampling_result[gl_InvocationID] = 0;\n" 5167 "\n" 5168 " break;\n" 5169 " }\n" 5170 " }\n" 5171 "\n" 5172 " gl_TessLevelInner[0] = 1.0;\n" 5173 " gl_TessLevelInner[1] = 1.0;\n" 5174 " gl_TessLevelOuter[0] = 1.0;\n" 5175 " gl_TessLevelOuter[1] = 1.0;\n" 5176 " gl_TessLevelOuter[2] = 1.0;\n" 5177 " gl_TessLevelOuter[3] = 1.0;\n" 5178 "}\n"; 5179 5180 std::string tc_string = tc_body; 5181 5182 while ((token_location = tc_string.find(token_n_samples)) != std::string::npos) 5183 { 5184 tc_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str()); 5185 } 5186 5187 while ((token_location = tc_string.find(token_sampler_declarations)) != std::string::npos) 5188 { 5189 tc_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string); 5190 } 5191 5192 while ((token_location = tc_string.find(token_sample_fetch)) != std::string::npos) 5193 { 5194 tc_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string); 5195 } 5196 5197 /* Set tessellation evaluation shader's body */ 5198 const char* te_body = "#version 400\n" 5199 "\n" 5200 "layout(quads) in;\n" 5201 "\n" 5202 "in int tc_te_vs_sampling_result[];\n" 5203 "in int tc_te_tc_sampling_result[];\n" 5204 "out int te_gs_vs_sampling_result;\n" 5205 "out int te_gs_tc_sampling_result;\n" 5206 "out int te_gs_te_sampling_result;\n" 5207 "out vec2 te_gs_uv;\n" 5208 "\n" 5209 "uniform float lod;\n" 5210 "uniform vec4 reference_colors[N_SAMPLES];\n" 5211 "SAMPLER_DECLARATIONS\n" 5212 "\n" 5213 "void main()\n" 5214 "{\n" 5215 " te_gs_vs_sampling_result = tc_te_vs_sampling_result[0];\n" 5216 " te_gs_tc_sampling_result = tc_te_tc_sampling_result[0];\n" 5217 " te_gs_te_sampling_result = 1;\n" 5218 "\n" 5219 /* gl_TessCoord spans from 0 to 1 for XY. To generate a screen-space quad, 5220 * we need to project these components to <-1, 1>. */ 5221 " gl_Position.xy = gl_TessCoord.xy * 2.0 - 1.0;\n" 5222 " gl_Position.zw = vec2(0, 1);\n" 5223 " te_gs_uv = vec2(gl_TessCoord.x, 1.0 - gl_TessCoord.y);\n" 5224 "\n" 5225 "\n" 5226 " const float epsilon = 1.0 / 255.0;\n" 5227 "\n" 5228 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n" 5229 " {\n" 5230 " SAMPLE_FETCH\n" 5231 "\n" 5232 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n" 5233 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n" 5234 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n" 5235 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n" 5236 " {\n" 5237 " te_gs_te_sampling_result = 0;\n" 5238 "\n" 5239 " break;\n" 5240 " }\n" 5241 " }\n" 5242 "\n" 5243 "}\n"; 5244 5245 std::string te_string = te_body; 5246 5247 while ((token_location = te_string.find(token_n_samples)) != std::string::npos) 5248 { 5249 te_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str()); 5250 } 5251 5252 while ((token_location = te_string.find(token_sampler_declarations)) != std::string::npos) 5253 { 5254 te_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string); 5255 } 5256 5257 while ((token_location = te_string.find(token_sample_fetch)) != std::string::npos) 5258 { 5259 te_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string); 5260 } 5261 5262 /* Set geometry shader's body */ 5263 const char* gs_body = "#version 400\n" 5264 "\n" 5265 "layout (triangles) in;\n" 5266 "layout (triangle_strip, max_vertices = 3) out;\n" 5267 "\n" 5268 "in int te_gs_vs_sampling_result[];\n" 5269 "in int te_gs_tc_sampling_result[];\n" 5270 "in int te_gs_te_sampling_result[];\n" 5271 "in vec2 te_gs_uv [];\n" 5272 "out int gs_fs_vs_sampling_result;\n" 5273 "out int gs_fs_tc_sampling_result;\n" 5274 "out int gs_fs_te_sampling_result;\n" 5275 "out int gs_fs_gs_sampling_result;\n" 5276 "out vec2 gs_fs_uv;\n" 5277 "\n" 5278 "uniform float lod;\n" 5279 "uniform vec4 reference_colors[N_SAMPLES];\n" 5280 "SAMPLER_DECLARATIONS\n" 5281 "\n" 5282 "void main()\n" 5283 "{\n" 5284 " const float epsilon = 1.0 / 255.0;\n" 5285 " int gs_sampling_result = 1;\n" 5286 " int tc_sampling_result = te_gs_tc_sampling_result[0] & " 5287 "te_gs_tc_sampling_result[1] & te_gs_tc_sampling_result[2];\n" 5288 " int te_sampling_result = te_gs_te_sampling_result[0] & " 5289 "te_gs_te_sampling_result[1] & te_gs_te_sampling_result[2];\n" 5290 " int vs_sampling_result = te_gs_vs_sampling_result[0] & " 5291 "te_gs_vs_sampling_result[1] & te_gs_vs_sampling_result[2];\n" 5292 "\n" 5293 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n" 5294 " {\n" 5295 " SAMPLE_FETCH;\n" 5296 "\n" 5297 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n" 5298 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n" 5299 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n" 5300 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n" 5301 " {\n" 5302 " gs_sampling_result = 0;\n" 5303 "\n" 5304 " break;\n" 5305 " }\n" 5306 " }\n" 5307 "\n" 5308 " gl_Position = gl_in[0].gl_Position;\n" 5309 " gs_fs_uv = te_gs_uv[0];\n" 5310 " gs_fs_gs_sampling_result = gs_sampling_result;\n" 5311 " gs_fs_tc_sampling_result = tc_sampling_result;\n" 5312 " gs_fs_te_sampling_result = te_sampling_result;\n" 5313 " gs_fs_vs_sampling_result = vs_sampling_result;\n" 5314 " EmitVertex();\n" 5315 "\n" 5316 " gl_Position = gl_in[1].gl_Position;\n" 5317 " gs_fs_uv = te_gs_uv[1];\n" 5318 " gs_fs_gs_sampling_result = gs_sampling_result;\n" 5319 " gs_fs_tc_sampling_result = tc_sampling_result;\n" 5320 " gs_fs_te_sampling_result = te_sampling_result;\n" 5321 " gs_fs_vs_sampling_result = vs_sampling_result;\n" 5322 " EmitVertex();\n" 5323 "\n" 5324 " gl_Position = gl_in[2].gl_Position;\n" 5325 " gs_fs_uv = te_gs_uv[2];\n" 5326 " gs_fs_gs_sampling_result = gs_sampling_result;\n" 5327 " gs_fs_tc_sampling_result = tc_sampling_result;\n" 5328 " gs_fs_te_sampling_result = te_sampling_result;\n" 5329 " gs_fs_vs_sampling_result = vs_sampling_result;\n" 5330 " EmitVertex();\n" 5331 " EndPrimitive();\n" 5332 "}\n"; 5333 5334 std::string gs_string = gs_body; 5335 5336 while ((token_location = gs_string.find(token_n_samples)) != std::string::npos) 5337 { 5338 gs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str()); 5339 } 5340 5341 while ((token_location = gs_string.find(token_sampler_declarations)) != std::string::npos) 5342 { 5343 gs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string); 5344 } 5345 5346 while ((token_location = gs_string.find(token_sample_fetch)) != std::string::npos) 5347 { 5348 gs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string); 5349 } 5350 5351 /* Set fragment shader's body */ 5352 const char* fs_body = "#version 400\n" 5353 "\n" 5354 "in vec2 gs_fs_uv;\n" 5355 "\n" 5356 "uniform float lod;\n" 5357 "uniform vec4 reference_colors[N_SAMPLES];\n" 5358 "SAMPLER_DECLARATIONS\n" 5359 "\n" 5360 "out vec4 result;\n" 5361 "\n" 5362 "void main()\n" 5363 "{\n" 5364 " const float epsilon = 1.0 / 255.0;\n" 5365 "\n" 5366 " result = vec4(1.0);\n" 5367 "\n" 5368 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n" 5369 " {\n" 5370 " SAMPLE_FETCH\n" 5371 "\n" 5372 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n" 5373 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n" 5374 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n" 5375 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n" 5376 " {\n" 5377 " result = vec4(0.0);\n" 5378 "\n" 5379 " break;\n" 5380 " }\n" 5381 " }\n" 5382 "}\n"; 5383 5384 std::string fs_string = fs_body; 5385 5386 while ((token_location = fs_string.find(token_n_samples)) != std::string::npos) 5387 { 5388 fs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str()); 5389 } 5390 5391 while ((token_location = fs_string.find(token_sampler_declarations)) != std::string::npos) 5392 { 5393 fs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string); 5394 } 5395 5396 while ((token_location = fs_string.find(token_sample_fetch)) != std::string::npos) 5397 { 5398 fs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_fs_string); 5399 } 5400 5401 /* Configure shader bodies */ 5402 const char* fs_body_raw_ptr = fs_string.c_str(); 5403 const char* gs_body_raw_ptr = gs_string.c_str(); 5404 const char* tc_body_raw_ptr = tc_string.c_str(); 5405 const char* te_body_raw_ptr = te_string.c_str(); 5406 const char* vs_body_raw_ptr = vs_string.c_str(); 5407 5408 gl.shaderSource(m_fs_id, 1 /* count */, &fs_body_raw_ptr, NULL /* length */); 5409 gl.shaderSource(m_gs_id, 1 /* count */, &gs_body_raw_ptr, NULL /* length */); 5410 gl.shaderSource(m_tc_id, 1 /* count */, &tc_body_raw_ptr, NULL /* length */); 5411 gl.shaderSource(m_te_id, 1 /* count */, &te_body_raw_ptr, NULL /* length */); 5412 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, NULL /* length */); 5413 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed."); 5414 5415 /* Compile the shaders */ 5416 const glw::GLuint so_ids[] = { m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id }; 5417 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]); 5418 5419 const glw::GLchar* shader_sources[] = { fs_body_raw_ptr, gs_body_raw_ptr, tc_body_raw_ptr, te_body_raw_ptr, 5420 vs_body_raw_ptr }; 5421 5422 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id) 5423 { 5424 glw::GLint compile_status = GL_FALSE; 5425 glw::GLint so_id = so_ids[n_so_id]; 5426 5427 gl.compileShader(so_id); 5428 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 5429 5430 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status); 5431 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 5432 5433 if (compile_status != GL_TRUE) 5434 { 5435 char temp[1024]; 5436 5437 gl.getShaderInfoLog(so_id, 1024, NULL, temp); 5438 5439 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation error log:\n" 5440 << temp << "\nShader source:\n" 5441 << shader_sources[n_so_id] << tcu::TestLog::EndMessage; 5442 5443 TCU_FAIL("Shader compilation failed"); 5444 } 5445 5446 /* Attach the shaders to the program object */ 5447 gl.attachShader(m_po_id, so_id); 5448 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed"); 5449 } /* for (all shader objects) */ 5450 5451 /* Set up XFB */ 5452 const char* varying_names[] = { "gs_fs_vs_sampling_result", "gs_fs_tc_sampling_result", "gs_fs_te_sampling_result", 5453 "gs_fs_gs_sampling_result" }; 5454 const unsigned int n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]); 5455 5456 gl.transformFeedbackVaryings(m_po_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS); 5457 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed."); 5458 5459 /* Link the program object */ 5460 glw::GLint link_status = GL_FALSE; 5461 5462 gl.linkProgram(m_po_id); 5463 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 5464 5465 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 5466 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 5467 5468 if (link_status != GL_TRUE) 5469 { 5470 TCU_FAIL("Program linking failed."); 5471 } 5472 5473 /* Retrieve uniform locations. Depending on the iteration, a number of those will be 5474 * inactive. 5475 */ 5476 m_po_lod_location = gl.getUniformLocation(m_po_id, "lod"); 5477 m_po_n_face_location = gl.getUniformLocation(m_po_id, "n_face"); 5478 m_po_reference_colors_location = gl.getUniformLocation(m_po_id, "reference_colors"); 5479 m_po_texture_location = gl.getUniformLocation(m_po_id, "texture"); 5480 m_po_z_float_location = gl.getUniformLocation(m_po_id, "z_float"); 5481 m_po_z_int_location = gl.getUniformLocation(m_po_id, "z_int"); 5482 5483 if (m_po_reference_colors_location == -1) 5484 { 5485 TCU_FAIL("reference_colors is considered an inactive uniform which is invalid."); 5486 } 5487 } 5488 5489 /** Initializes contents of a texture, from which the view texture will be created. **/ 5490 void TextureViewTestViewSampling::initParentTextureContents() 5491 { 5492 static const glw::GLenum cm_texture_targets[] = { 5493 /* NOTE: This order must match the order used for sampling CM/CMA texture targets. */ 5494 GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 5495 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 5496 }; 5497 static const unsigned int n_cm_texture_targets = sizeof(cm_texture_targets) / sizeof(cm_texture_targets[0]); 5498 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5499 5500 /* Bind the parent texture */ 5501 gl.bindTexture(m_iteration_parent_texture_target, m_to_id); 5502 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 5503 5504 /* If we're dealing with a single-sampled texture target, then we can clear the 5505 * contents of each layer/face/slice using FBO. This will unfortunately not work 5506 * for arrayed textures, layers or layer-faces of which cannot be attached to a draw 5507 * framebuffer. 5508 * If we need to update contents of a multisampled, potentially arrayed texture, 5509 * we'll need to use the filler program. 5510 **/ 5511 bool is_arrayed_texture_target = (m_iteration_parent_texture_target == GL_TEXTURE_1D_ARRAY || 5512 m_iteration_parent_texture_target == GL_TEXTURE_2D_ARRAY || 5513 m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 5514 bool is_multisampled_texture_target = (m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE || 5515 m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 5516 5517 if (!is_arrayed_texture_target && !is_multisampled_texture_target) 5518 { 5519 /* Good, no need to work with samples! */ 5520 DE_ASSERT(m_iteration_parent_texture_depth >= 1); 5521 DE_ASSERT(m_iteration_parent_texture_n_levels >= 1); 5522 5523 /* Cube-map texture target cannot be directly used for a glFramebufferTexture2D() call. Instead, 5524 * we need to split it into 6 cube-map texture targets. */ 5525 unsigned int n_texture_targets = 1; 5526 glw::GLenum texture_targets[n_cm_texture_targets] = { 5527 m_iteration_parent_texture_target, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, 5528 }; 5529 5530 if (m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP) 5531 { 5532 DE_STATIC_ASSERT(sizeof(texture_targets) == sizeof(cm_texture_targets)); 5533 memcpy(texture_targets, cm_texture_targets, sizeof(cm_texture_targets)); 5534 5535 n_texture_targets = n_cm_texture_targets; 5536 } 5537 5538 resetReferenceColorStorage(m_iteration_parent_texture_depth, /* n_layers */ 5539 n_texture_targets, /* n_faces */ 5540 m_iteration_parent_texture_n_levels, /* n_mipmaps */ 5541 1); /* n_samples */ 5542 5543 /* Iterate through all texture targets we need to update */ 5544 for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target) 5545 { 5546 const glw::GLenum texture_target = texture_targets[n_texture_target]; 5547 5548 /* Iterate through all layers of the texture. */ 5549 for (unsigned int n_layer = 0; n_layer < m_iteration_parent_texture_depth; ++n_layer) 5550 { 5551 /* ..and mip-maps, too. */ 5552 const unsigned int n_mipmaps_for_layer = (texture_target == GL_TEXTURE_3D) ? 5553 (m_iteration_parent_texture_n_levels - n_layer) : 5554 (m_iteration_parent_texture_n_levels); 5555 5556 for (unsigned int n_mipmap = 0; n_mipmap < n_mipmaps_for_layer; ++n_mipmap) 5557 { 5558 /* Use appropriate glFramebufferTexture*() API, depending on the texture target of the 5559 * parent texture. 5560 */ 5561 switch (texture_target) 5562 { 5563 case GL_TEXTURE_1D: 5564 { 5565 gl.framebufferTexture1D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_1D, m_to_id, 5566 n_mipmap); 5567 5568 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D() call failed."); 5569 break; 5570 } 5571 5572 case GL_TEXTURE_2D: 5573 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 5574 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 5575 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5576 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 5577 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 5578 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 5579 case GL_TEXTURE_RECTANGLE: 5580 { 5581 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, m_to_id, 5582 n_mipmap); 5583 5584 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 5585 break; 5586 } 5587 5588 case GL_TEXTURE_3D: 5589 { 5590 gl.framebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, m_to_id, 5591 n_mipmap, n_layer); 5592 5593 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture3D() call failed."); 5594 break; 5595 } 5596 5597 default: 5598 { 5599 TCU_FAIL("Unrecognized texture target"); 5600 } 5601 } /* switch (m_iteration_parent_texture_target) */ 5602 5603 /* Each layer/mipmap needs to be assigned an unique vec4. */ 5604 tcu::Vec4 reference_color = getRandomReferenceColor(); 5605 5606 setReferenceColor(n_layer, n_texture_target, /* n_face */ 5607 n_mipmap, 0, /* n_sample */ 5608 reference_color); 5609 5610 /* We should be OK to clear the mip-map at this point */ 5611 gl.clearColor(reference_color.x(), reference_color.y(), reference_color.z(), reference_color.w()); 5612 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed."); 5613 5614 gl.clear(GL_COLOR_BUFFER_BIT); 5615 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed."); 5616 } /* for (all mip-maps) */ 5617 } /* for (all layers) */ 5618 } /* for (all texture targets) */ 5619 } /* if (!is_arrayed_texture_target && !is_multisampled_texture_target) */ 5620 else 5621 { 5622 /* We need to handle an either multisampled or arrayed texture target or 5623 * a combination of the two. 5624 */ 5625 DE_ASSERT(m_iteration_parent_texture_target == GL_TEXTURE_1D_ARRAY || 5626 m_iteration_parent_texture_target == GL_TEXTURE_2D_ARRAY || 5627 m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE || 5628 m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || 5629 m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 5630 5631 DE_ASSERT(m_iteration_parent_texture_depth >= 1); 5632 DE_ASSERT(m_iteration_parent_texture_n_levels >= 1); 5633 5634 const unsigned int n_faces = 5635 (m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY) ? 6 /* faces */ : 1; 5636 5637 resetReferenceColorStorage(m_iteration_parent_texture_depth, /* n_layers */ 5638 n_faces, m_iteration_parent_texture_n_levels, /* n_mipmaps */ 5639 m_max_color_texture_samples_gl_value); /* n_samples */ 5640 5641 /* Set up storage for reference colors the fragment shader should use 5642 * when rendering to multisampled texture target */ 5643 float* reference_colors = new float[4 /* rgba */ * m_max_color_texture_samples_gl_value]; 5644 5645 /* Activate the filler program */ 5646 gl.useProgram(m_per_sample_filler_po_id); 5647 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 5648 5649 /* Iterate through all layers of the texture. */ 5650 for (unsigned int n_layer = 0; n_layer < m_iteration_parent_texture_depth; ++n_layer) 5651 { 5652 /* ..faces.. */ 5653 for (unsigned int n_face = 0; n_face < n_faces; ++n_face) 5654 { 5655 /* ..and mip-maps, too. */ 5656 for (unsigned int n_mipmap = 0; n_mipmap < m_iteration_parent_texture_n_levels; ++n_mipmap) 5657 { 5658 /* For all texture targets considered excl. GL_TEXTURE_2D_MULTISAMPLE, we need 5659 * to use glFramebufferTextur() to bind all layers to the color atatchment. For 5660 * 2DMS textures, we can use plain glFramebufferTexture2D(). 5661 */ 5662 if (m_iteration_parent_texture_target != GL_TEXTURE_2D_MULTISAMPLE) 5663 { 5664 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, n_mipmap); 5665 5666 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed."); 5667 } 5668 else 5669 { 5670 /* Sanity check */ 5671 DE_ASSERT(m_iteration_parent_texture_depth == 1); 5672 5673 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5674 m_iteration_parent_texture_target, m_to_id, n_mipmap); 5675 5676 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 5677 } 5678 5679 /* Generate reference colors for all samples */ 5680 const unsigned int n_samples = 5681 (is_multisampled_texture_target) ? m_max_color_texture_samples_gl_value : 1; 5682 5683 for (unsigned int n_sample = 0; n_sample < n_samples; ++n_sample) 5684 { 5685 tcu::Vec4 reference_color = getRandomReferenceColor(); 5686 5687 reference_colors[4 /* rgba */ * n_sample + 0] = reference_color.x(); 5688 reference_colors[4 /* rgba */ * n_sample + 1] = reference_color.y(); 5689 reference_colors[4 /* rgba */ * n_sample + 2] = reference_color.z(); 5690 reference_colors[4 /* rgba */ * n_sample + 3] = reference_color.w(); 5691 5692 setReferenceColor(n_layer, n_face, n_mipmap, n_sample, reference_color); 5693 } /* for (all samples) */ 5694 5695 /* Upload the reference sample colors */ 5696 gl.uniform4fv(m_per_sample_filler_po_reference_colors_location, n_samples, reference_colors); 5697 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed."); 5698 5699 /* Update the layer ID the program should render to */ 5700 const unsigned int layer_id = n_face * 6 /* faces */ + n_layer; 5701 5702 gl.uniform1i(m_per_sample_filler_po_layer_id_location, layer_id); 5703 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 5704 5705 /* Draw the full-screen quad. Geometry shader will draw the quad for us, 5706 * so all we need to do is to feed the rendering pipeline with a single 5707 * point. 5708 */ 5709 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 5710 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 5711 } /* for (all mip-maps) */ 5712 } /* for (all faces) */ 5713 } /* for (all layers) */ 5714 5715 delete[] reference_colors; 5716 } 5717 } 5718 5719 /** Initializes the 'per sample filler' program object, used to fill a multi-sample texture 5720 * with colors varying on a per-sample basis. 5721 */ 5722 void TextureViewTestViewSampling::initPerSampleFillerProgramObject() 5723 { 5724 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5725 5726 /* Sanity checks: GL_MAX_COLOR_TEXTURE_SAMPLES is not 0 */ 5727 DE_ASSERT(m_max_color_texture_samples_gl_value != 0); 5728 5729 /* Generate program and shader objects */ 5730 m_per_sample_filler_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 5731 m_per_sample_filler_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 5732 m_per_sample_filler_vs_id = gl.createShader(GL_VERTEX_SHADER); 5733 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 5734 5735 m_per_sample_filler_po_id = gl.createProgram(); 5736 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 5737 5738 /* Configure fragment shader's body */ 5739 static const char* fs_body = "#version 400\n" 5740 "\n" 5741 "uniform vec4 reference_colors[N_MAX_SAMPLES];\n" 5742 "\n" 5743 "out vec4 result;\n" 5744 "\n" 5745 "void main()\n" 5746 "{\n" 5747 " result = reference_colors[gl_SampleID];\n" 5748 "}\n"; 5749 std::string fs_body_string = fs_body; 5750 const char* fs_body_string_raw_ptr = DE_NULL; 5751 std::stringstream n_max_samples_sstream; 5752 const char* n_max_samples_token = "N_MAX_SAMPLES"; 5753 std::size_t token_location = std::string::npos; 5754 5755 n_max_samples_sstream << m_max_color_texture_samples_gl_value; 5756 5757 while ((token_location = fs_body_string.find(n_max_samples_token)) != std::string::npos) 5758 { 5759 fs_body_string.replace(token_location, strlen(n_max_samples_token), n_max_samples_sstream.str()); 5760 } 5761 5762 fs_body_string_raw_ptr = fs_body_string.c_str(); 5763 5764 gl.shaderSource(m_per_sample_filler_fs_id, 1 /* count */, &fs_body_string_raw_ptr, DE_NULL /* length */); 5765 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 5766 5767 /* Configure geometry shader's body */ 5768 static const char* gs_body = "#version 400\n" 5769 "\n" 5770 "layout(points) in;\n" 5771 "layout(triangle_strip, max_vertices = 4) out;\n" 5772 "\n" 5773 "uniform int layer_id;\n" 5774 "\n" 5775 "void main()\n" 5776 "{\n" 5777 " gl_Layer = layer_id;\n" 5778 " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 5779 " EmitVertex();\n" 5780 "\n" 5781 " gl_Layer = layer_id;\n" 5782 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 5783 " EmitVertex();\n" 5784 "\n" 5785 " gl_Layer = layer_id;\n" 5786 " gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n" 5787 " EmitVertex();\n" 5788 "\n" 5789 " gl_Layer = layer_id;\n" 5790 " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n" 5791 " EmitVertex();\n" 5792 "\n" 5793 " EndPrimitive();\n" 5794 "\n" 5795 "}\n"; 5796 5797 gl.shaderSource(m_per_sample_filler_gs_id, 1 /* count */, &gs_body, DE_NULL /* length */); 5798 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 5799 5800 /* Configure vertex shader */ 5801 static const char* vs_body = "#version 400\n" 5802 "\n" 5803 "void main()\n" 5804 "{\n" 5805 " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 5806 "}\n"; 5807 5808 gl.shaderSource(m_per_sample_filler_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */); 5809 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 5810 5811 /* Attach the shaders to the program object */ 5812 gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_fs_id); 5813 gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_gs_id); 5814 gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_vs_id); 5815 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed."); 5816 5817 /* Compile the shaders */ 5818 const glw::GLuint so_ids[] = { m_per_sample_filler_fs_id, m_per_sample_filler_gs_id, m_per_sample_filler_vs_id }; 5819 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]); 5820 5821 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id) 5822 { 5823 glw::GLint compile_status = GL_FALSE; 5824 glw::GLuint so_id = so_ids[n_so_id]; 5825 5826 gl.compileShader(so_id); 5827 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 5828 5829 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status); 5830 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiV() call failed."); 5831 5832 if (compile_status != GL_TRUE) 5833 { 5834 TCU_FAIL("Shader compilation failed."); 5835 } 5836 } /* for (all shader objects) */ 5837 5838 /* Link the program object */ 5839 glw::GLint link_status = GL_FALSE; 5840 5841 gl.linkProgram(m_per_sample_filler_po_id); 5842 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 5843 5844 gl.getProgramiv(m_per_sample_filler_po_id, GL_LINK_STATUS, &link_status); 5845 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 5846 5847 if (link_status != GL_TRUE) 5848 { 5849 TCU_FAIL("Program linking failed."); 5850 } 5851 5852 /* Retrieve uniform locations */ 5853 m_per_sample_filler_po_layer_id_location = gl.getUniformLocation(m_per_sample_filler_po_id, "layer_id"); 5854 m_per_sample_filler_po_reference_colors_location = 5855 gl.getUniformLocation(m_per_sample_filler_po_id, "reference_colors[0]"); 5856 5857 if (m_per_sample_filler_po_layer_id_location == -1) 5858 { 5859 TCU_FAIL("layer_id uniform is considered inactive which is invalid"); 5860 } 5861 5862 if (m_per_sample_filler_po_reference_colors_location == -1) 5863 { 5864 TCU_FAIL("reference_colors uniform is considered inactive which is invalid"); 5865 } 5866 } 5867 5868 /** Initializes GL objects needed to run the test (excluding iteration-specific objects) */ 5869 void TextureViewTestViewSampling::initTest() 5870 { 5871 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5872 5873 /* Generate and configure BO storage to hold result XFB data of a single 5874 * draw call. 5875 * 5876 * Each draw call outputs 6 vertices. For each vertex, 4 ints will be XFBed out. */ 5877 gl.genBuffers(1, &m_bo_id); 5878 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 5879 5880 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id); 5881 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 5882 5883 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 6 /* draw calls */ * (4 * sizeof(int)), /* as per comment */ 5884 DE_NULL, GL_STATIC_DRAW); 5885 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 5886 5887 /* Generate a FBO and bind it to both binding targets */ 5888 gl.genFramebuffers(1, &m_fbo_id); 5889 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed."); 5890 5891 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id); 5892 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed."); 5893 5894 /* Generate and bind a VAO */ 5895 gl.genVertexArrays(1, &m_vao_id); 5896 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 5897 5898 gl.bindVertexArray(m_vao_id); 5899 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 5900 5901 /* Generate and configure a texture object we will use to verify view sampling works correctly 5902 * from within a fragment shader. 5903 */ 5904 gl.genTextures(1, &m_result_to_id); 5905 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 5906 5907 gl.bindTexture(GL_TEXTURE_2D, m_result_to_id); 5908 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 5909 5910 gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, m_reference_texture_width, m_reference_texture_height); 5911 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 5912 5913 /* Determine implementation-specific GL_MAX_COLOR_TEXTURE_SAMPLES value */ 5914 gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &m_max_color_texture_samples_gl_value); 5915 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname."); 5916 5917 /* Modify pixel storage settings so that we don't rely on the default aligment setting. */ 5918 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 5919 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 5920 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed."); 5921 5922 /* Modify GL_PATCH_VERTICES setting so that a single patch consists of only a single vertex 5923 * (instead of the default 3) */ 5924 gl.patchParameteri(GL_PATCH_VERTICES, 1); 5925 GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed."); 5926 } 5927 5928 /** Initializes and sets up a texture object storage, but does not fill it 5929 * with actual content. Implements separate code paths for handling parent 5930 * & view textures. 5931 * 5932 * @param is_view_texture true if a view texture should be initialized, 5933 * false if te caller needs a parent texture. Note 5934 * that a parent texture must be initialized prior 5935 * to configuring a view texture. 5936 * @param texture_target Texture target to use for the parent texture. 5937 * @param view_texture_target Texture target to use for the view texture. 5938 **/ 5939 void TextureViewTestViewSampling::initTextureObject(bool is_view_texture, glw::GLenum texture_target, 5940 glw::GLenum view_texture_target) 5941 { 5942 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5943 unsigned int texture_depth = 0; 5944 glw::GLuint* to_id_ptr = (is_view_texture) ? &m_view_to_id : &m_to_id; 5945 5946 /* Sanity check: make sure GL_TEXTURE_BUFFER texture target is not requested. This 5947 * would be against the test specification. 5948 **/ 5949 DE_ASSERT(texture_target != GL_TEXTURE_BUFFER); 5950 DE_ASSERT(view_texture_target != GL_TEXTURE_BUFFER); 5951 5952 /* If we're going to be creating a cube-map or cube-map array texture view in this iteration, 5953 * make sure the parent or view texture's depth is valid */ 5954 if (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY) 5955 { 5956 texture_depth = 13; /* 1 + 2 * (6 faces) */ 5957 } 5958 else if (view_texture_target == GL_TEXTURE_CUBE_MAP) 5959 { 5960 texture_depth = 7; /* 1 + (6 faces) */ 5961 } 5962 else 5963 { 5964 texture_depth = m_reference_texture_depth; 5965 } 5966 5967 if (texture_target == GL_TEXTURE_CUBE_MAP_ARRAY) 5968 { 5969 texture_depth = 6 /* faces */ * 3; 5970 } 5971 5972 /* Release the texture object, as we're using immutable texture objects and would 5973 * prefer the resources not to leak. 5974 */ 5975 if (*to_id_ptr != 0) 5976 { 5977 gl.deleteTextures(1, to_id_ptr); 5978 5979 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed."); 5980 } 5981 5982 /* Generate a new texture object */ 5983 gl.genTextures(1, to_id_ptr); 5984 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 5985 5986 if (is_view_texture) 5987 { 5988 /* Determine values of arguments we'll pass to glTextureView() call */ 5989 unsigned int minlayer = 0; 5990 unsigned int minlevel = 0; 5991 unsigned int numlayers = 0; 5992 unsigned int numlevels = 2; 5993 5994 const bool is_texture_arrayed_texture_target = 5995 (texture_target == GL_TEXTURE_1D_ARRAY || texture_target == GL_TEXTURE_2D_ARRAY || 5996 texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 5997 const bool is_texture_cube_map_texture_target = (texture_target == GL_TEXTURE_CUBE_MAP); 5998 const bool is_texture_multisample_texture_target = 5999 (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 6000 const bool is_texture_rectangle_texture_target = (texture_target == GL_TEXTURE_RECTANGLE); 6001 const bool is_view_arrayed_texture_target = 6002 (view_texture_target == GL_TEXTURE_1D_ARRAY || view_texture_target == GL_TEXTURE_2D_ARRAY || 6003 view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || 6004 view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 6005 const bool is_view_cube_map_texture_target = (view_texture_target == GL_TEXTURE_CUBE_MAP); 6006 const bool is_view_cube_map_array_texture_target = (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY); 6007 6008 if (is_texture_multisample_texture_target || is_texture_rectangle_texture_target) 6009 { 6010 minlevel = 0; 6011 numlevels = 1; 6012 } 6013 else 6014 { 6015 minlevel = 1; 6016 } 6017 6018 if ((true == is_texture_arrayed_texture_target) || 6019 ((false == is_texture_cube_map_texture_target) && (true == is_view_cube_map_texture_target)) || 6020 ((false == is_texture_cube_map_texture_target) && (true == is_view_cube_map_array_texture_target))) 6021 { 6022 minlayer = 1; 6023 } 6024 else 6025 { 6026 minlayer = 0; 6027 } 6028 6029 if (!is_texture_cube_map_texture_target && is_view_cube_map_array_texture_target) 6030 { 6031 numlayers = 12; 6032 } 6033 else if (is_view_cube_map_texture_target || is_view_cube_map_array_texture_target) 6034 { 6035 numlayers = 6; 6036 } 6037 else if (is_view_arrayed_texture_target) 6038 { 6039 if (is_texture_arrayed_texture_target || is_texture_cube_map_texture_target) 6040 { 6041 numlayers = 2; 6042 } 6043 else 6044 { 6045 numlayers = 1; 6046 } 6047 } 6048 else 6049 { 6050 numlayers = 1; 6051 } 6052 6053 /* Set up view texture */ 6054 gl.textureView(*to_id_ptr, view_texture_target, m_to_id, GL_RGBA8, minlevel, numlevels, minlayer, numlayers); 6055 6056 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed."); 6057 6058 /* Store the argument values */ 6059 m_iteration_view_texture_minlayer = minlayer; 6060 m_iteration_view_texture_minlevel = minlevel; 6061 m_iteration_view_texture_numlayers = numlayers; 6062 m_iteration_view_texture_numlevels = numlevels; 6063 m_iteration_view_texture_target = view_texture_target; 6064 6065 m_testCtx.getLog() << tcu::TestLog::Message << "Created a view for texture target " 6066 << "[" << TextureViewUtilities::getTextureTargetString(view_texture_target) << "] " 6067 << "from a parent texture target " 6068 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6069 << "using arguments: " 6070 << "minlayer:[" << minlayer << "] " 6071 << "minlevel:[" << minlevel << "] " 6072 << "numlayers:[" << numlayers << "] " 6073 << "numlevels:[" << numlevels << "]." << tcu::TestLog::EndMessage; 6074 6075 gl.bindTexture(view_texture_target, *to_id_ptr); 6076 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 6077 } /* if (is_view_texture) */ 6078 else 6079 { 6080 /* Reset iteration-specific view settings */ 6081 m_iteration_parent_texture_depth = 1; 6082 m_iteration_parent_texture_height = 1; 6083 m_iteration_parent_texture_n_levels = 1; 6084 m_iteration_parent_texture_n_samples = 1; 6085 m_iteration_parent_texture_width = 1; 6086 6087 /* Initialize storage for the newly created texture object */ 6088 gl.bindTexture(texture_target, *to_id_ptr); 6089 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 6090 6091 /* Use max conformant sample count for multisample texture targets */ 6092 if (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 6093 { 6094 m_max_color_texture_samples_gl_value = getMaxConformantSampleCount(texture_target, GL_RGBA8); 6095 } 6096 else 6097 { 6098 /* Use GL_MAX_COLOR_TEXTURE_SAMPLES value for other targets */ 6099 gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &m_max_color_texture_samples_gl_value); 6100 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname."); 6101 } 6102 6103 switch (texture_target) 6104 { 6105 case GL_TEXTURE_1D: 6106 { 6107 gl.texStorage1D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width); 6108 6109 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed."); 6110 6111 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps; 6112 m_iteration_parent_texture_width = m_reference_texture_width; 6113 6114 m_testCtx.getLog() << tcu::TestLog::Message 6115 << "Created an immutable parent texture object for texture target " 6116 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6117 << "of " 6118 << "levels:[" << m_reference_texture_n_mipmaps << "] " 6119 << "width:[" << m_reference_texture_width << "]." << tcu::TestLog::EndMessage; 6120 break; 6121 } 6122 6123 case GL_TEXTURE_1D_ARRAY: 6124 { 6125 gl.texStorage2D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width, 6126 texture_depth); 6127 6128 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 6129 6130 m_iteration_parent_texture_depth = texture_depth; 6131 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps; 6132 m_iteration_parent_texture_width = m_reference_texture_width; 6133 6134 m_testCtx.getLog() << tcu::TestLog::Message 6135 << "Created an immutable parent texture object for texture target " 6136 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6137 << "of " 6138 << "depth:[" << texture_depth << "] " 6139 << "levels:[" << m_reference_texture_n_mipmaps << "] " 6140 << "width:[" << m_reference_texture_width << "]." << tcu::TestLog::EndMessage; 6141 6142 break; 6143 } 6144 6145 case GL_TEXTURE_CUBE_MAP: 6146 case GL_TEXTURE_2D: 6147 { 6148 gl.texStorage2D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width, 6149 m_reference_texture_height); 6150 6151 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 6152 6153 m_iteration_parent_texture_height = m_reference_texture_height; 6154 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps; 6155 m_iteration_parent_texture_width = m_reference_texture_width; 6156 6157 m_testCtx.getLog() << tcu::TestLog::Message 6158 << "Created an immutable parent texture object for texture target " 6159 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6160 << "of " 6161 << "levels:[" << m_reference_texture_n_mipmaps << "] " 6162 << "width:[" << m_reference_texture_width << "] " 6163 << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage; 6164 6165 break; 6166 } 6167 6168 case GL_TEXTURE_RECTANGLE: 6169 { 6170 gl.texStorage2D(texture_target, 1, /* rectangle textures do not use mip-maps */ 6171 GL_RGBA8, m_reference_texture_width, m_reference_texture_height); 6172 6173 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 6174 6175 m_iteration_parent_texture_height = m_reference_texture_height; 6176 m_iteration_parent_texture_width = m_reference_texture_width; 6177 6178 m_testCtx.getLog() << tcu::TestLog::Message 6179 << "Created an immutable parent texture object for texture target " 6180 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6181 << "of " 6182 << "levels:1 " 6183 << "width:[" << m_reference_texture_width << "] " 6184 << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage; 6185 6186 break; 6187 } 6188 6189 case GL_TEXTURE_2D_ARRAY: 6190 { 6191 gl.texStorage3D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width, 6192 m_reference_texture_height, texture_depth); 6193 6194 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed."); 6195 6196 m_iteration_parent_texture_depth = texture_depth; 6197 m_iteration_parent_texture_height = m_reference_texture_height; 6198 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps; 6199 m_iteration_parent_texture_width = m_reference_texture_width; 6200 6201 m_testCtx.getLog() << tcu::TestLog::Message 6202 << "Created an immutable parent texture object for texture target " 6203 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6204 << "of " 6205 << "depth:[" << texture_depth << "] " 6206 << "levels:[" << m_reference_texture_n_mipmaps << "] " 6207 << "width:[" << m_reference_texture_width << "] " 6208 << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage; 6209 6210 break; 6211 } 6212 6213 case GL_TEXTURE_2D_MULTISAMPLE: 6214 { 6215 gl.texStorage2DMultisample(texture_target, m_max_color_texture_samples_gl_value, GL_RGBA8, 6216 m_reference_texture_width, m_reference_texture_height, 6217 GL_TRUE); /* fixedsamplelocations */ 6218 6219 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed."); 6220 6221 m_iteration_parent_texture_height = m_reference_texture_height; 6222 m_iteration_parent_texture_n_samples = m_max_color_texture_samples_gl_value; 6223 m_iteration_parent_texture_width = m_reference_texture_width; 6224 6225 m_testCtx.getLog() << tcu::TestLog::Message 6226 << "Created an immutable parent texture object for texture target " 6227 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6228 << "of " 6229 << "samples:[" << m_max_color_texture_samples_gl_value << "] " 6230 << "width:[" << m_reference_texture_width << "] " 6231 << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage; 6232 6233 break; 6234 } 6235 6236 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 6237 { 6238 gl.texStorage3DMultisample(texture_target, m_max_color_texture_samples_gl_value, GL_RGBA8, 6239 m_reference_texture_width, m_reference_texture_height, texture_depth, 6240 GL_TRUE); /* fixed sample locations */ 6241 6242 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3DMultisample() call failed."); 6243 6244 m_iteration_parent_texture_depth = texture_depth; 6245 m_iteration_parent_texture_height = m_reference_texture_height; 6246 m_iteration_parent_texture_n_samples = m_max_color_texture_samples_gl_value; 6247 m_iteration_parent_texture_width = m_reference_texture_width; 6248 6249 m_testCtx.getLog() << tcu::TestLog::Message 6250 << "Created an immutable parent texture object for texture target " 6251 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6252 << "of " 6253 << "samples:[" << m_max_color_texture_samples_gl_value << "] " 6254 << "width:[" << m_reference_texture_width << "] " 6255 << "height:[" << m_reference_texture_height << "] " 6256 << "depth:[" << texture_depth << "]." << tcu::TestLog::EndMessage; 6257 6258 break; 6259 } 6260 6261 case GL_TEXTURE_3D: 6262 case GL_TEXTURE_CUBE_MAP_ARRAY: 6263 { 6264 gl.texStorage3D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width, 6265 m_reference_texture_height, texture_depth); 6266 6267 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed."); 6268 6269 m_iteration_parent_texture_depth = texture_depth; 6270 m_iteration_parent_texture_height = m_reference_texture_height; 6271 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps; 6272 m_iteration_parent_texture_width = m_reference_texture_width; 6273 6274 m_testCtx.getLog() << tcu::TestLog::Message 6275 << "Created an immutable parent texture object for texture target " 6276 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] " 6277 << "of " 6278 << "levels:[" << m_reference_texture_n_mipmaps << "] " 6279 << "width:[" << m_reference_texture_width << "] " 6280 << "height:[" << m_reference_texture_height << "] " 6281 << "depth:[" << texture_depth << "]." << tcu::TestLog::EndMessage; 6282 6283 break; 6284 } 6285 6286 default: 6287 { 6288 TCU_FAIL("Unrecognized texture target."); 6289 } 6290 } /* switch (texture_target) */ 6291 6292 m_iteration_parent_texture_target = texture_target; 6293 } 6294 6295 /* Configure texture filtering */ 6296 if (texture_target != GL_TEXTURE_2D_MULTISAMPLE && texture_target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY && 6297 texture_target != GL_TEXTURE_RECTANGLE) 6298 { 6299 gl.texParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 6300 gl.texParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 6301 6302 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed."); 6303 } 6304 } 6305 6306 /** Executes test iteration. 6307 * 6308 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 6309 */ 6310 tcu::TestNode::IterateResult TextureViewTestViewSampling::iterate() 6311 { 6312 bool has_failed = false; 6313 6314 /* Make sure GL_ARB_texture_view is reported as supported before carrying on 6315 * with actual execution */ 6316 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions(); 6317 6318 if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end()) 6319 { 6320 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported"); 6321 } 6322 6323 /* Initialize all objects required to run the test */ 6324 initTest(); 6325 6326 /* Initialize per-sample filler program */ 6327 initPerSampleFillerProgramObject(); 6328 6329 /* Iterate through all texture/view texture target combinations */ 6330 TextureViewUtilities::_compatible_texture_target_pairs_const_iterator texture_target_iterator; 6331 TextureViewUtilities::_compatible_texture_target_pairs texture_target_pairs = 6332 TextureViewUtilities::getLegalTextureAndViewTargetCombinations(); 6333 6334 for (texture_target_iterator = texture_target_pairs.begin(); texture_target_iterator != texture_target_pairs.end(); 6335 ++texture_target_iterator) 6336 { 6337 const glw::GLenum parent_texture_target = texture_target_iterator->first; 6338 const glw::GLenum view_texture_target = texture_target_iterator->second; 6339 6340 /* Initialize parent texture */ 6341 initTextureObject(false /* is_view_texture */, parent_texture_target, view_texture_target); 6342 6343 /* Initialize view */ 6344 initTextureObject(true /* is_view_texture */, parent_texture_target, view_texture_target); 6345 6346 /* Initialize contents of the parent texture */ 6347 initParentTextureContents(); 6348 6349 /* Initialize iteration-specific test program object */ 6350 initIterationSpecificProgramObject(); 6351 6352 /* Run the actual test */ 6353 bool status = executeTest(); 6354 6355 if (!status) 6356 { 6357 has_failed = true; 6358 6359 m_testCtx.getLog() << tcu::TestLog::Message << "Test case failed." << tcu::TestLog::EndMessage; 6360 } 6361 else 6362 { 6363 m_testCtx.getLog() << tcu::TestLog::Message << "Test case succeeded." << tcu::TestLog::EndMessage; 6364 } 6365 } 6366 6367 if (!has_failed) 6368 { 6369 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 6370 } 6371 else 6372 { 6373 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 6374 } 6375 6376 return STOP; 6377 } 6378 6379 /** De-allocates existing reference color storage (if one already exists) and 6380 * allocates a new one using user-provided properties. 6381 * 6382 * @param n_layers Amount of layers to consider. Use a value of 1 for non-arrayed 6383 * texture targets. 6384 * @param n_faces Amount of faces to consider. Use a value of 1 for non-CM 6385 * texture targets. 6386 * @param n_mipmaps Amount of mip-maps to consider. Use a value of 1 for non-mipmapped 6387 * texture targets. 6388 * @param n_samples Amount of samples to consider. Use a value of 1 for single-sampled 6389 * texture targets. 6390 **/ 6391 void TextureViewTestViewSampling::resetReferenceColorStorage(unsigned int n_layers, unsigned int n_faces, 6392 unsigned int n_mipmaps, unsigned int n_samples) 6393 { 6394 /* Sanity checks */ 6395 DE_ASSERT(n_layers >= 1); 6396 DE_ASSERT(n_faces >= 1); 6397 DE_ASSERT(n_mipmaps >= 1); 6398 DE_ASSERT(n_samples >= 1); 6399 6400 /* Allocate the descriptor if it's the first time the test will be 6401 * attempting to access it */ 6402 if (m_reference_color_storage == DE_NULL) 6403 { 6404 m_reference_color_storage = new _reference_color_storage(n_faces, n_layers, n_mipmaps, n_samples); 6405 } 6406 else 6407 { 6408 /* The descriptor's already there so we only need to update the properties */ 6409 m_reference_color_storage->n_faces = n_faces; 6410 m_reference_color_storage->n_layers = n_layers; 6411 m_reference_color_storage->n_mipmaps = n_mipmaps; 6412 m_reference_color_storage->n_samples = n_samples; 6413 } 6414 6415 /* If there's any data descriptor found allocated at this point, 6416 * release it */ 6417 if (m_reference_color_storage->data != DE_NULL) 6418 { 6419 delete[] m_reference_color_storage->data; 6420 6421 m_reference_color_storage->data = DE_NULL; 6422 } 6423 6424 m_reference_color_storage->data = new tcu::Vec4[n_layers * n_faces * n_mipmaps * n_samples]; 6425 } 6426 6427 /** Assigns user-specified reference color to a specific sample of a layer/face's mip-map. 6428 * 6429 * This function throws an assertion failure if the requested layer/face/mip-map/sample index 6430 * is invalid. 6431 * 6432 * @param n_layer Layer index to use for the association. Use a value of 0 for non-arrayed texture 6433 * targets. 6434 * @param n_face Face index to use for the association. Use a value of 0 for non-CM texture targets. 6435 * @param n_mipmap Mip-map index to use for the association. Use a value of 0 for non-mipmapped texture 6436 * targets. 6437 * @param n_sample Sample index to use for the association. Use a value of 0 for single-sampled texture 6438 * targets. 6439 * @param color Color to associate with the specified sample. 6440 **/ 6441 void TextureViewTestViewSampling::setReferenceColor(unsigned int n_layer, unsigned int n_face, unsigned int n_mipmap, 6442 unsigned int n_sample, tcu::Vec4 color) 6443 { 6444 DE_ASSERT(m_reference_color_storage != DE_NULL); 6445 if (m_reference_color_storage != DE_NULL) 6446 { 6447 DE_ASSERT(n_face < m_reference_color_storage->n_faces); 6448 DE_ASSERT(n_layer < m_reference_color_storage->n_layers); 6449 DE_ASSERT(n_mipmap < m_reference_color_storage->n_mipmaps); 6450 DE_ASSERT(n_sample < m_reference_color_storage->n_samples); 6451 6452 /* Hierarchy is: 6453 * 6454 * layers -> faces -> mipmaps -> samples */ 6455 const unsigned int index = 6456 n_layer * (m_reference_color_storage->n_faces * m_reference_color_storage->n_mipmaps * 6457 m_reference_color_storage->n_samples) + 6458 n_face * (m_reference_color_storage->n_mipmaps * m_reference_color_storage->n_samples) + 6459 n_mipmap * (m_reference_color_storage->n_samples) + n_sample; 6460 6461 m_reference_color_storage->data[index] = color; 6462 } 6463 } 6464 6465 /** Constructor. 6466 * 6467 * @param context Rendering context. 6468 **/ 6469 TextureViewTestViewClasses::TextureViewTestViewClasses(deqp::Context& context) 6470 : TestCase(context, "view_classes", "Verifies view sampling works correctly. Tests all valid" 6471 " texture/view internalformat combinations.") 6472 , m_bo_id(0) 6473 , m_po_id(0) 6474 , m_to_id(0) 6475 , m_to_temp_id(0) 6476 , m_vao_id(0) 6477 , m_view_to_id(0) 6478 , m_vs_id(0) 6479 , m_decompressed_mipmap_data(DE_NULL) 6480 , m_mipmap_data(DE_NULL) 6481 , m_bo_size(0) 6482 , m_has_test_failed(false) 6483 , m_texture_height(4) 6484 , m_texture_unit_for_parent_texture(GL_TEXTURE0) 6485 , m_texture_unit_for_view_texture(GL_TEXTURE1) 6486 , m_texture_width(4) 6487 , m_view_data_offset(0) 6488 { 6489 /* Left blank on purpose */ 6490 } 6491 6492 /** Deinitializes all buffers and GL objects that may have been created 6493 * during test execution. Also restores GL state that may have been modified. 6494 **/ 6495 void TextureViewTestViewClasses::deinit() 6496 { 6497 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6498 6499 if (m_bo_id != 0) 6500 { 6501 gl.deleteBuffers(1, &m_bo_id); 6502 6503 m_bo_id = 0; 6504 } 6505 6506 if (m_decompressed_mipmap_data != DE_NULL) 6507 { 6508 delete[] m_decompressed_mipmap_data; 6509 6510 m_decompressed_mipmap_data = DE_NULL; 6511 } 6512 6513 if (m_mipmap_data != DE_NULL) 6514 { 6515 delete[] m_mipmap_data; 6516 6517 m_mipmap_data = DE_NULL; 6518 } 6519 6520 if (m_po_id != 0) 6521 { 6522 gl.deleteProgram(m_po_id); 6523 6524 m_po_id = 0; 6525 } 6526 6527 if (m_to_id != 0) 6528 { 6529 gl.deleteTextures(1, &m_to_id); 6530 6531 m_to_id = 0; 6532 } 6533 6534 if (m_to_temp_id != 0) 6535 { 6536 gl.deleteTextures(1, &m_to_temp_id); 6537 6538 m_to_temp_id = 0; 6539 } 6540 6541 if (m_vao_id != 0) 6542 { 6543 gl.deleteVertexArrays(1, &m_vao_id); 6544 6545 m_vao_id = 0; 6546 } 6547 6548 if (m_view_to_id != 0) 6549 { 6550 gl.deleteTextures(1, &m_view_to_id); 6551 6552 m_view_to_id = 0; 6553 } 6554 6555 if (m_vs_id != 0) 6556 { 6557 gl.deleteShader(m_vs_id); 6558 6559 m_vs_id = 0; 6560 } 6561 6562 /* Bring back the default pixel storage settings that the test may have modified. */ 6563 gl.pixelStorei(GL_PACK_ALIGNMENT, 4); 6564 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4); 6565 6566 /* Restore rasterization */ 6567 gl.enable(GL_RASTERIZER_DISCARD); 6568 } 6569 6570 /** Reads user-specified amount of components and stores it in user-provided location, 6571 * according to user-defined format (snorm, unorm, etc.) and component size. 6572 * 6573 * This function assumes component sizes are aligned on by boundary (that is: size % 8 6574 * equals 0 for all components). An assertion failure will occur if this requirement is 6575 * not met. 6576 * This function throws TestError exception if any of the requested component sizes 6577 * or format is not supported. 6578 * 6579 * @param data Raw data buffer to read the data from. 6580 * @param n_components Amount of components to read. 6581 * @param component_sizes 4 ints subsequently defining component size for R/G/B/A channels. 6582 * Must not be NULL. 6583 * @param format Format to be used for data retrieval. This defines data format of 6584 * the underlying components (for instance: for UNORMs we need to 6585 * divide the read ubyte/ushort/uint data by maximum value allowed for 6586 * the type minus one) 6587 * @param result Location to store the read components. Must not be NULL. Must be 6588 * large enough to hold requested amount of components of user-specified 6589 * component size. 6590 * 6591 **/ 6592 void TextureViewTestViewClasses::getComponentDataForByteAlignedInternalformat(const unsigned char* data, 6593 const unsigned int n_components, 6594 const unsigned int* component_sizes, 6595 const _format format, void* result) 6596 { 6597 float* result_float = (float*)result; 6598 signed int* result_sint = (signed int*)result; 6599 unsigned int* result_uint = (unsigned int*)result; 6600 6601 /* Sanity checks: we assume the components are aligned on byte boundary. */ 6602 DE_ASSERT((component_sizes[0] % 8) == 0 && (component_sizes[1] % 8) == 0 && (component_sizes[2] % 8) == 0 && 6603 (component_sizes[3] % 8) == 0); 6604 6605 for (unsigned int n_component = 0; n_component < n_components; 6606 data += (component_sizes[n_component] >> 3 /* 8 bits/byte */), ++n_component) 6607 { 6608 switch (format) 6609 { 6610 case FORMAT_FLOAT: 6611 { 6612 switch (component_sizes[n_component]) 6613 { 6614 case 16: 6615 result_float[n_component] = deFloat16To32(*(const deFloat16*)data); 6616 break; 6617 case 32: 6618 result_float[n_component] = *(float*)data; 6619 break; 6620 6621 default: 6622 TCU_FAIL("Unsupported component size"); 6623 } 6624 6625 break; 6626 } 6627 6628 case FORMAT_SIGNED_INTEGER: 6629 { 6630 switch (component_sizes[n_component]) 6631 { 6632 case 8: 6633 result_sint[n_component] = *(signed char*)data; 6634 break; 6635 case 16: 6636 result_sint[n_component] = *(signed short*)data; 6637 break; 6638 case 32: 6639 result_sint[n_component] = *(signed int*)data; 6640 break; 6641 6642 default: 6643 TCU_FAIL("Unsupported component size"); 6644 } 6645 6646 break; 6647 } 6648 6649 case FORMAT_SNORM: 6650 { 6651 switch (component_sizes[n_component]) 6652 { 6653 case 8: 6654 result_float[n_component] = float(*(signed char*)data) / 127.0f; 6655 break; 6656 case 16: 6657 result_float[n_component] = float(*(signed short*)data) / 32767.0f; 6658 break; 6659 6660 default: 6661 TCU_FAIL("Unsupported component size"); 6662 } 6663 6664 if (result_float[n_component] < -1.0f) 6665 { 6666 result_float[n_component] = -1.0f; 6667 } 6668 6669 break; 6670 } 6671 6672 case FORMAT_UNORM: 6673 { 6674 switch (component_sizes[n_component]) 6675 { 6676 case 8: 6677 result_float[n_component] = float(*((unsigned char*)data)) / 255.0f; 6678 break; 6679 case 16: 6680 result_float[n_component] = float(*((unsigned short*)data)) / 65535.0f; 6681 break; 6682 6683 default: 6684 TCU_FAIL("Unsupported component size"); 6685 } 6686 6687 break; 6688 } 6689 6690 case FORMAT_UNSIGNED_INTEGER: 6691 { 6692 switch (component_sizes[n_component]) 6693 { 6694 case 8: 6695 result_uint[n_component] = *(unsigned char*)data; 6696 break; 6697 case 16: 6698 result_uint[n_component] = *(unsigned short*)data; 6699 break; 6700 case 32: 6701 result_uint[n_component] = *(unsigned int*)data; 6702 break; 6703 6704 default: 6705 TCU_FAIL("Unsupported component size"); 6706 } 6707 6708 break; 6709 } 6710 6711 default: 6712 { 6713 TCU_FAIL("Unrecognized mip-map format"); 6714 } 6715 } /* switch (view_format) */ 6716 } /* for (all components) */ 6717 } 6718 6719 /** Initializes buffer object storage of sufficient size to hold data that will be 6720 * XFBed out by the test's vertex shader, given user-specified parent texture & 6721 * view's internalformats. 6722 * 6723 * Throws TestError exceptions if GL calls fail. 6724 * 6725 * @param texture_internalformat Internalformat used by the parent texture object, 6726 * from which the view will be created. 6727 * @param view_internalformat Internalformat that will be used by the texture view. 6728 **/ 6729 void TextureViewTestViewClasses::initBufferObject(glw::GLenum texture_internalformat, glw::GLenum view_internalformat) 6730 { 6731 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6732 6733 /* Calculate how much size we will need to read the XFBed data. Each sampled data 6734 * will either end up stored in a vecX, ivecX or uvecX (where X stands for amount 6735 * of components supported by considered internalformat), so we can assume it will 6736 * take a sizeof(float) = sizeof(int) = sizeof(unsigned int) 6737 */ 6738 const unsigned int parent_texture_n_components = 6739 TextureViewUtilities::getAmountOfComponentsForInternalformat(texture_internalformat); 6740 const unsigned int view_texture_n_components = 6741 TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat); 6742 6743 /* Configure buffer object storage. 6744 * 6745 * NOTE: We do not care about the data type of the stored data, since sizes of the 6746 * types we're interested in (floats, ints and uints) match. 6747 */ 6748 DE_ASSERT(sizeof(float) == sizeof(unsigned int) && sizeof(float) == sizeof(int)); 6749 6750 m_bo_size = 6751 static_cast<unsigned int>(parent_texture_n_components * sizeof(float) * m_texture_height * m_texture_width + 6752 view_texture_n_components * sizeof(float) * m_texture_height * m_texture_width); 6753 6754 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_size, DE_NULL, /* data */ 6755 GL_STATIC_DRAW); 6756 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 6757 6758 /* For XFB, we'll be outputting data sampled from both the texture and the view. 6759 * Sampled texture data will go to the first half of the buffer, and the corresponding 6760 * view data will go to the one half. 6761 * 6762 * Store the offset, from which the view's data will start so that we can correctly 6763 * configure buffer object bindings in initProgramObject() 6764 **/ 6765 m_view_data_offset = 6766 static_cast<unsigned int>(parent_texture_n_components * sizeof(float) * m_texture_height * m_texture_width); 6767 } 6768 6769 /** Initializes a program object that should be used for the test, given 6770 * user-specified texture and view internalformats. 6771 * 6772 * @param texture_internalformat Internalformat used by the parent texture object, 6773 * from which the view will be created. 6774 * @param view_internalformat Internalformat that will be used by the texture view. 6775 **/ 6776 void TextureViewTestViewClasses::initProgramObject(glw::GLenum texture_internalformat, glw::GLenum view_internalformat) 6777 { 6778 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6779 6780 /* Determine which samplers we should be using for sampling both textures */ 6781 const unsigned int texture_n_components = 6782 TextureViewUtilities::getAmountOfComponentsForInternalformat(texture_internalformat); 6783 const _sampler_type texture_sampler_type = 6784 TextureViewUtilities::getSamplerTypeForInternalformat(texture_internalformat); 6785 const char* texture_sampler_data_type_glsl = 6786 TextureViewUtilities::getGLSLDataTypeForSamplerType(texture_sampler_type, texture_n_components); 6787 const char* texture_sampler_glsl = TextureViewUtilities::getGLSLTypeForSamplerType(texture_sampler_type); 6788 const char* texture_swizzle_glsl = 6789 (texture_n_components == 4) ? "xyzw" : 6790 (texture_n_components == 3) ? "xyz" : (texture_n_components == 2) ? "xy" : "x"; 6791 const unsigned int view_n_components = 6792 TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat); 6793 const _sampler_type view_sampler_type = TextureViewUtilities::getSamplerTypeForInternalformat(view_internalformat); 6794 const char* view_sampler_data_type_glsl = 6795 TextureViewUtilities::getGLSLDataTypeForSamplerType(view_sampler_type, view_n_components); 6796 const char* view_sampler_glsl = TextureViewUtilities::getGLSLTypeForSamplerType(view_sampler_type); 6797 const char* view_swizzle_glsl = 6798 (view_n_components == 4) ? "xyzw" : (view_n_components == 3) ? "xyz" : (view_n_components == 2) ? "xy" : "x"; 6799 6800 /* Form vertex shader body */ 6801 const char* token_texture_data_type = "TEXTURE_DATA_TYPE"; 6802 const char* token_texture_sampler = "TEXTURE_SAMPLER"; 6803 const char* token_texture_swizzle = "TEXTURE_SWIZZLE"; 6804 const char* token_view_data_type = "VIEW_DATA_TYPE"; 6805 const char* token_view_sampler = "VIEW_SAMPLER"; 6806 const char* token_view_swizzle = "VIEW_SWIZZLE"; 6807 const char* vs_template_body = "#version 400\n" 6808 "\n" 6809 "uniform TEXTURE_SAMPLER texture;\n" 6810 "uniform VIEW_SAMPLER view;\n" 6811 "\n" 6812 "out TEXTURE_DATA_TYPE out_texture_data;\n" 6813 "out VIEW_DATA_TYPE out_view_data;\n" 6814 "\n" 6815 "void main()\n" 6816 "{\n" 6817 " ivec2 uv = ivec2(gl_VertexID % 4,\n" 6818 " gl_VertexID / 4);\n" 6819 "\n" 6820 " out_texture_data = texelFetch(texture, uv, 0).TEXTURE_SWIZZLE;\n" 6821 " out_view_data = texelFetch(view, uv, 0).VIEW_SWIZZLE;\n" 6822 "}\n"; 6823 6824 std::size_t token_position = std::string::npos; 6825 std::string vs_body = vs_template_body; 6826 6827 while ((token_position = vs_body.find(token_texture_data_type)) != std::string::npos) 6828 { 6829 vs_body.replace(token_position, strlen(token_texture_data_type), texture_sampler_data_type_glsl); 6830 } 6831 6832 while ((token_position = vs_body.find(token_texture_sampler)) != std::string::npos) 6833 { 6834 vs_body.replace(token_position, strlen(token_texture_sampler), texture_sampler_glsl); 6835 } 6836 6837 while ((token_position = vs_body.find(token_texture_swizzle)) != std::string::npos) 6838 { 6839 vs_body.replace(token_position, strlen(token_texture_swizzle), texture_swizzle_glsl); 6840 } 6841 6842 while ((token_position = vs_body.find(token_view_data_type)) != std::string::npos) 6843 { 6844 vs_body.replace(token_position, strlen(token_view_data_type), view_sampler_data_type_glsl); 6845 } 6846 6847 while ((token_position = vs_body.find(token_view_sampler)) != std::string::npos) 6848 { 6849 vs_body.replace(token_position, strlen(token_view_sampler), view_sampler_glsl); 6850 } 6851 6852 while ((token_position = vs_body.find(token_view_swizzle)) != std::string::npos) 6853 { 6854 vs_body.replace(token_position, strlen(token_view_swizzle), view_swizzle_glsl); 6855 } 6856 6857 /* Compile the shader */ 6858 glw::GLint compile_status = GL_FALSE; 6859 const char* vs_body_raw_ptr = vs_body.c_str(); 6860 6861 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */); 6862 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 6863 6864 gl.compileShader(m_vs_id); 6865 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 6866 6867 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status); 6868 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 6869 6870 if (compile_status != GL_TRUE) 6871 { 6872 TCU_FAIL("Shader compilation failed"); 6873 } 6874 6875 /* Configure test program object for XFB */ 6876 const char* varying_names[] = { "out_texture_data", "out_view_data" }; 6877 const unsigned int n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]); 6878 6879 gl.transformFeedbackVaryings(m_po_id, n_varying_names, varying_names, GL_SEPARATE_ATTRIBS); 6880 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed."); 6881 6882 /* Configure buffer object bindings for XFB */ 6883 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index for 'out_texture_data' */ 6884 m_bo_id, 0, /* offset */ 6885 m_view_data_offset); /* size */ 6886 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 1, /* index for 'out_view_data' */ 6887 m_bo_id, m_view_data_offset, /* offset */ 6888 m_bo_size - m_view_data_offset); /* size */ 6889 6890 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange() call(s) failed."); 6891 6892 /* Link the program object */ 6893 glw::GLint link_status = GL_FALSE; 6894 6895 gl.linkProgram(m_po_id); 6896 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 6897 6898 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 6899 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 6900 6901 if (link_status != GL_TRUE) 6902 { 6903 TCU_FAIL("Program linking failed."); 6904 } 6905 6906 /* Configure sampler uniforms */ 6907 glw::GLint texture_uniform_location = gl.getUniformLocation(m_po_id, "texture"); 6908 glw::GLint view_uniform_location = gl.getUniformLocation(m_po_id, "view"); 6909 6910 if (texture_uniform_location == -1) 6911 { 6912 TCU_FAIL("'texture' uniform is considered inactive which is invalid"); 6913 } 6914 6915 if (view_uniform_location == -1) 6916 { 6917 TCU_FAIL("'view' uniform is considered inactive which is invalid"); 6918 } 6919 6920 gl.useProgram(m_po_id); 6921 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 6922 6923 gl.uniform1i(texture_uniform_location, m_texture_unit_for_parent_texture - GL_TEXTURE0); 6924 gl.uniform1i(view_uniform_location, m_texture_unit_for_view_texture - GL_TEXTURE0); 6925 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call(s) failed."); 6926 } 6927 6928 /** Creates GL objects required to run the test, as well as modifies GL 6929 * configuration (pixel pack/unpack settings, enables 'rasterizer discard' mode) 6930 * in order for the test to run properly. 6931 **/ 6932 void TextureViewTestViewClasses::initTest() 6933 { 6934 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6935 6936 /* Generate objects that will be used by all test iterations. 6937 * 6938 * Note that we're not generating texture objects here. This is owing to the fact 6939 * we'll be using immutable textures and it makes more sense to generate the objects 6940 * in initTexture() instead. 6941 **/ 6942 gl.genBuffers(1, &m_bo_id); 6943 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 6944 6945 m_po_id = gl.createProgram(); 6946 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 6947 6948 gl.genVertexArrays(1, &m_vao_id); 6949 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 6950 6951 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 6952 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 6953 6954 /* Attach the vertex shader to the program object */ 6955 gl.attachShader(m_po_id, m_vs_id); 6956 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 6957 6958 /* Configure general buffer object binding. Indiced bindings will be configured 6959 * in initProgramObject() 6960 */ 6961 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id); 6962 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 6963 6964 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id); 6965 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 6966 6967 /* Bind the VAO */ 6968 gl.bindVertexArray(m_vao_id); 6969 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 6970 6971 /* Modify pack & unpack alignment settings */ 6972 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 6973 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 6974 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed."); 6975 6976 /* Disable rasterizatino */ 6977 gl.enable(GL_RASTERIZER_DISCARD); 6978 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed."); 6979 } 6980 6981 /** Generates and initializes storage of either the parent texture object or the 6982 * texture view, using user-specified internalformat. 6983 * 6984 * @param should_init_parent_texture true to initialize parent texture object storage, 6985 * false to configure texture view. 6986 * @param internalformat Internalformat to use for the process. 6987 * @param viewformat Internalformat that will be used by "view" texture. 6988 * 6989 **/ 6990 void TextureViewTestViewClasses::initTextureObject(bool should_init_parent_texture, glw::GLenum texture_internalformat, 6991 glw::GLenum view_internalformat) 6992 { 6993 glw::GLenum cached_view_internalformat = view_internalformat; 6994 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6995 glw::GLuint* to_id_ptr = (should_init_parent_texture) ? &m_to_id : &m_view_to_id; 6996 6997 /* If the object we're about to initialize has already been created, delete it first. */ 6998 if (*to_id_ptr != 0) 6999 { 7000 gl.deleteTextures(1, to_id_ptr); 7001 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed."); 7002 7003 *to_id_ptr = 0; 7004 } 7005 7006 /* Generate a new texture object */ 7007 gl.genTextures(1, to_id_ptr); 7008 7009 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 7010 7011 /* Initialize the object */ 7012 if (should_init_parent_texture) 7013 { 7014 gl.bindTexture(GL_TEXTURE_2D, *to_id_ptr); 7015 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 7016 7017 gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */ 7018 texture_internalformat, m_texture_width, m_texture_height); 7019 7020 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 7021 } 7022 else 7023 { 7024 gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, view_internalformat, 0, /* minlevel */ 7025 1, /* numlevels */ 7026 0, /* minlayer */ 7027 1); /* numlayers */ 7028 7029 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed."); 7030 7031 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id); 7032 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 7033 } 7034 7035 if (should_init_parent_texture) 7036 { 7037 /* We need to fill the base mip-map with actual contents. Calculate how much 7038 * data we will need to fill a 4x4 mip-map, given the requested internalformat. 7039 */ 7040 bool is_internalformat_compressed = TextureViewUtilities::isInternalformatCompressed(texture_internalformat); 7041 glw::GLenum internalformat_to_use = GL_NONE; 7042 7043 if (is_internalformat_compressed) 7044 { 7045 /* In order to initialize texture objects defined with a compressed internalformat 7046 * using raw decompressed data, we need to override caller-specified internalformat 7047 * with an internalformat that will describe decompressed data. The data will then 7048 * be converted by GL to the compressed internalformat that was used for the previous 7049 * glTexStorage2D() call. 7050 **/ 7051 _format format = TextureViewUtilities::getFormatOfInternalformat(texture_internalformat); 7052 7053 if (format == FORMAT_FLOAT) 7054 { 7055 internalformat_to_use = GL_RGBA32F; 7056 } 7057 else 7058 { 7059 DE_ASSERT(format == FORMAT_UNORM || format == FORMAT_SNORM); 7060 7061 internalformat_to_use = GL_RGBA8; 7062 } 7063 7064 view_internalformat = internalformat_to_use; 7065 } 7066 else 7067 { 7068 internalformat_to_use = texture_internalformat; 7069 } 7070 7071 /* Allocate the buffer. 7072 * 7073 * NOTE: This buffer is used in verifyResults(). When no longer needed, it will either 7074 * be deallocated there or in deinit(). 7075 **/ 7076 glw::GLenum format_to_use = TextureViewUtilities::getGLFormatOfInternalformat(internalformat_to_use); 7077 glw::GLenum type_to_use = TextureViewUtilities::getTypeCompatibleWithInternalformat(internalformat_to_use); 7078 const glw::GLenum view_type = TextureViewUtilities::getTypeCompatibleWithInternalformat(view_internalformat); 7079 7080 /* For some internalformats, we need to use a special data type in order to avoid 7081 * implicit data conversion during glTexSubImage2D() call. 7082 */ 7083 switch (texture_internalformat) 7084 { 7085 case GL_R11F_G11F_B10F: 7086 type_to_use = GL_UNSIGNED_INT_10F_11F_11F_REV; 7087 break; 7088 case GL_RGB9_E5: 7089 type_to_use = GL_UNSIGNED_INT_5_9_9_9_REV; 7090 break; 7091 case GL_RGB10_A2: 7092 type_to_use = GL_UNSIGNED_INT_2_10_10_10_REV; 7093 break; 7094 7095 /* Fall-through for other internalformats! */ 7096 } /* switch (texture_internalformat) */ 7097 7098 /* Carry on */ 7099 const unsigned int mipmap_raw_size = TextureViewUtilities::getTextureDataSize( 7100 internalformat_to_use, type_to_use, m_texture_width, m_texture_height); 7101 7102 if (m_mipmap_data != NULL) 7103 { 7104 delete[] m_mipmap_data; 7105 7106 m_mipmap_data = NULL; 7107 } 7108 7109 m_mipmap_data = new unsigned char[mipmap_raw_size]; 7110 7111 /* Prepare data for texture */ 7112 memset(m_mipmap_data, 0, mipmap_raw_size); 7113 7114 switch (view_type) 7115 { 7116 case GL_BYTE: 7117 { 7118 glw::GLbyte* buffer = (glw::GLbyte*)m_mipmap_data; 7119 const glw::GLuint n_total_components = mipmap_raw_size / 1; 7120 7121 for (glw::GLuint i = 0; i < n_total_components; ++i) 7122 { 7123 buffer[i] = static_cast<glw::GLbyte>(i - 128); 7124 } 7125 7126 break; 7127 } 7128 7129 case GL_SHORT: 7130 { 7131 glw::GLshort* buffer = (glw::GLshort*)m_mipmap_data; 7132 const glw::GLuint n_total_components = mipmap_raw_size / 2; 7133 7134 for (glw::GLuint i = 0; i < n_total_components; ++i) 7135 { 7136 buffer[i] = static_cast<glw::GLshort>(i - 0xC000); // 0xC000 = (fp16) -2 makes this non de-norm 7137 } 7138 7139 break; 7140 } 7141 7142 case GL_INT: 7143 { 7144 glw::GLint* buffer = (glw::GLint*)m_mipmap_data; 7145 const glw::GLuint n_total_components = mipmap_raw_size / 4; 7146 7147 for (glw::GLuint i = 0; i < n_total_components; ++i) 7148 { 7149 buffer[i] = i - 128; 7150 } 7151 7152 break; 7153 } 7154 7155 case GL_UNSIGNED_BYTE: 7156 { 7157 glw::GLubyte* buffer = (glw::GLubyte*)m_mipmap_data; 7158 const glw::GLuint n_total_components = mipmap_raw_size / 1; 7159 7160 for (glw::GLuint i = 0; i < n_total_components; ++i) 7161 { 7162 buffer[i] = static_cast<glw::GLubyte>(i); 7163 } 7164 7165 break; 7166 } 7167 7168 case GL_UNSIGNED_SHORT: 7169 { 7170 glw::GLushort* buffer = (glw::GLushort*)m_mipmap_data; 7171 const glw::GLuint n_total_components = mipmap_raw_size / 2; 7172 7173 for (glw::GLuint i = 0; i < n_total_components; ++i) 7174 { 7175 buffer[i] = static_cast<glw::GLushort>(i); 7176 } 7177 7178 break; 7179 } 7180 7181 case GL_UNSIGNED_INT: 7182 { 7183 glw::GLuint* buffer = (glw::GLuint*)m_mipmap_data; 7184 const glw::GLuint n_total_components = mipmap_raw_size / 4; 7185 7186 for (glw::GLuint i = 0; i < n_total_components; ++i) 7187 { 7188 buffer[i] = i; 7189 } 7190 7191 break; 7192 } 7193 7194 case GL_UNSIGNED_INT_24_8: 7195 { 7196 glw::GLuint* buffer = (glw::GLuint*)m_mipmap_data; 7197 const glw::GLuint n_total_components = mipmap_raw_size / 4; 7198 7199 for (glw::GLuint i = 0; i < n_total_components; ++i) 7200 { 7201 buffer[i] = (i << 8) | (0xaa); 7202 } 7203 7204 break; 7205 } 7206 7207 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 7208 { 7209 glw::GLfloat* float_buffer = (glw::GLfloat*)m_mipmap_data; 7210 const glw::GLuint n_total_components = mipmap_raw_size / 8; 7211 glw::GLuint* uint_buffer = (glw::GLuint*)(m_mipmap_data + 4); 7212 7213 for (glw::GLuint i = 0; i < n_total_components; ++i) 7214 { 7215 float_buffer[i * 2] = (float)i - 128; 7216 uint_buffer[i * 2] = (i << 8) | (0xaa); 7217 } 7218 7219 break; 7220 } 7221 7222 case GL_HALF_FLOAT: 7223 { 7224 tcu::Float16* buffer = (tcu::Float16*)m_mipmap_data; 7225 const glw::GLuint n_total_components = mipmap_raw_size / 2; 7226 7227 for (glw::GLuint i = 0; i < n_total_components; ++i) 7228 { 7229 float value = (float)i - 128; 7230 7231 buffer[i] = (tcu::Float16)value; 7232 } 7233 7234 break; 7235 } 7236 7237 case GL_FLOAT: 7238 { 7239 glw::GLfloat* float_buffer = (glw::GLfloat*)m_mipmap_data; 7240 const glw::GLuint n_total_components = mipmap_raw_size / 4; 7241 7242 float offset = (cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) ? 0.0f : -128.0f; 7243 for (glw::GLuint i = 0; i < n_total_components; ++i) 7244 { 7245 float_buffer[i] = (float)i + offset; 7246 } 7247 7248 break; 7249 } 7250 7251 case GL_UNSIGNED_INT_2_10_10_10_REV: 7252 { 7253 glw::GLuint* buffer = (glw::GLuint*)m_mipmap_data; 7254 const glw::GLuint n_total_components = mipmap_raw_size / 4; 7255 7256 for (glw::GLuint i = 0; i < n_total_components; ++i) 7257 { 7258 buffer[i] = i | (i << 8) | (i << 16); 7259 } 7260 7261 break; 7262 } 7263 7264 default: 7265 { 7266 TCU_FAIL("Unrecognized texture view type"); 7267 } 7268 } /* switch (view_type) */ 7269 7270 /* BPTC_FLOAT view class is a special case that needs an extra step. Signed and 7271 * unsigned internal formats use different encodings, so instead of passing 7272 * "regular" 32-bit floating-point data, we need to convert the values we initialized 7273 * above to an actual BPTC representation. Since the encodings differ, we should 7274 * compress these values using the internalformat that we will be later using for the 7275 * texture view. 7276 */ 7277 unsigned int imageSize_to_use = 0; 7278 bool use_glCompressedTexSubImage2D_call = false; 7279 7280 if ((cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT || 7281 cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) && 7282 cached_view_internalformat != texture_internalformat) 7283 { 7284 /* Create a temporary texture object we'll use to compress the floating-point data. */ 7285 gl.genTextures(1, &m_to_temp_id); 7286 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 7287 7288 gl.bindTexture(GL_TEXTURE_2D, m_to_temp_id); 7289 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 7290 7291 /* Initialize compressed storage */ 7292 gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */ 7293 cached_view_internalformat, m_texture_width, m_texture_height); 7294 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 7295 7296 /* Submit floating-point decompressed data */ 7297 gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */ 7298 0, /* xoffset */ 7299 0, /* yoffset */ 7300 m_texture_width, m_texture_height, GL_RGB, GL_FLOAT, m_mipmap_data); 7301 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed."); 7302 7303 /* Extract the compressed version */ 7304 gl.getCompressedTexImage(GL_TEXTURE_2D, 0, /* level */ 7305 m_mipmap_data); 7306 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage() call failed."); 7307 7308 /* Delete the temporary texture object */ 7309 gl.deleteTextures(1, &m_to_temp_id); 7310 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed."); 7311 7312 m_to_temp_id = 0; 7313 7314 /* Revert to previous 2D texture binding */ 7315 gl.bindTexture(GL_TEXTURE_2D, m_to_id); 7316 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 7317 7318 /* Make sure upcoming glCompressedTexSubImage2D() call is made with sensible arguments */ 7319 imageSize_to_use = (unsigned int)ceil((float)m_texture_width / 4.0f) * 7320 (unsigned int)ceil((float)m_texture_height / 4.0f) * 16; /* block size */ 7321 use_glCompressedTexSubImage2D_call = true; 7322 } 7323 7324 /* Fill the mip-map with data */ 7325 if (use_glCompressedTexSubImage2D_call) 7326 { 7327 gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, /* level */ 7328 0, /* xoffset */ 7329 0, /* yoffset */ 7330 m_texture_width, m_texture_height, texture_internalformat, imageSize_to_use, 7331 m_mipmap_data); 7332 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexSubImage2D() call failed."); 7333 } 7334 else 7335 { 7336 gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */ 7337 0, /* xoffset */ 7338 0, /* yoffset */ 7339 m_texture_width, m_texture_height, format_to_use, type_to_use, m_mipmap_data); 7340 7341 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed."); 7342 } 7343 } 7344 7345 /* Make sure the texture object is complete */ 7346 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); 7347 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 7348 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 7349 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 7350 GL_NEAREST); /* we're using texelFetch() so no mipmaps needed */ 7351 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 7352 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 7353 7354 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed."); 7355 } 7356 7357 /** Executes test iteration. 7358 * 7359 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 7360 */ 7361 tcu::TestNode::IterateResult TextureViewTestViewClasses::iterate() 7362 { 7363 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7364 7365 /* Only execute the test if GL_ARB_texture_view is supported */ 7366 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view")) 7367 { 7368 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported, skipping."); 7369 } 7370 7371 /* Create all GL objects required to run the test */ 7372 initTest(); 7373 7374 /* Iterate through all valid "texture internalformat + view internalformat" combinations */ 7375 TextureViewUtilities::_compatible_internalformat_pairs_const_iterator internalformat_combination_iterator; 7376 TextureViewUtilities::_compatible_internalformat_pairs internalformat_combinations = 7377 TextureViewUtilities::getLegalTextureAndViewInternalformatCombinations(); 7378 7379 for (internalformat_combination_iterator = internalformat_combinations.begin(); 7380 internalformat_combination_iterator != internalformat_combinations.end(); 7381 internalformat_combination_iterator++) 7382 { 7383 TextureViewUtilities::_internalformat_pair internalformat_pair = *internalformat_combination_iterator; 7384 glw::GLenum texture_internalformat = internalformat_pair.first; 7385 glw::GLenum view_internalformat = internalformat_pair.second; 7386 7387 /* Initialize parent texture object storage */ 7388 initTextureObject(true, /* should_init_parent_texture */ 7389 texture_internalformat, view_internalformat); 7390 7391 /* Create the texture view */ 7392 initTextureObject(false, /* should_init_parent_texture */ 7393 texture_internalformat, view_internalformat); 7394 7395 /* Initialize buffer object storage so that it's large enough to 7396 * hold the result data. 7397 **/ 7398 initBufferObject(texture_internalformat, view_internalformat); 7399 7400 /* Create the program object we'll use for the test */ 7401 initProgramObject(texture_internalformat, view_internalformat); 7402 7403 /* Configure texture bindings */ 7404 gl.activeTexture(m_texture_unit_for_parent_texture); 7405 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed."); 7406 7407 gl.bindTexture(GL_TEXTURE_2D, m_to_id); 7408 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 7409 7410 gl.activeTexture(m_texture_unit_for_view_texture); 7411 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed."); 7412 7413 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id); 7414 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 7415 7416 /* Run the test program */ 7417 gl.beginTransformFeedback(GL_POINTS); 7418 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 7419 { 7420 gl.drawArrays(GL_POINTS, 0 /* first */, m_texture_width * m_texture_height); 7421 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 7422 } 7423 gl.endTransformFeedback(); 7424 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 7425 7426 /* Retrieve the results */ 7427 const unsigned char* result_bo_data_ptr = 7428 (const unsigned char*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 7429 const unsigned char* result_texture_data_ptr = result_bo_data_ptr; 7430 const unsigned char* result_view_data_ptr = result_bo_data_ptr + m_view_data_offset; 7431 7432 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 7433 7434 /* Verify the retrieved values are valid */ 7435 verifyResultData(texture_internalformat, view_internalformat, result_texture_data_ptr, result_view_data_ptr); 7436 7437 /* Unmap the buffer object */ 7438 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 7439 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 7440 } /* for (all internalformat combinations) */ 7441 7442 if (m_has_test_failed) 7443 { 7444 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 7445 } 7446 else 7447 { 7448 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 7449 } 7450 7451 return STOP; 7452 } 7453 7454 /** Verifies the data XFBed out by the test's vertex shader is valid. 7455 * 7456 * @param texture_internalformat Internalformat that was used to define storage 7457 * of the parent texture object. 7458 * @param view_internalformat Internalformat that was used to define texture 7459 * view. 7460 * @param texture_data_ptr Data, as XFBed out by the vertex shader, that was 7461 * built by texelFetch() calls operating on the parent 7462 * texture object. 7463 * @param view_data_ptr Data, as XFBed out by the vertex shader, that was 7464 * built by texelFetch() calls operating on the texture 7465 * view. 7466 * 7467 **/ 7468 void TextureViewTestViewClasses::verifyResultData(glw::GLenum texture_internalformat, glw::GLenum view_internalformat, 7469 const unsigned char* texture_data_ptr, 7470 const unsigned char* view_data_ptr) 7471 { 7472 const char* texture_internalformat_string = TextureViewUtilities::getInternalformatString(texture_internalformat); 7473 const char* view_internalformat_string = TextureViewUtilities::getInternalformatString(view_internalformat); 7474 7475 /* For quite a number of cases, we can do a plain memcmp() applied to sampled texture/view data. 7476 * If both buffers are a match, we're OK. 7477 */ 7478 bool has_failed = false; 7479 const unsigned char* mipmap_data = DE_NULL; 7480 7481 if (memcmp(texture_data_ptr, view_data_ptr, m_view_data_offset) != 0) 7482 { 7483 /* Iterate over all texel components. 7484 * 7485 * The approach we're taking here works as follows: 7486 * 7487 * 1) Calculate what values should be sampled for each component using input mipmap 7488 * data. 7489 * 2) Compare the reference values against the values returned when sampling the view. 7490 * 7491 * Note that in step 2) we're dealing with data that is returned by float/int/uint samplers, 7492 * so we need to additionally process the data that we obtain by "casting" input data to 7493 * the view's internalformat before we can perform the comparison. 7494 * 7495 * Finally, if the reference values are calculated for compressed data, we decompress it 7496 * to GL_R8/GL_RG8/GL_RGB8/GL_RGBA8 internalformat first, depending on how many components 7497 * the compressed internalformat supports. 7498 **/ 7499 bool can_continue = true; 7500 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7501 7502 /* Determine a few important properties first */ 7503 const bool is_view_internalformat_compressed = 7504 TextureViewUtilities::isInternalformatCompressed(view_internalformat); 7505 unsigned int n_bits_per_view_texel = 0; 7506 7507 const unsigned int n_view_components = 7508 TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat); 7509 _format texture_format = TextureViewUtilities::getFormatOfInternalformat(texture_internalformat); 7510 7511 unsigned int view_component_sizes[4] = { 0 }; 7512 _format view_format = TextureViewUtilities::getFormatOfInternalformat(view_internalformat); 7513 7514 if (!is_view_internalformat_compressed) 7515 { 7516 TextureViewUtilities::getComponentSizeForInternalformat(view_internalformat, view_component_sizes); 7517 7518 n_bits_per_view_texel = 7519 view_component_sizes[0] + view_component_sizes[1] + view_component_sizes[2] + view_component_sizes[3]; 7520 } 7521 else 7522 { 7523 if (texture_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT || 7524 texture_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) 7525 { 7526 /* Each component of decompressed data will be retrieved as a 32-bit FP */ 7527 for (unsigned int n_component = 0; n_component < n_view_components; ++n_component) 7528 { 7529 view_component_sizes[n_component] = 32 /* bits per byte */; 7530 } 7531 7532 n_bits_per_view_texel = 32 /* bits per byte */ * n_view_components; 7533 } 7534 else 7535 { 7536 /* Each component of decompressed data is stored as either signed or unsigned 7537 * byte. */ 7538 for (unsigned int n_component = 0; n_component < n_view_components; ++n_component) 7539 { 7540 view_component_sizes[n_component] = 8 /* bits per byte */; 7541 } 7542 7543 n_bits_per_view_texel = 8 /* bits per byte */ * n_view_components; 7544 } 7545 } 7546 7547 /* If we need to use compressed data as reference, we need to ask GL to decompress 7548 * the mipmap data using view-specific internalformat. 7549 */ 7550 mipmap_data = m_mipmap_data; 7551 7552 if (is_view_internalformat_compressed) 7553 { 7554 /* Deallocate the buffer if necessary just in case */ 7555 if (m_decompressed_mipmap_data != DE_NULL) 7556 { 7557 delete[] m_decompressed_mipmap_data; 7558 7559 m_decompressed_mipmap_data = DE_NULL; 7560 } 7561 7562 m_decompressed_mipmap_data = 7563 new unsigned char[m_texture_width * m_texture_height * (n_bits_per_view_texel >> 3)]; 7564 7565 glw::GLuint reference_tex_id = m_to_id; 7566 if (texture_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT || 7567 texture_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) 7568 { 7569 // Encodings of SIGNED and UNSIGNED BPTC compressed texture are not compatible 7570 // even though they are in the same view class. Since the "view" texture contains 7571 // the correct encoding for the results we use that as a reference instead of the 7572 // incompatible parent encoded. 7573 reference_tex_id = m_view_to_id; 7574 } 7575 gl.bindTexture(GL_TEXTURE_2D, reference_tex_id); 7576 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 7577 7578 gl.getTexImage(GL_TEXTURE_2D, 0, /* level */ 7579 (n_view_components == 4) ? 7580 GL_RGBA : 7581 (n_view_components == 3) ? GL_RGB : (n_view_components == 2) ? GL_RG : GL_RED, 7582 (texture_format == FORMAT_SNORM) ? 7583 GL_BYTE : 7584 (texture_format == FORMAT_FLOAT) ? GL_FLOAT : GL_UNSIGNED_BYTE, 7585 m_decompressed_mipmap_data); 7586 7587 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage() call failed."); 7588 7589 mipmap_data = m_decompressed_mipmap_data; 7590 } 7591 7592 for (unsigned int n_texel = 0; n_texel < m_texture_height * m_texture_width && can_continue; ++n_texel) 7593 { 7594 /* NOTE: Vertex shader stores the sampled contents of a view texture as a 7595 * vec4/ivec4/uvec4. This means that each comonent in view_data_ptr 7596 * always takes sizeof(float) = sizeof(int) = sizeof(uint) bytes. 7597 * 7598 * NOTE: We cast input mip-map's data to view's internalformat, which is 7599 * why we're assuming each components takes n_bits_per_view_texel 7600 * bits instead of n_bits_per_mipmap_texel. 7601 */ 7602 const unsigned char* mipmap_texel_data = 7603 mipmap_data + (n_bits_per_view_texel >> 3 /* 8 bits/byte */) * n_texel; 7604 float reference_components_float[4] = { 0 }; 7605 signed int reference_components_int[4] = { 0 }; 7606 unsigned int reference_components_uint[4] = { 0 }; 7607 float view_components_float[4] = { 0 }; 7608 signed int view_components_int[4] = { 0 }; 7609 unsigned int view_components_uint[4] = { 0 }; 7610 _sampler_type view_sampler_type = 7611 TextureViewUtilities::getSamplerTypeForInternalformat(view_internalformat); 7612 const unsigned char* view_texel_data = view_data_ptr + sizeof(float) * n_view_components * n_texel; 7613 7614 /* Retrieve data sampled from the view */ 7615 for (unsigned int n_component = 0; n_component < n_view_components; 7616 view_texel_data += sizeof(float), /* as per comment */ 7617 ++n_component) 7618 { 7619 switch (view_sampler_type) 7620 { 7621 case SAMPLER_TYPE_FLOAT: 7622 { 7623 view_components_float[n_component] = *((float*)view_texel_data); 7624 7625 break; 7626 } 7627 7628 case SAMPLER_TYPE_SIGNED_INTEGER: 7629 { 7630 view_components_int[n_component] = *((signed int*)view_texel_data); 7631 7632 break; 7633 } 7634 7635 case SAMPLER_TYPE_UNSIGNED_INTEGER: 7636 { 7637 view_components_uint[n_component] = *((unsigned int*)view_texel_data); 7638 7639 break; 7640 } 7641 7642 default: 7643 { 7644 TCU_FAIL("Unrecognized sampler type"); 7645 } 7646 } /* switch (view_sampler_type) */ 7647 } /* for (all components) */ 7648 7649 /* Compute reference data. Handle non-byte aligned internalformats manually. */ 7650 if (view_internalformat == GL_R11F_G11F_B10F) 7651 { 7652 const unsigned int* reference_data = (unsigned int*)mipmap_texel_data; 7653 const unsigned int red_component = (*reference_data) & ((1 << 11) - 1); 7654 const unsigned int green_component = (*reference_data >> 11) & ((1 << 11) - 1); 7655 const unsigned int blue_component = (*reference_data >> 22) & ((1 << 10) - 1); 7656 7657 if (view_sampler_type == SAMPLER_TYPE_FLOAT) 7658 { 7659 reference_components_float[0] = Float11(red_component).asFloat(); 7660 reference_components_float[1] = Float11(green_component).asFloat(); 7661 reference_components_float[2] = Float10(blue_component).asFloat(); 7662 } 7663 else 7664 { 7665 TCU_FAIL("Internal error: invalid sampler type requested"); 7666 } 7667 } 7668 else if (view_internalformat == GL_RGB9_E5) 7669 { 7670 /* Refactored version of tcuTexture.cpp::unpackRGB999E5() */ 7671 const unsigned int* reference_data = (unsigned int*)mipmap_texel_data; 7672 const unsigned int exponent = (*reference_data >> 27) & ((1 << 5) - 1); 7673 const unsigned int red_component = (*reference_data) & ((1 << 9) - 1); 7674 const unsigned int green_component = (*reference_data >> 9) & ((1 << 9) - 1); 7675 const unsigned int blue_component = (*reference_data >> 18) & ((1 << 9) - 1); 7676 7677 float shared_exponent = 7678 deFloatPow(2.0f, (float)((int)exponent - 15 /* exponent bias */ - 9 /* mantissa */)); 7679 7680 if (view_sampler_type == SAMPLER_TYPE_FLOAT) 7681 { 7682 reference_components_float[0] = float(red_component) * shared_exponent; 7683 reference_components_float[1] = float(green_component) * shared_exponent; 7684 reference_components_float[2] = float(blue_component) * shared_exponent; 7685 } 7686 else 7687 { 7688 TCU_FAIL("Internal error: invalid sampler type requested"); 7689 } 7690 } 7691 else if (view_internalformat == GL_RGB10_A2) 7692 { 7693 unsigned int* reference_data = (unsigned int*)mipmap_texel_data; 7694 const unsigned int mask_rgb = (1 << 10) - 1; 7695 const unsigned int mask_a = (1 << 2) - 1; 7696 7697 if (view_sampler_type == SAMPLER_TYPE_FLOAT) 7698 { 7699 reference_components_float[0] = float(((*reference_data)) & (mask_rgb)) / float(mask_rgb); 7700 reference_components_float[1] = float(((*reference_data) >> 10) & (mask_rgb)) / float(mask_rgb); 7701 reference_components_float[2] = float(((*reference_data) >> 20) & (mask_rgb)) / float(mask_rgb); 7702 reference_components_float[3] = float(((*reference_data) >> 30) & (mask_a)) / float(mask_a); 7703 } 7704 else 7705 { 7706 TCU_FAIL("Internal error: invalid sampler type requested"); 7707 } 7708 } 7709 else if (view_internalformat == GL_RGB10_A2UI) 7710 { 7711 unsigned int* reference_data = (unsigned int*)mipmap_texel_data; 7712 const unsigned int mask_rgb = (1 << 10) - 1; 7713 const unsigned int mask_a = (1 << 2) - 1; 7714 7715 if (view_sampler_type == SAMPLER_TYPE_UNSIGNED_INTEGER) 7716 { 7717 reference_components_uint[0] = ((*reference_data)) & (mask_rgb); 7718 reference_components_uint[1] = ((*reference_data) >> 10) & (mask_rgb); 7719 reference_components_uint[2] = ((*reference_data) >> 20) & (mask_rgb); 7720 reference_components_uint[3] = ((*reference_data) >> 30) & (mask_a); 7721 } 7722 else 7723 { 7724 TCU_FAIL("Internal error: invalid sampler type requested"); 7725 } 7726 } 7727 else if (view_internalformat == GL_RG16F) 7728 { 7729 unsigned short* reference_data = (unsigned short*)mipmap_texel_data; 7730 7731 if (view_sampler_type == SAMPLER_TYPE_FLOAT) 7732 { 7733 reference_components_float[0] = tcu::Float16(*(reference_data + 0)).asFloat(); 7734 reference_components_float[1] = tcu::Float16(*(reference_data + 1)).asFloat(); 7735 } 7736 else 7737 { 7738 TCU_FAIL("Internal error: invalid sampler type requested"); 7739 } 7740 } 7741 else 7742 { 7743 void* result_data = NULL; 7744 7745 switch (view_sampler_type) 7746 { 7747 case SAMPLER_TYPE_FLOAT: 7748 result_data = reference_components_float; 7749 break; 7750 case SAMPLER_TYPE_SIGNED_INTEGER: 7751 result_data = reference_components_int; 7752 break; 7753 case SAMPLER_TYPE_UNSIGNED_INTEGER: 7754 result_data = reference_components_uint; 7755 break; 7756 7757 default: 7758 TCU_FAIL("Unrecognized sampler type"); 7759 } 7760 7761 getComponentDataForByteAlignedInternalformat(mipmap_texel_data, n_view_components, view_component_sizes, 7762 view_format, result_data); 7763 } 7764 7765 for (unsigned int n_component = 0; n_component < n_view_components; ++n_component) 7766 { 7767 /* If view texture operates on sRGB color space, we need to adjust our 7768 * reference value so that it is moved back into linear space. 7769 */ 7770 if (TextureViewUtilities::isInternalformatSRGB(view_internalformat) && 7771 !TextureViewUtilities::isInternalformatSRGB(texture_internalformat)) 7772 { 7773 DE_ASSERT(view_sampler_type == SAMPLER_TYPE_FLOAT); 7774 7775 /* Convert as per (8.14) from GL4.4 spec. Exclude alpha channel. */ 7776 if (n_component != 3) 7777 { 7778 if (reference_components_float[n_component] <= 0.04045f) 7779 { 7780 reference_components_float[n_component] /= 12.92f; 7781 } 7782 else 7783 { 7784 reference_components_float[n_component] = 7785 deFloatPow((reference_components_float[n_component] + 0.055f) / 1.055f, 2.4f); 7786 } 7787 } /* if (n_component != 3) */ 7788 } /* if (TextureViewUtilities::isInternalformatSRGB(view_internalformat) ) */ 7789 7790 /* Compare the reference and view texture values */ 7791 const float epsilon_float = 1.0f / float((1 << (view_component_sizes[n_component] - 1)) - 1); 7792 const signed int epsilon_int = 1; 7793 const unsigned int epsilon_uint = 1; 7794 7795 switch (view_sampler_type) 7796 { 7797 case SAMPLER_TYPE_FLOAT: 7798 { 7799 if (de::abs(reference_components_float[n_component] - view_components_float[n_component]) > 7800 epsilon_float) 7801 { 7802 has_failed = true; 7803 } 7804 7805 break; 7806 } 7807 7808 case SAMPLER_TYPE_SIGNED_INTEGER: 7809 { 7810 signed int larger_value = 0; 7811 signed int smaller_value = 0; 7812 7813 if (reference_components_int[n_component] > view_components_int[n_component]) 7814 { 7815 larger_value = reference_components_int[n_component]; 7816 smaller_value = view_components_int[n_component]; 7817 } 7818 else 7819 { 7820 smaller_value = reference_components_int[n_component]; 7821 larger_value = view_components_int[n_component]; 7822 } 7823 7824 if ((larger_value - smaller_value) > epsilon_int) 7825 { 7826 has_failed = true; 7827 } 7828 7829 break; 7830 } 7831 7832 case SAMPLER_TYPE_UNSIGNED_INTEGER: 7833 { 7834 unsigned int larger_value = 0; 7835 unsigned int smaller_value = 0; 7836 7837 if (reference_components_uint[n_component] > view_components_uint[n_component]) 7838 { 7839 larger_value = reference_components_uint[n_component]; 7840 smaller_value = view_components_uint[n_component]; 7841 } 7842 else 7843 { 7844 smaller_value = reference_components_uint[n_component]; 7845 larger_value = view_components_uint[n_component]; 7846 } 7847 7848 if ((larger_value - smaller_value) > epsilon_uint) 7849 { 7850 has_failed = true; 7851 } 7852 7853 break; 7854 } 7855 7856 default: 7857 TCU_FAIL("Unrecognized sampler type"); 7858 } /* switch (view_sampler_type) */ 7859 7860 if (has_failed) 7861 { 7862 can_continue = false; 7863 7864 switch (view_sampler_type) 7865 { 7866 case SAMPLER_TYPE_FLOAT: 7867 { 7868 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data sampled from a texture view " 7869 "[" 7870 << view_internalformat_string << "]" 7871 " created from a texture object" 7872 "[" 7873 << texture_internalformat_string << "]" 7874 " at texel " 7875 "(" 7876 << (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height) 7877 << "): expected:(" << reference_components_float[0] << ", " 7878 << reference_components_float[1] << ", " << reference_components_float[2] 7879 << ", " << reference_components_float[3] << ") found:(" 7880 << view_components_float[0] << ", " << view_components_float[1] << ", " 7881 << view_components_float[2] << ", " << view_components_float[3] << ")." 7882 << tcu::TestLog::EndMessage; 7883 7884 break; 7885 } 7886 7887 case SAMPLER_TYPE_SIGNED_INTEGER: 7888 { 7889 m_testCtx.getLog() 7890 << tcu::TestLog::Message << "Invalid data sampled from a signed integer texture view " 7891 "[" 7892 << view_internalformat_string << "]" 7893 " created from a texture object" 7894 "[" 7895 << texture_internalformat_string << "]" 7896 " at texel " 7897 "(" 7898 << (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height) << "): expected:(" 7899 << reference_components_int[0] << ", " << reference_components_int[1] << ", " 7900 << reference_components_int[2] << ", " << reference_components_int[3] << ") found:(" 7901 << view_components_int[0] << ", " << view_components_int[1] << ", " 7902 << view_components_int[2] << ", " << view_components_int[3] << ")." 7903 << tcu::TestLog::EndMessage; 7904 7905 break; 7906 } 7907 7908 case SAMPLER_TYPE_UNSIGNED_INTEGER: 7909 { 7910 m_testCtx.getLog() 7911 << tcu::TestLog::Message << "Invalid data sampled from an unsigned integer texture view " 7912 "[" 7913 << view_internalformat_string << "]" 7914 " created from a texture object" 7915 "[" 7916 << texture_internalformat_string << "]" 7917 " at texel " 7918 "(" 7919 << (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height) << "): expected:(" 7920 << reference_components_uint[0] << ", " << reference_components_uint[1] << ", " 7921 << reference_components_uint[2] << ", " << reference_components_uint[3] << ") found:(" 7922 << view_components_uint[0] << ", " << view_components_uint[1] << ", " 7923 << view_components_uint[2] << ", " << view_components_uint[3] << ")." 7924 << tcu::TestLog::EndMessage; 7925 7926 break; 7927 } 7928 7929 default: 7930 TCU_FAIL("Unrecognized sampler type"); 7931 } /* switch (view_sampler_type) */ 7932 7933 break; 7934 } /* if (has_failed) */ 7935 } /* for (all components) */ 7936 } /* for (all texels) */ 7937 } /* if (memcmp(texture_data_ptr, view_data_ptr, m_view_data_offset) != 0) */ 7938 7939 if (has_failed) 7940 { 7941 /* Log detailed information about the failure */ 7942 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data read from a view of internalformat " 7943 << "[" << view_internalformat_string << "]" 7944 << " created from a texture of internalformat " 7945 << "[" << texture_internalformat_string << "]" 7946 << ". Byte streams follow:" << tcu::TestLog::EndMessage; 7947 7948 /* Form texture and view data strings */ 7949 std::stringstream mipmap_data_sstream; 7950 std::stringstream sampled_view_data_sstream; 7951 7952 mipmap_data_sstream.fill('0'); 7953 sampled_view_data_sstream.fill('0'); 7954 7955 mipmap_data_sstream.width(2); 7956 sampled_view_data_sstream.width(2); 7957 7958 mipmap_data_sstream << "Mip-map data: ["; 7959 sampled_view_data_sstream << "Sampled view data: ["; 7960 7961 for (unsigned int n = 0; n < m_view_data_offset; ++n) 7962 { 7963 mipmap_data_sstream << "0x" << std::hex << (int)(mipmap_data[n]); 7964 sampled_view_data_sstream << "0x" << std::hex << (int)(view_data_ptr[n]); 7965 7966 if (n != (m_view_data_offset - 1)) 7967 { 7968 mipmap_data_sstream << "|"; 7969 sampled_view_data_sstream << "|"; 7970 } 7971 else 7972 { 7973 mipmap_data_sstream << "]"; 7974 sampled_view_data_sstream << "]"; 7975 } 7976 } 7977 7978 sampled_view_data_sstream << "\n"; 7979 mipmap_data_sstream << "\n"; 7980 7981 /* Log both strings */ 7982 m_testCtx.getLog() << tcu::TestLog::Message << mipmap_data_sstream.str() << sampled_view_data_sstream.str() 7983 << tcu::TestLog::EndMessage; 7984 7985 /* Do not fail the test at this point. Instead, raise a failure flag that will 7986 * cause the test to fail once all iterations execute */ 7987 m_has_test_failed = true; 7988 } 7989 else 7990 { 7991 m_testCtx.getLog() << tcu::TestLog::Message << "Correct data read from a view of internalformat " 7992 << "[" << view_internalformat_string << "]" 7993 << " created from a texture of internalformat " 7994 << "[" << texture_internalformat_string << "]" << tcu::TestLog::EndMessage; 7995 } 7996 } 7997 7998 /** Constructor. 7999 * 8000 * @param context Rendering context. 8001 * 8002 **/ 8003 TextureViewTestCoherency::TextureViewTestCoherency(deqp::Context& context) 8004 : TestCase(context, "coherency", "Verifies view/parent texture coherency") 8005 , m_are_images_supported(false) 8006 , m_bo_id(0) 8007 , m_draw_fbo_id(0) 8008 , m_gradient_verification_po_id(0) 8009 , m_gradient_verification_po_sample_exact_uv_location(-1) 8010 , m_gradient_verification_po_lod_location(-1) 8011 , m_gradient_verification_po_texture_location(-1) 8012 , m_gradient_verification_vs_id(0) 8013 , m_gradient_image_write_image_size_location(-1) 8014 , m_gradient_image_write_po_id(0) 8015 , m_gradient_image_write_vs_id(0) 8016 , m_gradient_write_po_id(0) 8017 , m_gradient_write_fs_id(0) 8018 , m_gradient_write_vs_id(0) 8019 , m_read_fbo_id(0) 8020 , m_static_to_id(0) 8021 , m_to_id(0) 8022 , m_vao_id(0) 8023 , m_view_to_id(0) 8024 , m_verification_po_expected_color_location(-1) 8025 , m_verification_po_lod_location(-1) 8026 , m_verification_po_id(0) 8027 , m_verification_vs_id(0) 8028 , m_static_texture_height(1) 8029 , m_static_texture_width(1) 8030 , m_texture_height(64) 8031 , m_texture_n_components(4) 8032 , m_texture_n_levels(7) 8033 , m_texture_width(64) 8034 { 8035 /* Initialize static color that will be used for some of the cases */ 8036 m_static_color_byte[0] = 100; 8037 m_static_color_byte[1] = 0; 8038 m_static_color_byte[2] = 255; 8039 m_static_color_byte[3] = 200; 8040 8041 m_static_color_float[0] = float(m_static_color_byte[0]) / 255.0f; 8042 m_static_color_float[1] = float(m_static_color_byte[1]) / 255.0f; 8043 m_static_color_float[2] = float(m_static_color_byte[2]) / 255.0f; 8044 m_static_color_float[3] = float(m_static_color_byte[3]) / 255.0f; 8045 } 8046 8047 /** Verifies that texture/view & view/texture coherency requirement is met 8048 * when glTexSubImage2D() or glBlitFramebuffer() API calls are used to modify 8049 * the contents of one of the mip-maps. The function does not use any memory 8050 * barriers as these are not required for the objects to stay synchronised. 8051 * 8052 * Throws TestError exceptionif the GL implementation fails the check. 8053 * 8054 * @param texture_type Defines whether it should be parent texture or 8055 * its view that the writing operation should be 8056 * performed against. The reading operation will 8057 * be issued against the sibling object. 8058 * @param should_use_glTexSubImage2D true if glTexSubImage2D() should be used for the 8059 * check, false to use glBlitFramebuffer(). 8060 * 8061 **/ 8062 void TextureViewTestCoherency::checkAPICallCoherency(_texture_type texture_type, bool should_use_glTexSubImage2D) 8063 { 8064 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8065 unsigned int write_to_height = 0; 8066 unsigned int write_to_width = 0; 8067 glw::GLuint write_to_id = 0; 8068 8069 getWritePropertiesForTextureType(texture_type, &write_to_id, &write_to_width, &write_to_height); 8070 8071 if (should_use_glTexSubImage2D) 8072 { 8073 /* Update texture binding for texture unit 0, given the texture type the caller wants 8074 * us to test. We'll need the binding set appropriately for the subsequent 8075 * glTexSubImage2D() call. 8076 */ 8077 gl.activeTexture(GL_TEXTURE0); 8078 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed."); 8079 8080 gl.bindTexture(GL_TEXTURE_2D, write_to_id); 8081 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 8082 } 8083 else 8084 { 8085 /* To perform a blit operation, we need to configure draw & read FBO, taking 8086 * the tested texture type into account. */ 8087 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_draw_fbo_id); 8088 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id); 8089 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call(s) failed."); 8090 8091 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, write_to_id, 1); /* level */ 8092 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed for GL_DRAW_FRAMEBUFFER target."); 8093 8094 gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_static_to_id, 8095 0); /* level */ 8096 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed for GL_READ_FRAMEBUFFER target."); 8097 } 8098 8099 /* Execute the API call */ 8100 const unsigned int region_width = (write_to_width >> 1); 8101 const unsigned int region_height = (write_to_height >> 1); 8102 const unsigned int region_x = region_width - (region_width >> 1); 8103 const unsigned int region_y = region_height - (region_height >> 1); 8104 8105 if (should_use_glTexSubImage2D) 8106 { 8107 /* Call glTexSubImage2D() to replace a portion of the gradient with a static color */ 8108 { 8109 unsigned char* static_color_data_ptr = getStaticColorTextureData(region_width, region_height); 8110 8111 gl.texSubImage2D(GL_TEXTURE_2D, 1, /* level */ 8112 region_x, region_y, region_width, region_height, GL_RGBA, GL_UNSIGNED_BYTE, 8113 static_color_data_ptr); 8114 8115 /* Good to release static color data buffer at this point */ 8116 delete[] static_color_data_ptr; 8117 8118 static_color_data_ptr = DE_NULL; 8119 8120 /* Make sure the API call was successful */ 8121 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed."); 8122 } 8123 } 8124 else 8125 { 8126 gl.blitFramebuffer(0, /* srcX0 */ 8127 0, /* srcY0 */ 8128 m_static_texture_width, /* srcX1 */ 8129 m_static_texture_height, /* srcY1 */ 8130 region_x, region_y, region_x + region_width, region_y + region_height, GL_COLOR_BUFFER_BIT, 8131 GL_NEAREST); 8132 GLU_EXPECT_NO_ERROR(gl.getError(), "glBlitFramebuffer() call failed."); 8133 } 8134 8135 /* Bind the sibling object so that we can make sure the data read from the 8136 * region can be correctly read from a shader without a memory barrier. 8137 * 8138 * While we're here, also determine which LOD we should be sampling from in 8139 * the shader. 8140 **/ 8141 unsigned int read_lod = 0; 8142 glw::GLuint read_to_id = 0; 8143 8144 getReadPropertiesForTextureType(texture_type, &read_to_id, &read_lod); 8145 8146 gl.bindTexture(GL_TEXTURE_2D, read_to_id); 8147 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 8148 8149 /* Update the test program uniforms before we carry on with actual 8150 * verification 8151 */ 8152 gl.useProgram(m_verification_po_id); 8153 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 8154 8155 DE_STATIC_ASSERT(sizeof(m_static_color_float) == sizeof(float) * 4); 8156 8157 gl.uniform4fv(m_verification_po_expected_color_location, 1, /* count */ 8158 m_static_color_float); 8159 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed."); 8160 8161 gl.uniform1i(m_verification_po_lod_location, read_lod); 8162 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 8163 8164 /* Make sure rasterization is disabled before we carry on */ 8165 gl.enable(GL_RASTERIZER_DISCARD); 8166 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed."); 8167 8168 /* Go ahead with the rendering. Make sure to capture the varyings */ 8169 gl.beginTransformFeedback(GL_POINTS); 8170 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 8171 { 8172 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 8173 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 8174 } 8175 gl.endTransformFeedback(); 8176 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 8177 8178 /* Map the buffer object so we can validate the sampling result */ 8179 const glw::GLint* data_ptr = (const glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 8180 8181 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 8182 DE_ASSERT(data_ptr != NULL); 8183 8184 /* Verify the outcome of the sampling operation */ 8185 if (*data_ptr != 1) 8186 { 8187 TCU_FAIL("Invalid data was sampled in vertex shader"); 8188 } 8189 8190 /* Unmap the buffer object */ 8191 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 8192 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 8193 8194 data_ptr = DE_NULL; 8195 8196 /* Disable GL_RASTERIZER_DISCARD mode */ 8197 gl.disable(GL_RASTERIZER_DISCARD); 8198 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed."); 8199 } 8200 8201 /** Verifies texture/view & view/texture coherency is met when one of the objects 8202 * is used as a render-target. The function writes to user-specified texture type, 8203 * and then verifies the contents of the sibling object. 8204 * 8205 * The function throws TestError exception if any of the checks fail. 8206 * 8207 * @param texture_type Tells which of the two objects should be written to. 8208 * @param should_use_images true if images should be used for 8209 * @param barrier_type Type of the memory barrier that should be injected 8210 * after vertex shader stage with image writes is executed. 8211 * Must be BARRIER_TYPE_NONE if @param should_use_images 8212 * is set to false. 8213 * @param verification_mean Determines whether the verification should be performed 8214 * using a program object, or by CPU with the data 8215 * extracted from the sibling object using a glGetTexImage() 8216 * call. 8217 * 8218 **/ 8219 void TextureViewTestCoherency::checkProgramWriteCoherency(_texture_type texture_type, bool should_use_images, 8220 _barrier_type barrier_type, 8221 _verification_mean verification_mean) 8222 { 8223 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8224 8225 if (!should_use_images) 8226 { 8227 /* Sanity check: no barrier should be requested if images are not used */ 8228 DE_ASSERT(barrier_type == BARRIER_TYPE_NONE); 8229 8230 /* Sanity check: glGetTexImage*() call should only be used for verification 8231 * when images are used */ 8232 DE_ASSERT(verification_mean == VERIFICATION_MEAN_PROGRAM); 8233 } 8234 8235 /* Determine GL id of an object we will be rendering the gradient to */ 8236 glw::GLuint write_to_id = 0; 8237 unsigned int write_to_width = 0; 8238 unsigned int write_to_height = 0; 8239 8240 getWritePropertiesForTextureType(texture_type, &write_to_id, &write_to_width, &write_to_height); 8241 8242 /* Configure the render targets */ 8243 if (should_use_images) 8244 { 8245 gl.bindImageTexture(0, /* unit */ 8246 write_to_id, 1, /* second level */ 8247 GL_FALSE, /* layered */ 8248 0, /* layer */ 8249 GL_WRITE_ONLY, GL_RGBA8); 8250 8251 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed."); 8252 } 8253 else 8254 { 8255 /* We first need to fill either the texture or its sibling view with 8256 * gradient data. Set up draw framebuffer */ 8257 gl.bindFramebuffer(GL_FRAMEBUFFER, m_draw_fbo_id); 8258 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed for GL_FRAMEBUFFER target"); 8259 8260 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, write_to_id, 1); /* level */ 8261 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 8262 8263 /* Configure the viewport accordingly */ 8264 gl.viewport(0, /* x */ 8265 0, /* y */ 8266 write_to_width, write_to_height); 8267 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed."); 8268 } 8269 8270 /* The gradient needs to be rendered differently, depending on whether 8271 * we're asked to use images or not */ 8272 if (should_use_images) 8273 { 8274 gl.useProgram(m_gradient_image_write_po_id); 8275 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 8276 8277 gl.uniform2i(m_gradient_image_write_image_size_location, write_to_width, write_to_height); 8278 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform2i() call failed."); 8279 8280 gl.enable(GL_RASTERIZER_DISCARD); 8281 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed."); 8282 { 8283 gl.drawArrays(GL_POINTS, 0 /* first */, write_to_width * write_to_height); 8284 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 8285 } 8286 gl.disable(GL_RASTERIZER_DISCARD); 8287 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable(GL_RASTERIZER_DISCARD) call failed."); 8288 8289 /* If the caller requested any barriers, issue them at this point */ 8290 switch (barrier_type) 8291 { 8292 case BARRIER_TYPE_TEXTURE_FETCH_BARRIER_BIT: 8293 { 8294 gl.memoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 8295 8296 GLU_EXPECT_NO_ERROR(gl.getError(), 8297 "glMemoryBarrier() call failed for GL_TEXTURE_FETCH_BARRIER_BIT barrier"); 8298 8299 break; 8300 } 8301 8302 case BARRIER_TYPE_TEXTURE_UPDATE_BUFFER_BIT: 8303 { 8304 gl.memoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); 8305 8306 GLU_EXPECT_NO_ERROR(gl.getError(), 8307 "glMemoryBarrier() call failed for GL_TEXTURE_UPDATE_BARRIER_BIT barrier"); 8308 8309 break; 8310 } 8311 8312 default: 8313 { 8314 TCU_FAIL("Unrecognized barrier type"); 8315 } 8316 } /* switch (barrier_type) */ 8317 } /* if (should_use_images) */ 8318 else 8319 { 8320 /* Render the gradient on a full-screen quad */ 8321 gl.useProgram(m_gradient_write_po_id); 8322 GLU_EXPECT_NO_ERROR(gl.getError(), "gluseProgram() call failed."); 8323 8324 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */); 8325 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 8326 } 8327 8328 /* Determine which texture and which mip-map level we will need to sample 8329 * in order to verify whether the former operations have been completed 8330 * successfully. 8331 **/ 8332 unsigned int read_lod = 0; 8333 glw::GLuint read_to_id = 0; 8334 8335 getReadPropertiesForTextureType(texture_type, &read_to_id, &read_lod); 8336 8337 /* Before we proceed with verification, update the texture binding so that 8338 * the verification program can sample from the right texture */ 8339 gl.activeTexture(GL_TEXTURE0); 8340 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed."); 8341 8342 gl.bindTexture(GL_TEXTURE_2D, read_to_id); 8343 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 8344 8345 if (verification_mean == VERIFICATION_MEAN_PROGRAM) 8346 { 8347 /* Switch to a verification program. It uses a vertex shader to sample 8348 * all texels of the texture so issue as many invocations as necessary. */ 8349 unsigned int n_invocations = write_to_width * write_to_height; 8350 8351 gl.useProgram(m_gradient_verification_po_id); 8352 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 8353 8354 gl.uniform1i(m_gradient_verification_po_texture_location, 0); 8355 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 8356 8357 gl.uniform1i(m_gradient_verification_po_sample_exact_uv_location, should_use_images); 8358 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 8359 8360 gl.uniform1f(m_gradient_verification_po_lod_location, (float)read_lod); 8361 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed."); 8362 8363 gl.enable(GL_RASTERIZER_DISCARD); 8364 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed."); 8365 8366 gl.beginTransformFeedback(GL_POINTS); 8367 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 8368 { 8369 gl.drawArrays(GL_POINTS, 0 /* first */, n_invocations); 8370 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 8371 } 8372 gl.endTransformFeedback(); 8373 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 8374 8375 gl.disable(GL_RASTERIZER_DISCARD); 8376 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable(GL_RASTERIZER_DISCARD) call failed."); 8377 8378 /* Map the result buffer object storage into process space */ 8379 const int* result_data_ptr = (const int*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 8380 8381 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 8382 8383 if (result_data_ptr == DE_NULL) 8384 { 8385 TCU_FAIL("glMapBuffer() did not generate an error but returned a NULL pointer"); 8386 } 8387 8388 /* Verify the XFBed data */ 8389 for (unsigned int n_invocation = 0; n_invocation < n_invocations; ++n_invocation) 8390 { 8391 if (result_data_ptr[n_invocation] != 1) 8392 { 8393 unsigned int invocation_x = n_invocation % write_to_width; 8394 unsigned int invocation_y = n_invocation / write_to_width; 8395 8396 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled at " 8397 << "(" << invocation_x << ", " << invocation_y << ") when sampling from " 8398 << ((texture_type == TEXTURE_TYPE_PARENT_TEXTURE) ? "a texture" : "a view") 8399 << tcu::TestLog::EndMessage; 8400 8401 /* Make sure the buffer is unmapped before throwing the exception */ 8402 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 8403 8404 TCU_FAIL("Invalid data sampled"); 8405 } 8406 } /* for (all invocations) */ 8407 8408 /* Unmap the buffer storage */ 8409 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 8410 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 8411 } /* if (verification_mean == VERIFICATION_MEAN_PROGRAM) */ 8412 else 8413 { 8414 DE_ASSERT(verification_mean == VERIFICATION_MEAN_GLGETTEXIMAGE); 8415 8416 /* Allocate space for the data */ 8417 unsigned char* data_ptr = new unsigned char[write_to_width * write_to_height * m_texture_n_components]; 8418 8419 /* Retrieve the rendered data */ 8420 gl.getTexImage(GL_TEXTURE_2D, read_lod, GL_RGBA, GL_UNSIGNED_BYTE, data_ptr); 8421 8422 if (gl.getError() != GL_NO_ERROR) 8423 { 8424 /* Release the buffer before we throw an exception */ 8425 delete[] data_ptr; 8426 8427 TCU_FAIL("glGetTexImage() call failed."); 8428 } 8429 8430 /* Verify the data is correct */ 8431 const int epsilon = 1; 8432 bool is_data_correct = true; 8433 8434 for (unsigned int y = 0; y < write_to_height; ++y) 8435 { 8436 const unsigned char* row_ptr = data_ptr + y * m_texture_n_components * write_to_width; 8437 8438 for (unsigned int x = 0; x < write_to_width; ++x) 8439 { 8440 const unsigned char* texel_ptr = row_ptr + x * m_texture_n_components; 8441 const float end_rgba[] = { 0.0f, 0.1f, 1.0f, 1.0f }; 8442 const float lerp_factor = float(x) / float(write_to_width); 8443 const float start_rgba[] = { 1.0f, 0.9f, 0.0f, 0.0f }; 8444 const float expected_data_float[] = { start_rgba[0] * (1.0f - lerp_factor) + end_rgba[0] * lerp_factor, 8445 start_rgba[1] * (1.0f - lerp_factor) + end_rgba[1] * lerp_factor, 8446 start_rgba[2] * (1.0f - lerp_factor) + end_rgba[2] * lerp_factor, 8447 start_rgba[3] * (1.0f - lerp_factor) + 8448 end_rgba[3] * lerp_factor }; 8449 const unsigned char expected_data_ubyte[] = { (unsigned char)(expected_data_float[0] * 255.0f), 8450 (unsigned char)(expected_data_float[1] * 255.0f), 8451 (unsigned char)(expected_data_float[2] * 255.0f), 8452 (unsigned char)(expected_data_float[3] * 255.0f) }; 8453 8454 if (de::abs((int)texel_ptr[0] - (int)expected_data_ubyte[0]) > epsilon || 8455 de::abs((int)texel_ptr[1] - (int)expected_data_ubyte[1]) > epsilon || 8456 de::abs((int)texel_ptr[2] - (int)expected_data_ubyte[2]) > epsilon || 8457 de::abs((int)texel_ptr[3] - (int)expected_data_ubyte[3]) > epsilon) 8458 { 8459 is_data_correct = false; 8460 8461 break; 8462 } 8463 } 8464 } /* for (all rows) */ 8465 8466 /* Good to release the data buffer at this point */ 8467 delete[] data_ptr; 8468 8469 data_ptr = DE_NULL; 8470 8471 /* Fail the test if any of the rendered texels were found invalid */ 8472 if (!is_data_correct) 8473 { 8474 TCU_FAIL("Invalid data sampled"); 8475 } 8476 } 8477 } 8478 8479 /** Deinitializes all GL objects that may have been created during 8480 * test execution. 8481 **/ 8482 void TextureViewTestCoherency::deinit() 8483 { 8484 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8485 8486 /* Release any GL objects the test may have created */ 8487 if (m_bo_id != 0) 8488 { 8489 gl.deleteBuffers(1, &m_bo_id); 8490 8491 m_bo_id = 0; 8492 } 8493 8494 if (m_draw_fbo_id != 0) 8495 { 8496 gl.deleteFramebuffers(1, &m_draw_fbo_id); 8497 8498 m_draw_fbo_id = 0; 8499 } 8500 8501 if (m_gradient_image_write_po_id != 0) 8502 { 8503 gl.deleteProgram(m_gradient_image_write_po_id); 8504 8505 m_gradient_image_write_po_id = 0; 8506 } 8507 8508 if (m_gradient_image_write_vs_id != 0) 8509 { 8510 gl.deleteShader(m_gradient_image_write_vs_id); 8511 8512 m_gradient_image_write_vs_id = 0; 8513 } 8514 8515 if (m_gradient_verification_po_id != 0) 8516 { 8517 gl.deleteProgram(m_gradient_verification_po_id); 8518 8519 m_gradient_verification_po_id = 0; 8520 } 8521 8522 if (m_gradient_verification_vs_id != 0) 8523 { 8524 gl.deleteShader(m_gradient_verification_vs_id); 8525 8526 m_gradient_verification_vs_id = 0; 8527 } 8528 8529 if (m_gradient_write_fs_id != 0) 8530 { 8531 gl.deleteShader(m_gradient_write_fs_id); 8532 8533 m_gradient_write_fs_id = 0; 8534 } 8535 8536 if (m_gradient_write_po_id != 0) 8537 { 8538 gl.deleteProgram(m_gradient_write_po_id); 8539 8540 m_gradient_write_po_id = 0; 8541 } 8542 8543 if (m_gradient_write_vs_id != 0) 8544 { 8545 gl.deleteShader(m_gradient_write_vs_id); 8546 8547 m_gradient_write_vs_id = 0; 8548 } 8549 8550 if (m_read_fbo_id != 0) 8551 { 8552 gl.deleteFramebuffers(1, &m_read_fbo_id); 8553 8554 m_read_fbo_id = 0; 8555 } 8556 8557 if (m_static_to_id != 0) 8558 { 8559 gl.deleteTextures(1, &m_static_to_id); 8560 8561 m_static_to_id = 0; 8562 } 8563 8564 if (m_to_id != 0) 8565 { 8566 gl.deleteTextures(1, &m_to_id); 8567 8568 m_to_id = 0; 8569 } 8570 8571 if (m_vao_id != 0) 8572 { 8573 gl.deleteVertexArrays(1, &m_vao_id); 8574 8575 m_vao_id = 0; 8576 } 8577 8578 if (m_view_to_id != 0) 8579 { 8580 gl.deleteTextures(1, &m_view_to_id); 8581 8582 m_view_to_id = 0; 8583 } 8584 8585 if (m_verification_po_id != 0) 8586 { 8587 gl.deleteProgram(m_verification_po_id); 8588 8589 m_verification_po_id = 0; 8590 } 8591 8592 if (m_verification_vs_id != 0) 8593 { 8594 gl.deleteShader(m_verification_vs_id); 8595 8596 m_verification_vs_id = 0; 8597 } 8598 8599 /* Disable GL_RASTERIZER_DISCARD mode */ 8600 gl.disable(GL_RASTERIZER_DISCARD); 8601 } 8602 8603 /** Allocates a sufficiently large buffer for RGBA8 data and fills it with 8604 * a horizontal gradient (as described in the test specification) 8605 * 8606 * It is user's responsibility to release the buffer when no longer needed. 8607 * 8608 * @return Pointer to the buffer. 8609 **/ 8610 unsigned char* TextureViewTestCoherency::getHorizontalGradientData() const 8611 { 8612 const float end_rgba[] = { 1.0f, 0.9f, 0.0f, 0.0f }; 8613 unsigned char* result = new unsigned char[m_texture_width * m_texture_height * m_texture_n_components]; 8614 const float start_rgba[] = { 0.0f, 0.1f, 1.0f, 1.0f }; 8615 const unsigned int texel_size = m_texture_n_components; 8616 8617 for (unsigned int y = 0; y < m_texture_height; ++y) 8618 { 8619 unsigned char* row_data_ptr = result + texel_size * m_texture_width * y; 8620 8621 for (unsigned int x = 0; x < m_texture_width; ++x) 8622 { 8623 const float lerp_factor = float(x) / float(m_texture_width); 8624 unsigned char* pixel_data_ptr = row_data_ptr + texel_size * x; 8625 8626 for (unsigned int n_component = 0; n_component < 4 /* rgba */; ++n_component) 8627 { 8628 pixel_data_ptr[n_component] = (unsigned char)((end_rgba[n_component] * lerp_factor + 8629 start_rgba[n_component] * (1.0f - lerp_factor)) * 8630 255.0f); 8631 } /* for (all components) */ 8632 } /* for (all columns) */ 8633 } /* for (all rows) */ 8634 8635 return result; 8636 } 8637 8638 /** Retrieves properties of a sibling object that should be read from during 8639 * some of the checks. 8640 * 8641 * @param texture_type Type of the texture object that should be used for reading. 8642 * @param out_to_id Deref will be used to store texture object ID of the object. 8643 * @param out_read_lod Deref will be used to store LOD to be used for reading from 8644 * the object. 8645 * 8646 **/ 8647 void TextureViewTestCoherency::getReadPropertiesForTextureType(_texture_type texture_type, glw::GLuint* out_to_id, 8648 unsigned int* out_read_lod) const 8649 { 8650 switch (texture_type) 8651 { 8652 case TEXTURE_TYPE_PARENT_TEXTURE: 8653 { 8654 *out_to_id = m_view_to_id; 8655 8656 /* We've modified LOD1 of parent texture which corresponds 8657 * to LOD 0 from the view's PoV 8658 */ 8659 *out_read_lod = 0; 8660 8661 break; 8662 } 8663 8664 case TEXTURE_TYPE_TEXTURE_VIEW: 8665 { 8666 *out_to_id = m_to_id; 8667 8668 /* We've modified LOD1 of the view texture which corresponds 8669 * to LOD2 from parent texture's PoV. 8670 */ 8671 *out_read_lod = 2; 8672 8673 break; 8674 } 8675 8676 default: 8677 { 8678 TCU_FAIL("Unrecognized read source"); 8679 } 8680 } /* switch (texture_type) */ 8681 } 8682 8683 /** Allocates a sufficiently large buffer to hold RGBA8 data of user-specified resolution 8684 * and fills it with a static color (as described in the test specification) 8685 * 8686 * It is caller's responsibility to release the returned buffer when it's no longer 8687 * needed. 8688 * 8689 * @param width Width of the mip-map the buffer will be used as a data source for; 8690 * @param height Height of the mip-map the buffer will be used as a data source for; 8691 * 8692 * @return Pointer to the buffer. 8693 **/ 8694 unsigned char* TextureViewTestCoherency::getStaticColorTextureData(unsigned int width, unsigned int height) const 8695 { 8696 /* Prepare the data buffer storing the data we want to replace the region of the 8697 * data source with. 8698 */ 8699 unsigned char* result_ptr = new unsigned char[width * height * m_texture_n_components]; 8700 8701 for (unsigned int y = 0; y < height; ++y) 8702 { 8703 unsigned char* row_data_ptr = result_ptr + y * width * m_texture_n_components; 8704 8705 for (unsigned int x = 0; x < width; ++x) 8706 { 8707 unsigned char* pixel_data_ptr = row_data_ptr + x * m_texture_n_components; 8708 8709 memcpy(pixel_data_ptr, m_static_color_byte, sizeof(m_static_color_byte)); 8710 } /* for (all columns) */ 8711 } /* for (all rows) */ 8712 8713 return result_ptr; 8714 } 8715 8716 /** Retrieves properties of a parent texture object that should be written to during 8717 * some of the checks. 8718 * 8719 * @param texture_type Type of the texture object that should be used for writing. 8720 * @param out_to_id Deref will be used to store texture object ID of the object. Must not be NULL. 8721 * @param out_width Deref will be used to store width of the mip-map the test will 8722 * be writing to; Must not be NULL. 8723 * @param out_height Deref will be used to store height of the mip-map the test will 8724 * be writing to. Must not be NULL. 8725 * 8726 **/ 8727 void TextureViewTestCoherency::getWritePropertiesForTextureType(_texture_type texture_type, glw::GLuint* out_to_id, 8728 unsigned int* out_width, unsigned int* out_height) const 8729 { 8730 DE_ASSERT(out_to_id != DE_NULL); 8731 DE_ASSERT(out_width != DE_NULL); 8732 DE_ASSERT(out_height != DE_NULL); 8733 8734 /* All tests will be attempting to modify layer 1 of either the texture 8735 * or its sibling view. For views, the resolution is therefore going to 8736 * be 16x16 (because the base resolution is 32x32, as the view uses a mipmap 8737 * range of 1 to 2 inclusive); for parent texture, this will be 32x32 (as the base 8738 * mip-map is 64x64) 8739 */ 8740 switch (texture_type) 8741 { 8742 case TEXTURE_TYPE_PARENT_TEXTURE: 8743 { 8744 *out_to_id = m_to_id; 8745 *out_width = m_texture_width >> 1; 8746 *out_height = m_texture_height >> 1; 8747 8748 break; 8749 } 8750 8751 case TEXTURE_TYPE_TEXTURE_VIEW: 8752 { 8753 *out_to_id = m_view_to_id; 8754 *out_width = m_texture_width >> 2; 8755 *out_height = m_texture_height >> 2; 8756 8757 break; 8758 } 8759 8760 default: 8761 { 8762 TCU_FAIL("Unrecognized texture type"); 8763 } 8764 } /* switch (texture_type) */ 8765 } 8766 8767 /** Initializes buffer objects that will be used during the test. 8768 * 8769 * Throws exceptions if the initialization fails at any point. 8770 **/ 8771 void TextureViewTestCoherency::initBufferObjects() 8772 { 8773 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8774 8775 /* Generate and configure buffer object storage */ 8776 gl.genBuffers(1, &m_bo_id); 8777 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 8778 8779 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id); 8780 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 8781 8782 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id); 8783 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 8784 8785 /* Case 1) needs the BO to hold just a single int. 8786 * Case 3) needs one int per result texel. 8787 * 8788 * Allocate enough space to handle all the cases. 8789 **/ 8790 glw::GLint bo_size = static_cast<glw::GLint>((m_texture_height >> 1) * (m_texture_width >> 1) * sizeof(int)); 8791 8792 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL, /* data */ 8793 GL_STATIC_DRAW); 8794 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferdata() call failed."); 8795 } 8796 8797 /** Initializes framebuffer objects that will be used during the test. 8798 * 8799 * Throws exceptions if the initialization fails at any point. 8800 **/ 8801 void TextureViewTestCoherency::initFBO() 8802 { 8803 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8804 8805 /* Generate framebuffer object(s) */ 8806 gl.genFramebuffers(1, &m_draw_fbo_id); 8807 gl.genFramebuffers(1, &m_read_fbo_id); 8808 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed."); 8809 } 8810 8811 /** Initializes program objects that will be used during the test. 8812 * 8813 * This method will throw exceptions if either compilation or linking of 8814 * any of the processed shaders/programs fails. 8815 * 8816 **/ 8817 void TextureViewTestCoherency::initPrograms() 8818 { 8819 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8820 8821 /* The test uses images in vertex shader stage. Make sure this is actually supported by 8822 * the implementation */ 8823 m_are_images_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_image_load_store"); 8824 8825 if (m_are_images_supported) 8826 { 8827 glw::GLint gl_max_vertex_image_uniforms_value = 0; 8828 8829 gl.getIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &gl_max_vertex_image_uniforms_value); 8830 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_VERTEX_IMAGE_UNIFORM pname"); 8831 8832 if (gl_max_vertex_image_uniforms_value < 1) 8833 { 8834 m_testCtx.getLog() << tcu::TestLog::Message 8835 << "Image support will not be tested by view_parent_texture_coherency, as" 8836 "the implementation does not support image uniforms in vertex shader stage." 8837 << tcu::TestLog::EndMessage; 8838 8839 /* We cannot execute the test on this platform */ 8840 m_are_images_supported = false; 8841 } 8842 } /* if (m_are_images_supported) */ 8843 8844 /* Create program objects */ 8845 if (m_are_images_supported) 8846 { 8847 m_gradient_image_write_po_id = gl.createProgram(); 8848 } 8849 8850 m_gradient_verification_po_id = gl.createProgram(); 8851 m_gradient_write_po_id = gl.createProgram(); 8852 m_verification_po_id = gl.createProgram(); 8853 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed."); 8854 8855 /* Create fragment shader objects */ 8856 m_gradient_write_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 8857 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed for GL_FRAGMENT_SHADER type"); 8858 8859 /* Create vertex shader objects */ 8860 if (m_are_images_supported) 8861 { 8862 m_gradient_image_write_vs_id = gl.createShader(GL_VERTEX_SHADER); 8863 } 8864 8865 m_gradient_verification_vs_id = gl.createShader(GL_VERTEX_SHADER); 8866 m_gradient_write_vs_id = gl.createShader(GL_VERTEX_SHADER); 8867 m_verification_vs_id = gl.createShader(GL_VERTEX_SHADER); 8868 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed for GL_VERTEX_SHADER type."); 8869 8870 /* Set gradient verification program's fragment shader body */ 8871 const char* gradient_verification_vs_body = 8872 "#version 400\n" 8873 "\n" 8874 "out int result;\n" 8875 "\n" 8876 "uniform float lod;\n" 8877 "uniform bool sample_exact_uv;\n" 8878 "uniform sampler2D texture;\n" 8879 "\n" 8880 "void main()\n" 8881 "{\n" 8882 " const float epsilon = 1.0 / 255.0;\n" 8883 " const vec4 end_rgba = vec4(0.0, 0.1, 1.0, 1.0);\n" 8884 " const vec4 start_rgba = vec4(1.0, 0.9, 0.0, 0.0);\n" 8885 "\n" 8886 " ivec2 texture_size = textureSize(texture, int(lod) );\n" 8887 " vec2 uv = vec2( float(gl_VertexID % texture_size.x) / float(texture_size.x),\n" 8888 " 1.0 - float(gl_VertexID / texture_size.x) / float(texture_size.y) );\n" 8889 " vec4 expected_color;\n" 8890 " vec4 texture_color = textureLod(texture, uv, lod);\n" 8891 "\n" 8892 " if (sample_exact_uv)\n" 8893 " {\n" 8894 " expected_color = mix(start_rgba, end_rgba, uv.x);\n" 8895 " }\n" 8896 " else\n" 8897 " {\n" 8898 " expected_color = mix(start_rgba, end_rgba, uv.x + 0.5/float(texture_size.x) );\n" 8899 " }\n" 8900 "\n" 8901 "\n" 8902 " if (abs(texture_color.x - expected_color.x) > epsilon ||\n" 8903 " abs(texture_color.y - expected_color.y) > epsilon ||\n" 8904 " abs(texture_color.z - expected_color.z) > epsilon ||\n" 8905 " abs(texture_color.w - expected_color.w) > epsilon)\n" 8906 " {\n" 8907 " result = int( texture_color.y * 255.0);\n" 8908 " }\n" 8909 " else\n" 8910 " {\n" 8911 " result = 1;\n" 8912 " }\n" 8913 "}\n"; 8914 8915 gl.shaderSource(m_gradient_verification_vs_id, 1 /* count */, &gradient_verification_vs_body, NULL /* length */); 8916 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 8917 8918 /* Set gradient write (for images) program's vertex shader body */ 8919 if (m_are_images_supported) 8920 { 8921 const char* gradient_write_image_vs_body = 8922 "#version 400\n" 8923 "\n" 8924 "#extension GL_ARB_shader_image_load_store : require\n" 8925 "\n" 8926 "layout(rgba8) uniform image2D image;\n" 8927 " uniform ivec2 image_size;\n" 8928 "\n" 8929 "void main()\n" 8930 "{\n" 8931 " const vec4 end_rgba = vec4(0.0, 0.1, 1.0, 1.0);\n" 8932 " const vec4 start_rgba = vec4(1.0, 0.9, 0.0, 0.0);\n" 8933 " ivec2 xy = ivec2(gl_VertexID % image_size.x, gl_VertexID / image_size.x);\n" 8934 " vec2 uv = vec2(float(xy.x) / float(image_size.x), 1.0 - float(xy.y) / " 8935 "float(image_size.y) );\n" 8936 " vec4 result = mix (start_rgba, end_rgba, uv.x);\n" 8937 "\n" 8938 " imageStore(image, xy, result);\n" 8939 "}\n"; 8940 8941 gl.shaderSource(m_gradient_image_write_vs_id, 1 /* count */, &gradient_write_image_vs_body, NULL /* length */); 8942 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 8943 } 8944 8945 /* Set gradient write program's fragment shader body */ 8946 const char* gradient_write_fs_body = "#version 400\n" 8947 "\n" 8948 "in vec2 uv;\n" 8949 "\n" 8950 "layout(location = 0) out vec4 result;\n" 8951 "\n" 8952 "void main()\n" 8953 "{\n" 8954 " const vec4 end_rgba = vec4(0.0, 0.1, 1.0, 1.0);\n" 8955 " const vec4 start_rgba = vec4(1.0, 0.9, 0.0, 0.0);\n" 8956 "\n" 8957 " result = mix(start_rgba, end_rgba, uv.x);\n" 8958 "}\n"; 8959 8960 gl.shaderSource(m_gradient_write_fs_id, 1 /* count */, &gradient_write_fs_body, NULL /* length */); 8961 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 8962 8963 /* Set gradient write program's vertex shader body */ 8964 const char* gradient_write_vs_body = 8965 "#version 400\n" 8966 "\n" 8967 "out vec2 uv;\n" 8968 "\n" 8969 "void main()\n" 8970 "{\n" 8971 " switch (gl_VertexID)\n" 8972 " {\n" 8973 " case 0: gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); uv = vec2(0.0, 1.0); break;\n" 8974 " case 1: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); uv = vec2(0.0, 0.0); break;\n" 8975 " case 2: gl_Position = vec4( 1.0, -1.0, 0.0, 1.0); uv = vec2(1.0, 1.0); break;\n" 8976 " case 3: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); uv = vec2(1.0, 0.0); break;\n" 8977 " }\n" 8978 "}\n"; 8979 8980 gl.shaderSource(m_gradient_write_vs_id, 1 /* count */, &gradient_write_vs_body, NULL /* length */); 8981 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 8982 8983 /* Set verification program's vertex shader body */ 8984 const char* verification_vs_body = "#version 400\n" 8985 "\n" 8986 "uniform vec4 expected_color;\n" 8987 "uniform int lod;\n" 8988 "uniform sampler2D sampler;\n" 8989 "\n" 8990 "out int result;\n" 8991 "\n" 8992 "void main()\n" 8993 "{\n" 8994 " const float epsilon = 1.0 / 256.0;\n" 8995 "\n" 8996 " vec4 sampled_data = textureLod(sampler, vec2(0.5, 0.5), lod);\n" 8997 "\n" 8998 " if (abs(sampled_data.x - expected_color.x) > epsilon ||\n" 8999 " abs(sampled_data.y - expected_color.y) > epsilon ||\n" 9000 " abs(sampled_data.z - expected_color.z) > epsilon ||\n" 9001 " abs(sampled_data.w - expected_color.w) > epsilon)\n" 9002 " {\n" 9003 " result = 0;\n" 9004 " }\n" 9005 " else\n" 9006 " {\n" 9007 " result = 1;\n" 9008 " }\n" 9009 "}\n"; 9010 9011 gl.shaderSource(m_verification_vs_id, 1 /* count */, &verification_vs_body, NULL /* length */); 9012 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 9013 9014 /* Compile the shaders */ 9015 const glw::GLuint so_ids[] = { m_gradient_image_write_vs_id, m_gradient_verification_vs_id, m_gradient_write_fs_id, 9016 m_gradient_write_vs_id, m_verification_vs_id }; 9017 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]); 9018 9019 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id) 9020 { 9021 glw::GLuint so_id = so_ids[n_so_id]; 9022 9023 if (so_id != 0) 9024 { 9025 gl.compileShader(so_id); 9026 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 9027 9028 /* Verify the compilation ended successfully */ 9029 glw::GLint compile_status = GL_FALSE; 9030 9031 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status); 9032 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 9033 9034 if (compile_status != GL_TRUE) 9035 { 9036 TCU_FAIL("Shader compilation failed."); 9037 } 9038 } 9039 } /* for (all shader objects) */ 9040 9041 /* Attach the shaders to relevant programs */ 9042 if (m_are_images_supported) 9043 { 9044 gl.attachShader(m_gradient_image_write_po_id, m_gradient_image_write_vs_id); 9045 } 9046 9047 gl.attachShader(m_gradient_verification_po_id, m_gradient_verification_vs_id); 9048 gl.attachShader(m_gradient_write_po_id, m_gradient_write_fs_id); 9049 gl.attachShader(m_gradient_write_po_id, m_gradient_write_vs_id); 9050 gl.attachShader(m_verification_po_id, m_verification_vs_id); 9051 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed."); 9052 9053 /* Set up XFB */ 9054 const char* verification_varying_name = "result"; 9055 const glw::GLuint xfb_po_ids[] = { 9056 m_gradient_verification_po_id, m_verification_po_id, 9057 }; 9058 const unsigned int n_xfb_po_ids = sizeof(xfb_po_ids) / sizeof(xfb_po_ids[0]); 9059 9060 for (unsigned int n_xfb_po_id = 0; n_xfb_po_id < n_xfb_po_ids; ++n_xfb_po_id) 9061 { 9062 glw::GLint po_id = xfb_po_ids[n_xfb_po_id]; 9063 9064 gl.transformFeedbackVaryings(po_id, 1 /* count */, &verification_varying_name, GL_INTERLEAVED_ATTRIBS); 9065 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed."); 9066 } 9067 9068 /* Link the programs */ 9069 const glw::GLuint po_ids[] = { m_gradient_image_write_po_id, m_gradient_verification_po_id, m_gradient_write_po_id, 9070 m_verification_po_id }; 9071 const unsigned int n_po_ids = sizeof(po_ids) / sizeof(po_ids[0]); 9072 9073 for (unsigned int n_po_id = 0; n_po_id < n_po_ids; ++n_po_id) 9074 { 9075 glw::GLuint po_id = po_ids[n_po_id]; 9076 9077 if (po_id != 0) 9078 { 9079 gl.linkProgram(po_id); 9080 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 9081 9082 /* Make sure the linking was successful. */ 9083 glw::GLint link_status = GL_FALSE; 9084 9085 gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status); 9086 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 9087 9088 if (link_status != GL_TRUE) 9089 { 9090 TCU_FAIL("Program linking failed."); 9091 } 9092 } 9093 } /* for (all program objects) */ 9094 9095 /* Retrieve uniform locations for gradient write program (image case) */ 9096 if (m_are_images_supported) 9097 { 9098 m_gradient_image_write_image_size_location = gl.getUniformLocation(m_gradient_image_write_po_id, "image_size"); 9099 9100 if (m_gradient_image_write_image_size_location == -1) 9101 { 9102 TCU_FAIL("image_size is considered an inactive uniform which is invalid."); 9103 } 9104 } 9105 9106 /* Retrieve uniform locations for gradient verification program */ 9107 m_gradient_verification_po_sample_exact_uv_location = 9108 gl.getUniformLocation(m_gradient_verification_po_id, "sample_exact_uv"); 9109 m_gradient_verification_po_lod_location = gl.getUniformLocation(m_gradient_verification_po_id, "lod"); 9110 m_gradient_verification_po_texture_location = gl.getUniformLocation(m_gradient_verification_po_id, "texture"); 9111 9112 if (m_gradient_verification_po_sample_exact_uv_location == -1) 9113 { 9114 TCU_FAIL("sample_exact_uv is considered an inactive uniform which is invalid"); 9115 } 9116 9117 if (m_gradient_verification_po_lod_location == -1) 9118 { 9119 TCU_FAIL("lod is considered an inactive uniform which is invalid."); 9120 } 9121 9122 if (m_gradient_verification_po_texture_location == -1) 9123 { 9124 TCU_FAIL("texture is considered an inactive uniform which is invalid."); 9125 } 9126 9127 /* Retrieve uniform locations for verification program */ 9128 m_verification_po_expected_color_location = gl.getUniformLocation(m_verification_po_id, "expected_color"); 9129 m_verification_po_lod_location = gl.getUniformLocation(m_verification_po_id, "lod"); 9130 9131 if (m_verification_po_expected_color_location == -1) 9132 { 9133 TCU_FAIL("expected_color is considered an inactive uniform which is invalid."); 9134 } 9135 9136 if (m_verification_po_lod_location == -1) 9137 { 9138 TCU_FAIL("lod is considered an inactive uniform which is invalid."); 9139 } 9140 } 9141 9142 /** Initializes texture objects required to run the test. 9143 * 9144 * Throws exceptions if the initialization fails at any point. 9145 **/ 9146 void TextureViewTestCoherency::initTextures() 9147 { 9148 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9149 9150 /* Generate the texture objects */ 9151 gl.genTextures(1, &m_static_to_id); 9152 gl.genTextures(1, &m_to_id); 9153 gl.genTextures(1, &m_view_to_id); 9154 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed."); 9155 9156 /* Set up parent texture object */ 9157 gl.bindTexture(GL_TEXTURE_2D, m_to_id); 9158 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 9159 9160 gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height); 9161 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 9162 9163 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 9164 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 9165 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 9166 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 9167 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed."); 9168 9169 /* Set up the texture views we'll be using for the test */ 9170 gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, GL_RGBA8, 1, /* minlevel */ 9171 2, /* numlevels */ 9172 0, /* minlayer */ 9173 1); /* numlayers */ 9174 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed"); 9175 9176 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id); 9177 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 9178 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 9179 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 9180 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 9181 9182 /* Set up storage for static color texture */ 9183 gl.bindTexture(GL_TEXTURE_2D, m_static_to_id); 9184 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 9185 9186 gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */ 9187 GL_RGBA8, m_static_texture_width, m_static_texture_height); 9188 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 9189 9190 /* Fill the texture objects with actual contents */ 9191 initTextureContents(); 9192 } 9193 9194 /** Fills all relevant mip-maps of all previously initialized texture objects with 9195 * contents. 9196 * 9197 * Throws an exception if any of the issued GL API calls fail. 9198 **/ 9199 void TextureViewTestCoherency::initTextureContents() 9200 { 9201 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9202 9203 /* Make sure parent texture object is bound before we start modifying 9204 * the mip-maps */ 9205 gl.bindTexture(GL_TEXTURE_2D, m_to_id); 9206 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 9207 9208 /* Set up parent texture mip-maps */ 9209 unsigned char* base_mipmap_data_ptr = getHorizontalGradientData(); 9210 9211 gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */ 9212 0, /* xoffset */ 9213 0, /* yoffset */ 9214 m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, base_mipmap_data_ptr); 9215 9216 delete[] base_mipmap_data_ptr; 9217 base_mipmap_data_ptr = NULL; 9218 9219 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed."); 9220 9221 /* Generate all mip-maps */ 9222 gl.generateMipmap(GL_TEXTURE_2D); 9223 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed."); 9224 9225 /* Set up static color texture contents. We only need to fill the base mip-map 9226 * since the texture's resolution is 1x1. 9227 */ 9228 DE_ASSERT(m_static_texture_height == 1 && m_static_texture_width == 1); 9229 9230 unsigned char* static_texture_data_ptr = getStaticColorTextureData(m_static_texture_width, m_static_texture_height); 9231 9232 gl.bindTexture(GL_TEXTURE_2D, m_static_to_id); 9233 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 9234 9235 gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */ 9236 0, /* xoffset */ 9237 0, /* yoffset */ 9238 m_static_texture_width, m_static_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, 9239 static_texture_data_ptr); 9240 9241 /* Good to release the buffer at this point */ 9242 delete[] static_texture_data_ptr; 9243 9244 static_texture_data_ptr = DE_NULL; 9245 9246 /* Was the API call successful? */ 9247 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed."); 9248 } 9249 9250 /** Initializes a vertex array object used for the draw calls issued during the test. */ 9251 void TextureViewTestCoherency::initVAO() 9252 { 9253 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9254 9255 /* Generate and bind a vertex array object */ 9256 gl.genVertexArrays(1, &m_vao_id); 9257 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 9258 9259 gl.bindVertexArray(m_vao_id); 9260 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 9261 } 9262 9263 /** Executes test iteration. 9264 * 9265 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 9266 */ 9267 tcu::TestNode::IterateResult TextureViewTestCoherency::iterate() 9268 { 9269 /* Do not execute the test if GL_ARB_texture_view is not supported */ 9270 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view")) 9271 { 9272 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported."); 9273 } 9274 9275 /* Initialize all GL objects required to run the test */ 9276 initBufferObjects(); 9277 initPrograms(); 9278 initTextures(); 9279 initFBO(); 9280 initVAO(); 9281 9282 /* Iterate over the set of texture types we are to test */ 9283 const _texture_type texture_types[] = { TEXTURE_TYPE_PARENT_TEXTURE, TEXTURE_TYPE_TEXTURE_VIEW }; 9284 const unsigned int n_texture_types = sizeof(texture_types) / sizeof(texture_types[0]); 9285 9286 for (unsigned int n_texture_type = 0; n_texture_type < n_texture_types; ++n_texture_type) 9287 { 9288 _texture_type texture_type = texture_types[n_texture_type]; 9289 9290 /* Verify parent texture/view coherency when using glTexSubImage2D() */ 9291 checkAPICallCoherency(texture_type, true); 9292 9293 /* Verify parent texture/view coherency when using glBlitFramebuffer() */ 9294 checkAPICallCoherency(texture_type, false); 9295 9296 /* Verify parent texture/view coherency when modifying contents of one 9297 * of the objects in a program, and then reading the sibling from another 9298 * program. 9299 */ 9300 checkProgramWriteCoherency(texture_type, false, /* should_use_images */ 9301 BARRIER_TYPE_NONE, VERIFICATION_MEAN_PROGRAM); 9302 9303 if (m_are_images_supported) 9304 { 9305 /* Verify a view bound to an image unit and written to using image uniforms 9306 * in vertex shader stage can later be sampled correctly, assuming 9307 * a GL_TEXTURE_FETCH_BARRIER_BIT barrier is inserted between the write 9308 * operations and sampling from another program object. 9309 */ 9310 checkProgramWriteCoherency(texture_type, true, /* should_use_images */ 9311 BARRIER_TYPE_TEXTURE_FETCH_BARRIER_BIT, VERIFICATION_MEAN_PROGRAM); 9312 9313 /* Verify a view bound to an image unit and written to using image uniforms 9314 * in vertex shader stage can later be correctly retrieved using a glGetTexImage() 9315 * call, assuming a GL_TEXTURE_UPDATE_BARRIER_BIT barrier is inserted between the 9316 * two operations. 9317 **/ 9318 checkProgramWriteCoherency(texture_type, true, /* should_use_images */ 9319 BARRIER_TYPE_TEXTURE_UPDATE_BUFFER_BIT, VERIFICATION_MEAN_GLGETTEXIMAGE); 9320 } 9321 9322 /* Reinitialize all texture contents */ 9323 initTextureContents(); 9324 } /* for (all read sources) */ 9325 9326 /* Test case passed */ 9327 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 9328 9329 return STOP; 9330 } 9331 9332 /** Constructor. 9333 * 9334 * @param context Rendering context. 9335 * 9336 **/ 9337 TextureViewTestBaseAndMaxLevels::TextureViewTestBaseAndMaxLevels(deqp::Context& context) 9338 : TestCase(context, "base_and_max_levels", "test_description") 9339 , m_texture_height(256) 9340 , m_texture_n_components(4) 9341 , m_texture_n_levels(6) 9342 , m_texture_width(256) 9343 , m_view_height(128) 9344 , m_view_width(128) 9345 , m_layer_data_lod0(DE_NULL) 9346 , m_layer_data_lod1(DE_NULL) 9347 , m_fbo_id(0) 9348 , m_fs_id(0) 9349 , m_po_id(0) 9350 , m_po_lod_index_uniform_location(-1) 9351 , m_po_to_sampler_uniform_location(-1) 9352 , m_result_to_id(0) 9353 , m_to_id(0) 9354 , m_vao_id(0) 9355 , m_view_to_id(0) 9356 , m_vs_id(0) 9357 { 9358 /* Left blank on purpose */ 9359 } 9360 9361 /* Deinitializes all GL objects that may have been created during test execution. */ 9362 void TextureViewTestBaseAndMaxLevels::deinit() 9363 { 9364 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9365 9366 if (m_fbo_id != 0) 9367 { 9368 gl.deleteFramebuffers(1, &m_fbo_id); 9369 9370 m_fbo_id = 0; 9371 } 9372 9373 if (m_fs_id != 0) 9374 { 9375 gl.deleteShader(m_fs_id); 9376 9377 m_fs_id = 0; 9378 } 9379 9380 if (m_layer_data_lod0 != DE_NULL) 9381 { 9382 delete[] m_layer_data_lod0; 9383 9384 m_layer_data_lod0 = DE_NULL; 9385 } 9386 9387 if (m_layer_data_lod1 != DE_NULL) 9388 { 9389 delete[] m_layer_data_lod1; 9390 9391 m_layer_data_lod1 = DE_NULL; 9392 } 9393 9394 if (m_po_id != 0) 9395 { 9396 gl.deleteProgram(m_po_id); 9397 9398 m_po_id = 0; 9399 } 9400 9401 if (m_result_to_id != 0) 9402 { 9403 gl.deleteTextures(1, &m_result_to_id); 9404 9405 m_result_to_id = 0; 9406 } 9407 9408 if (m_to_id != 0) 9409 { 9410 gl.deleteTextures(1, &m_to_id); 9411 9412 m_to_id = 0; 9413 } 9414 9415 if (m_vao_id != 0) 9416 { 9417 gl.deleteVertexArrays(1, &m_vao_id); 9418 9419 m_vao_id = 0; 9420 } 9421 9422 if (m_view_to_id != 0) 9423 { 9424 gl.deleteTextures(1, &m_view_to_id); 9425 9426 m_view_to_id = 0; 9427 } 9428 9429 if (m_vs_id != 0) 9430 { 9431 gl.deleteShader(m_vs_id); 9432 9433 m_vs_id = 0; 9434 } 9435 } 9436 9437 /* Initializes and configures a program object used later by the test. */ 9438 void TextureViewTestBaseAndMaxLevels::initProgram() 9439 { 9440 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9441 9442 /* Generate shader object IDs */ 9443 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 9444 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 9445 9446 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed"); 9447 9448 /* Generate program object ID */ 9449 m_po_id = gl.createProgram(); 9450 9451 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed"); 9452 9453 /* Set up vertex shader body */ 9454 static const char* vs_body = 9455 "#version 400\n" 9456 "\n" 9457 "out vec2 uv;\n" 9458 "\n" 9459 "void main()\n" 9460 "{\n" 9461 " switch (gl_VertexID)\n" 9462 " {\n" 9463 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); uv = vec2(0.0, 1.0); break;\n" 9464 " case 1: gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); uv = vec2(0.0, 0.0); break;\n" 9465 " case 2: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); uv = vec2(1.0, 1.0); break;\n" 9466 " case 3: gl_Position = vec4( 1.0, -1.0, 0.0, 1.0); uv = vec2(1.0, 0.0); break;\n" 9467 " };\n" 9468 "}\n"; 9469 9470 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */); 9471 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed for vertex shader case"); 9472 9473 /* Set up fragment shader body */ 9474 static const char* fs_body = "#version 400\n" 9475 "\n" 9476 "in vec2 uv;\n" 9477 "\n" 9478 "uniform int lod_index;\n" 9479 "uniform sampler2D to_sampler;\n" 9480 "\n" 9481 "out vec4 result;\n" 9482 "\n" 9483 "void main()\n" 9484 "{\n" 9485 " result = textureLod(to_sampler, uv, float(lod_index) );\n" 9486 "}\n"; 9487 9488 gl.shaderSource(m_fs_id, 1 /* count */, &fs_body, DE_NULL /* length */); 9489 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed for fragment shader case"); 9490 9491 /* Compile both shaders */ 9492 const glw::GLuint so_ids[] = { m_fs_id, m_vs_id }; 9493 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]); 9494 9495 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id) 9496 { 9497 glw::GLint so_id = so_ids[n_so_id]; 9498 9499 gl.compileShader(so_id); 9500 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 9501 9502 /* Make sure the compilation has succeeded */ 9503 glw::GLint compile_status = GL_FALSE; 9504 9505 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status); 9506 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 9507 9508 if (compile_status != GL_TRUE) 9509 { 9510 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed" << tcu::TestLog::EndMessage; 9511 } 9512 } /* for (all shader objects) */ 9513 9514 /* Attach the shaders to the program object */ 9515 gl.attachShader(m_po_id, m_fs_id); 9516 gl.attachShader(m_po_id, m_vs_id); 9517 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed"); 9518 9519 /* Link the program object */ 9520 gl.linkProgram(m_po_id); 9521 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call faikled"); 9522 9523 /* Verify the linking has succeeded */ 9524 glw::GLint link_status = GL_FALSE; 9525 9526 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 9527 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed for GL_LINK_STATUS pname"); 9528 9529 if (link_status != GL_TRUE) 9530 { 9531 TCU_FAIL("Program linking failed"); 9532 } 9533 9534 /* Retrieve uniform locations */ 9535 m_po_lod_index_uniform_location = gl.getUniformLocation(m_po_id, "lod_index"); 9536 m_po_to_sampler_uniform_location = gl.getUniformLocation(m_po_id, "to_sampler"); 9537 9538 if (m_po_lod_index_uniform_location == -1) 9539 { 9540 TCU_FAIL("lod_index is considered an inactive uniform"); 9541 } 9542 9543 if (m_po_to_sampler_uniform_location == -1) 9544 { 9545 TCU_FAIL("to_sampler is considered an inactive uniform"); 9546 } 9547 } 9548 9549 /* Initializes all GL objects used by the test. */ 9550 void TextureViewTestBaseAndMaxLevels::initTest() 9551 { 9552 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9553 9554 /* Initialize textures */ 9555 initTextures(); 9556 9557 /* Initialize framebuffer and configure its attachments */ 9558 gl.genFramebuffers(1, &m_fbo_id); 9559 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed"); 9560 9561 /* Build the program we'll need for the test */ 9562 initProgram(); 9563 9564 /* Generate a vertex array object to execute the draw calls */ 9565 gl.genVertexArrays(1, &m_vao_id); 9566 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 9567 9568 gl.bindVertexArray(m_vao_id); 9569 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 9570 9571 /* Finally, allocate space for buffers that will be filled with rendered data */ 9572 m_layer_data_lod0 = new unsigned char[m_texture_width * m_texture_height * m_texture_n_components]; 9573 m_layer_data_lod1 = new unsigned char[(m_texture_width >> 1) * (m_texture_height >> 1) * m_texture_n_components]; 9574 9575 if (m_layer_data_lod0 == DE_NULL || m_layer_data_lod1 == DE_NULL) 9576 { 9577 TCU_FAIL("Out of memory"); 9578 } 9579 } 9580 9581 /** Initializes texture objects used by the test. */ 9582 void TextureViewTestBaseAndMaxLevels::initTextures() 9583 { 9584 /* Generate IDs first */ 9585 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9586 9587 gl.genTextures(1, &m_result_to_id); 9588 gl.genTextures(1, &m_to_id); 9589 gl.genTextures(1, &m_view_to_id); 9590 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed"); 9591 9592 /* Set up parent texture object's storage */ 9593 gl.bindTexture(GL_TEXTURE_2D, m_to_id); 9594 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 9595 9596 gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height); 9597 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed"); 9598 9599 /* Configure GL_TEXTURE_BASE_LEVEL parameter of the texture object as per test spec */ 9600 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2); 9601 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_BASE_LEVEL pname"); 9602 9603 /* Configure GL_TEXTURE_MAX_LEVEL parameter of the texture object as per test spec */ 9604 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); 9605 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_MAX_LEVEL pname"); 9606 9607 /* Set up mip-maps */ 9608 for (unsigned int n_mipmap = 0; n_mipmap < m_texture_n_levels; ++n_mipmap) 9609 { 9610 const float start_rgba[] = { /* As per test specification */ 9611 float(n_mipmap + 0) / 10.0f, float(n_mipmap + 1) / 10.0f, 9612 float(n_mipmap + 2) / 10.0f, float(n_mipmap + 3) / 10.0f 9613 }; 9614 const float end_rgba[] = { float(10 - (n_mipmap + 0)) / 10.0f, float(10 - (n_mipmap + 1)) / 10.0f, 9615 float(10 - (n_mipmap + 2)) / 10.0f, float(10 - (n_mipmap + 3)) / 10.0f }; 9616 9617 /* Allocate space for the layer data */ 9618 const unsigned int mipmap_height = m_texture_height >> n_mipmap; 9619 const unsigned int mipmap_width = m_texture_width >> n_mipmap; 9620 unsigned char* data = new unsigned char[mipmap_width * mipmap_height * m_texture_n_components]; 9621 9622 if (data == NULL) 9623 { 9624 TCU_FAIL("Out of memory"); 9625 } 9626 9627 /* Fill the buffer with layer data */ 9628 const unsigned int pixel_size = 4 /* components */; 9629 9630 for (unsigned int y = 0; y < mipmap_height; ++y) 9631 { 9632 unsigned char* row_data_ptr = data + mipmap_width * y * pixel_size; 9633 9634 for (unsigned int x = 0; x < mipmap_width; ++x) 9635 { 9636 const float lerp_factor = float(x) / float(mipmap_width); 9637 unsigned char* pixel_data_ptr = row_data_ptr + x * pixel_size; 9638 9639 for (unsigned int n_component = 0; n_component < m_texture_n_components; n_component++) 9640 { 9641 pixel_data_ptr[n_component] = (unsigned char)((start_rgba[n_component] * lerp_factor + 9642 end_rgba[n_component] * (1.0f - lerp_factor)) * 9643 255.0f); 9644 } 9645 } /* for (all columns) */ 9646 } /* for (all rows) */ 9647 9648 /* Upload the layer data */ 9649 gl.texSubImage2D(GL_TEXTURE_2D, n_mipmap, 0, /* xoffset */ 9650 0, /* yoffset */ 9651 mipmap_width, mipmap_height, GL_RGBA, GL_UNSIGNED_BYTE, data); 9652 9653 /* Release the data buffer */ 9654 delete[] data; 9655 9656 data = DE_NULL; 9657 9658 /* Make sure the API call finished successfully */ 9659 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed"); 9660 } /* for (all mip-maps) */ 9661 9662 /* Configure the texture view storage as per spec. */ 9663 gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, GL_RGBA8, 0, /* minlevel */ 9664 5, /* numlevels */ 9665 0, /* minlayer */ 9666 1); /* numlayers */ 9667 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed"); 9668 9669 /* Configure the texture view's GL_TEXTURE_BASE_LEVEL parameter */ 9670 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id); 9671 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 9672 9673 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); 9674 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_BASE_LEVEL pname"); 9675 9676 /* Configure the texture view's GL_TEXTURE_MAX_LEVEL parameter */ 9677 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); 9678 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_MAX_LEVEL pname"); 9679 9680 /* Set up result texture storage */ 9681 gl.bindTexture(GL_TEXTURE_2D, m_result_to_id); 9682 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 9683 9684 gl.texStorage2D(GL_TEXTURE_2D, 1, /* We will only attach the first level of the result texture to the FBO */ 9685 GL_RGBA8, m_view_width, m_view_height); 9686 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed"); 9687 } 9688 9689 /** Executes test iteration. 9690 * 9691 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 9692 */ 9693 tcu::TestNode::IterateResult TextureViewTestBaseAndMaxLevels::iterate() 9694 { 9695 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9696 9697 /* Only execute if GL_ARB_texture_view extension is supported */ 9698 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions(); 9699 9700 if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end()) 9701 { 9702 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported"); 9703 } 9704 9705 /* Initialize all GL objects necessary to run the test */ 9706 initTest(); 9707 9708 /* Activate test-wide program object */ 9709 gl.useProgram(m_po_id); 9710 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 9711 9712 /* Bind the data texture */ 9713 gl.activeTexture(GL_TEXTURE0); 9714 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed"); 9715 9716 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id); 9717 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 9718 9719 /* We will now use the program to sample the view's LOD 0 and LOD 1 and store 9720 * it in two separate textures. 9721 **/ 9722 for (unsigned int lod_level = 0; lod_level < 2; /* as per test spec */ 9723 ++lod_level) 9724 { 9725 /* Set up FBO attachments */ 9726 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id); 9727 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed"); 9728 9729 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_result_to_id, 9730 0); /* level */ 9731 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed"); 9732 9733 /* Update viewport configuration */ 9734 gl.viewport(0, /* x */ 9735 0, /* y */ 9736 m_view_width >> lod_level, m_view_height >> lod_level); 9737 9738 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed"); 9739 9740 /* Configure program object uniforms before we continue */ 9741 gl.uniform1i(m_po_lod_index_uniform_location, lod_level); 9742 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 9743 9744 /* Render a triangle strip. The program we're using will output a full-screen 9745 * quad with the sampled data */ 9746 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */); 9747 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 9748 9749 /* At the time of the draw call, we've modified the draw/read framebuffer binding 9750 * so that everything we render ends up in result texture. It's time to read it */ 9751 glw::GLvoid* result_data_ptr = (lod_level == 0) ? m_layer_data_lod0 : m_layer_data_lod1; 9752 9753 gl.readPixels(0, /* x */ 9754 0, /* y */ 9755 m_view_width >> lod_level, m_view_height >> lod_level, GL_RGBA, GL_UNSIGNED_BYTE, 9756 result_data_ptr); 9757 9758 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed"); 9759 } /* for (both LODs) */ 9760 9761 /* Now that we have both pieces of data, we can proceed with actual verification */ 9762 for (unsigned int lod_level = 0; lod_level < 2; ++lod_level) 9763 { 9764 /* NOTE: This code is a modification of initialization routine 9765 * found in initTextures() 9766 */ 9767 const unsigned char epsilon = 1; 9768 const glw::GLvoid* layer_data_ptr = (lod_level == 0) ? m_layer_data_lod0 : m_layer_data_lod1; 9769 const unsigned int layer_height = m_view_height >> lod_level; 9770 const unsigned int layer_width = m_view_width >> lod_level; 9771 const unsigned int pixel_size = 4 /* components */; 9772 const unsigned int view_minimum_level = 1; /* THS SHOULD BE 1 */ 9773 const float start_rgba[] = { 9774 /* As per test specification */ 9775 float(lod_level + view_minimum_level + 0) / 10.0f, float(lod_level + view_minimum_level + 1) / 10.0f, 9776 float(lod_level + view_minimum_level + 2) / 10.0f, float(lod_level + view_minimum_level + 3) / 10.0f 9777 }; 9778 const float end_rgba[] = { float(10 - (lod_level + view_minimum_level + 0)) / 10.0f, 9779 float(10 - (lod_level + view_minimum_level + 1)) / 10.0f, 9780 float(10 - (lod_level + view_minimum_level + 2)) / 10.0f, 9781 float(10 - (lod_level + view_minimum_level + 3)) / 10.0f }; 9782 9783 for (unsigned int y = 0; y < layer_height; ++y) 9784 { 9785 const unsigned char* row_data_ptr = (const unsigned char*)layer_data_ptr + layer_width * y * pixel_size; 9786 9787 for (unsigned int x = 0; x < layer_width; ++x) 9788 { 9789 const float lerp_factor = float(x) / float(layer_width); 9790 const unsigned char* pixel_data_ptr = row_data_ptr + x * pixel_size; 9791 9792 const unsigned char expected_data[] = { 9793 (unsigned char)((start_rgba[0] * lerp_factor + end_rgba[0] * (1.0f - lerp_factor)) * 255.0f), 9794 (unsigned char)((start_rgba[1] * lerp_factor + end_rgba[1] * (1.0f - lerp_factor)) * 255.0f), 9795 (unsigned char)((start_rgba[2] * lerp_factor + end_rgba[2] * (1.0f - lerp_factor)) * 255.0f), 9796 (unsigned char)((start_rgba[3] * lerp_factor + end_rgba[3] * (1.0f - lerp_factor)) * 255.0f) 9797 }; 9798 9799 if (de::abs(expected_data[0] - pixel_data_ptr[0]) > epsilon || 9800 de::abs(expected_data[1] - pixel_data_ptr[1]) > epsilon || 9801 de::abs(expected_data[2] - pixel_data_ptr[2]) > epsilon || 9802 de::abs(expected_data[3] - pixel_data_ptr[3]) > epsilon) 9803 { 9804 m_testCtx.getLog() << tcu::TestLog::Message << "Found an invalid texel at (" << x << ", " << y 9805 << ");" 9806 " expected value:" 9807 "(" 9808 << expected_data[0] << ", " << expected_data[1] << ", " << expected_data[2] 9809 << ", " << expected_data[3] << ")" 9810 ", found:" 9811 "(" 9812 << pixel_data_ptr[0] << ", " << pixel_data_ptr[1] << ", " << pixel_data_ptr[2] 9813 << ", " << pixel_data_ptr[3] << ")" << tcu::TestLog::EndMessage; 9814 9815 TCU_FAIL("Rendered data does not match expected pixel data"); 9816 } /* if (pixel mismatch found) */ 9817 } /* for (all columns) */ 9818 } /* for (all rows) */ 9819 } /* for (both LODs) */ 9820 9821 /* Test case passed */ 9822 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 9823 9824 return STOP; 9825 } 9826 9827 /** Constructor. 9828 * 9829 * @param context Rendering context. 9830 **/ 9831 TextureViewTestReferenceCounting::TextureViewTestReferenceCounting(deqp::Context& context) 9832 : TestCase(context, "reference_counting", 9833 "Makes sure that sampling from views, for which the parent texture object " 9834 "has already been deleted, works correctly.") 9835 , m_bo_id(0) 9836 , m_parent_to_id(0) 9837 , m_po_id(0) 9838 , m_po_expected_texel_uniform_location(-1) 9839 , m_po_lod_uniform_location(-1) 9840 , m_vao_id(0) 9841 , m_view_to_id(0) 9842 , m_view_view_to_id(0) 9843 , m_vs_id(0) 9844 , m_texture_height(64) 9845 , m_texture_n_levels(7) 9846 , m_texture_width(64) 9847 { 9848 /* Configure a vector storing unique colors that should be used 9849 * for filling subsequent mip-maps of parent texture */ 9850 m_mipmap_colors.push_back(_norm_vec4(123, 34, 56, 78)); 9851 m_mipmap_colors.push_back(_norm_vec4(234, 45, 67, 89)); 9852 m_mipmap_colors.push_back(_norm_vec4(34, 56, 78, 90)); 9853 m_mipmap_colors.push_back(_norm_vec4(45, 67, 89, 1)); 9854 m_mipmap_colors.push_back(_norm_vec4(56, 78, 90, 123)); 9855 m_mipmap_colors.push_back(_norm_vec4(67, 89, 1, 234)); 9856 m_mipmap_colors.push_back(_norm_vec4(78, 90, 12, 34)); 9857 9858 DE_ASSERT(m_mipmap_colors.size() == m_texture_n_levels); 9859 } 9860 9861 /** Deinitializes all GL objects that may have been created during test 9862 * execution. 9863 **/ 9864 void TextureViewTestReferenceCounting::deinit() 9865 { 9866 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9867 9868 if (m_bo_id != 0) 9869 { 9870 gl.deleteBuffers(1, &m_bo_id); 9871 9872 m_bo_id = 0; 9873 } 9874 9875 if (m_parent_to_id != 0) 9876 { 9877 gl.deleteTextures(1, &m_parent_to_id); 9878 9879 m_parent_to_id = 0; 9880 } 9881 9882 if (m_po_id != 0) 9883 { 9884 gl.deleteProgram(m_po_id); 9885 9886 m_po_id = 0; 9887 } 9888 9889 if (m_vao_id != 0) 9890 { 9891 gl.deleteVertexArrays(1, &m_vao_id); 9892 9893 m_vao_id = 0; 9894 } 9895 9896 if (m_view_to_id != 0) 9897 { 9898 gl.deleteTextures(1, &m_view_to_id); 9899 9900 m_view_to_id = 0; 9901 } 9902 9903 if (m_view_view_to_id != 0) 9904 { 9905 gl.deleteTextures(1, &m_view_view_to_id); 9906 9907 m_view_view_to_id = 0; 9908 } 9909 9910 if (m_vs_id != 0) 9911 { 9912 gl.deleteShader(m_vs_id); 9913 9914 m_vs_id = 0; 9915 } 9916 } 9917 9918 /* Initializes a program object to be used during the test. */ 9919 void TextureViewTestReferenceCounting::initProgram() 9920 { 9921 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9922 9923 /* Create program & shader object IDs */ 9924 m_po_id = gl.createProgram(); 9925 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed"); 9926 9927 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 9928 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed"); 9929 9930 /* Set vertex shader body */ 9931 const char* vs_body = "#version 400\n" 9932 "\n" 9933 "uniform vec4 expected_texel;\n" 9934 "uniform int lod;\n" 9935 "uniform sampler2D sampler;\n" 9936 "\n" 9937 "out int has_passed;\n" 9938 "\n" 9939 "void main()\n" 9940 "{\n" 9941 " vec4 data = textureLod(sampler, vec2(0.5, 0.5), lod);\n" 9942 " const float epsilon = 1.0 / 256.0;\n" 9943 "\n" 9944 " if (abs(data.r - expected_texel.r) > epsilon ||\n" 9945 " abs(data.g - expected_texel.g) > epsilon ||\n" 9946 " abs(data.b - expected_texel.b) > epsilon ||\n" 9947 " abs(data.a - expected_texel.a) > epsilon)\n" 9948 " {\n" 9949 " has_passed = 0;\n" 9950 " }\n" 9951 " else\n" 9952 " {\n" 9953 " has_passed = 1;\n" 9954 " }\n" 9955 "}\n"; 9956 9957 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, NULL /* length */); 9958 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed"); 9959 9960 /* Configure XFB */ 9961 const char* varying_name = "has_passed"; 9962 9963 gl.transformFeedbackVaryings(m_po_id, 1 /* count */, &varying_name, GL_INTERLEAVED_ATTRIBS); 9964 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed"); 9965 9966 /* Attach the shader object to the program */ 9967 gl.attachShader(m_po_id, m_vs_id); 9968 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed"); 9969 9970 /* Compile the shader */ 9971 gl.compileShader(m_vs_id); 9972 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 9973 9974 /* Make sure the compilation has succeeded */ 9975 glw::GLint compile_status = GL_FALSE; 9976 9977 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status); 9978 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 9979 9980 if (compile_status != GL_TRUE) 9981 { 9982 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed" << tcu::TestLog::EndMessage; 9983 } 9984 9985 /* Link the program object */ 9986 gl.linkProgram(m_po_id); 9987 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed"); 9988 9989 /* Make sure the program object has linked successfully */ 9990 glw::GLint link_status = GL_FALSE; 9991 9992 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 9993 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed"); 9994 9995 if (link_status != GL_TRUE) 9996 { 9997 TCU_FAIL("Program linking failed"); 9998 } 9999 10000 /* Retrieve uniform locations */ 10001 m_po_expected_texel_uniform_location = gl.getUniformLocation(m_po_id, "expected_texel"); 10002 m_po_lod_uniform_location = gl.getUniformLocation(m_po_id, "lod"); 10003 10004 if (m_po_expected_texel_uniform_location == -1) 10005 { 10006 TCU_FAIL("expected_texel is considered an inactive uniform which is invalid"); 10007 } 10008 10009 if (m_po_lod_uniform_location == -1) 10010 { 10011 TCU_FAIL("lod is considered an inactive uniform which is invalid"); 10012 } 10013 } 10014 10015 /** Initializes all texture objects and all views used by the test. */ 10016 void TextureViewTestReferenceCounting::initTextures() 10017 { 10018 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 10019 10020 /* Generate texture IDs */ 10021 gl.genTextures(1, &m_parent_to_id); 10022 gl.genTextures(1, &m_view_to_id); 10023 gl.genTextures(1, &m_view_view_to_id); 10024 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed"); 10025 10026 /* Set up parent texture object A */ 10027 gl.bindTexture(GL_TEXTURE_2D, m_parent_to_id); 10028 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 10029 10030 gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height); 10031 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed"); 10032 10033 /* Set up view B */ 10034 gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_parent_to_id, GL_RGBA8, 0, /* minlevel */ 10035 m_texture_n_levels, 0, /* minlayer */ 10036 1); /* numlayers */ 10037 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed"); 10038 10039 /* Set up view C */ 10040 gl.textureView(m_view_view_to_id, GL_TEXTURE_2D, m_view_to_id, GL_RGBA8, 0, /* minlevel */ 10041 m_texture_n_levels, 0, /* minlayer */ 10042 1); /* numlayers */ 10043 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed"); 10044 10045 /* Fill parent texture mip-maps with different static colors */ 10046 unsigned char* texel_data = new unsigned char[m_texture_width * m_texture_height * 4 /* components */]; 10047 10048 for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); n_mipmap++) 10049 { 10050 const _norm_vec4& mipmap_color = m_mipmap_colors[n_mipmap]; 10051 const unsigned int mipmap_height = m_texture_height >> n_mipmap; 10052 const unsigned int mipmap_width = m_texture_width >> n_mipmap; 10053 10054 for (unsigned int n_texel = 0; n_texel < mipmap_height * mipmap_width; ++n_texel) 10055 { 10056 unsigned char* texel_data_ptr = texel_data + n_texel * sizeof(mipmap_color.rgba); 10057 10058 memcpy(texel_data_ptr, mipmap_color.rgba, sizeof(mipmap_color.rgba)); 10059 } /* for (all relevant mip-map texels) */ 10060 10061 /* Upload new mip-map contents */ 10062 gl.texSubImage2D(GL_TEXTURE_2D, n_mipmap, 0, /* xoffset */ 10063 0, /* yoffset */ 10064 m_texture_width >> n_mipmap, m_texture_height >> n_mipmap, GL_RGBA, GL_UNSIGNED_BYTE, 10065 texel_data); 10066 10067 if (gl.getError() != GL_NO_ERROR) 10068 { 10069 delete[] texel_data; 10070 texel_data = NULL; 10071 10072 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed"); 10073 } 10074 } /* for (all mip-maps) */ 10075 10076 delete[] texel_data; 10077 texel_data = NULL; 10078 } 10079 10080 /* Initialize all GL objects necessary to run the test */ 10081 void TextureViewTestReferenceCounting::initTest() 10082 { 10083 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 10084 10085 /* Initialize all texture objects */ 10086 initTextures(); 10087 10088 /* Initialize test program object */ 10089 initProgram(); 10090 10091 /* Initialize XFB */ 10092 initXFB(); 10093 10094 /* Generate and bind a vertex array object, since we'll be doing a number of 10095 * draw calls later in the test */ 10096 gl.genVertexArrays(1, &m_vao_id); 10097 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 10098 10099 gl.bindVertexArray(m_vao_id); 10100 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 10101 } 10102 10103 /** Initializes a buffer object later used for Transform Feedback and binds 10104 * it to both general and indexed Transform Feedback binding points. 10105 **/ 10106 void TextureViewTestReferenceCounting::initXFB() 10107 { 10108 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 10109 10110 /* Sanity checks */ 10111 DE_ASSERT(m_po_id != 0); 10112 10113 /* Generate a buffer object we'll use for Transform Feedback */ 10114 gl.genBuffers(1, &m_bo_id); 10115 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 10116 10117 /* Set up buffer object storage. We need it to be large enough to hold 10118 * sizeof(glw::GLint) per mipmap level */ 10119 const glw::GLint bo_size = (glw::GLint)(sizeof(glw::GLint) * m_mipmap_colors.size()); 10120 10121 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id); 10122 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 10123 10124 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id); 10125 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 10126 10127 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL, /* data */ 10128 GL_STATIC_DRAW); 10129 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 10130 } 10131 10132 /** Executes test iteration. 10133 * 10134 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 10135 */ 10136 tcu::TestNode::IterateResult TextureViewTestReferenceCounting::iterate() 10137 { 10138 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 10139 10140 /* Carry on only if GL_ARB_texture_view extension is supported */ 10141 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view")) 10142 { 10143 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported"); 10144 } 10145 10146 /* Initialize all GL objects used for the test */ 10147 initTest(); 10148 10149 /* Make sure texture unit 0 is currently active */ 10150 gl.activeTexture(GL_TEXTURE0); 10151 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed."); 10152 10153 /* Activate the test program object */ 10154 gl.useProgram(m_po_id); 10155 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 10156 10157 /* Run the test in three iterations: 10158 * 10159 * - Sample both the texture and all the views; once that's finished 10160 * successfully, delete the parent texture. 10161 * - Sample both views; once that's finished successfully, delete 10162 * the first of the views; 10163 * - Sample the only remaining view and make sure all mip-maps store 10164 * valid colors. 10165 **/ 10166 for (unsigned int n_iteration = 0; n_iteration < 3; /* iterations in total */ 10167 n_iteration++) 10168 { 10169 glw::GLuint to_ids_to_sample[3] = { 0, 0, 0 }; 10170 10171 /* Configure IDs of textures we need to validate for current iteration */ 10172 switch (n_iteration) 10173 { 10174 case 0: 10175 { 10176 to_ids_to_sample[0] = m_parent_to_id; 10177 to_ids_to_sample[1] = m_view_to_id; 10178 to_ids_to_sample[2] = m_view_view_to_id; 10179 10180 break; 10181 } 10182 10183 case 1: 10184 { 10185 to_ids_to_sample[0] = m_view_to_id; 10186 to_ids_to_sample[1] = m_view_view_to_id; 10187 10188 break; 10189 } 10190 10191 case 2: 10192 { 10193 to_ids_to_sample[0] = m_view_view_to_id; 10194 10195 break; 10196 } 10197 10198 default: 10199 TCU_FAIL("Invalid iteration index"); 10200 } /* switch (n_iteration) */ 10201 10202 /* Iterate through all texture objects of our concern */ 10203 for (unsigned int n_texture = 0; n_texture < sizeof(to_ids_to_sample) / sizeof(to_ids_to_sample[0]); 10204 n_texture++) 10205 { 10206 glw::GLint to_id = to_ids_to_sample[n_texture]; 10207 10208 if (to_id == 0) 10209 { 10210 /* No texture object to sample from. */ 10211 continue; 10212 } 10213 10214 /* Bind the texture object of our interest to GL_TEXTURE_2D */ 10215 gl.bindTexture(GL_TEXTURE_2D, to_id); 10216 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 10217 10218 /* Start XFB */ 10219 gl.beginTransformFeedback(GL_POINTS); 10220 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 10221 10222 /* Iterate through all mip-maps of the texture we're currently sampling */ 10223 for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); ++n_mipmap) 10224 { 10225 const _norm_vec4& expected_mipmap_color = m_mipmap_colors[n_mipmap]; 10226 10227 /* Update uniforms first */ 10228 gl.uniform4f(m_po_expected_texel_uniform_location, (float)(expected_mipmap_color.rgba[0]) / 255.0f, 10229 (float)(expected_mipmap_color.rgba[1]) / 255.0f, 10230 (float)(expected_mipmap_color.rgba[2]) / 255.0f, 10231 (float)(expected_mipmap_color.rgba[3]) / 255.0f); 10232 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f() call failed."); 10233 10234 gl.uniform1i(m_po_lod_uniform_location, n_mipmap); 10235 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 10236 10237 /* Draw a single point. That'll feed the XFB buffer object with a single bool 10238 * indicating if the test passed for the mip-map, or not */ 10239 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 10240 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 10241 } /* for (all mip-maps) */ 10242 10243 /* We're done - close XFB */ 10244 gl.endTransformFeedback(); 10245 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 10246 10247 /* How did the sampling go? Map the buffer object containing the run 10248 * results into process space. 10249 */ 10250 const glw::GLint* run_results_ptr = 10251 (const glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 10252 10253 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 10254 10255 if (run_results_ptr == NULL) 10256 { 10257 TCU_FAIL("Pointer to mapped buffer object storage is NULL."); 10258 } 10259 10260 /* Make sure all mip-maps were sampled successfully */ 10261 for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); ++n_mipmap) 10262 { 10263 if (run_results_ptr[n_mipmap] != 1) 10264 { 10265 /* Make sure the TF BO is unmapped before we throw the exception */ 10266 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 10267 10268 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled for mip-map level [" 10269 << n_mipmap << "] and iteration [" << n_iteration << "]" 10270 << tcu::TestLog::EndMessage; 10271 10272 TCU_FAIL("Mip-map sampling failed."); 10273 } 10274 } /* for (all mip-maps) */ 10275 10276 /* Good to unmap the buffer object at this point */ 10277 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 10278 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 10279 } /* for (all initialized texture objects) */ 10280 10281 /* Now that we're done with the iteration, we should delete iteration-specific texture 10282 * object. 10283 */ 10284 switch (n_iteration) 10285 { 10286 case 0: 10287 { 10288 gl.deleteTextures(1, &m_parent_to_id); 10289 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed."); 10290 10291 m_parent_to_id = 0; 10292 break; 10293 } 10294 10295 case 1: 10296 { 10297 gl.deleteTextures(1, &m_view_to_id); 10298 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed."); 10299 10300 m_view_to_id = 0; 10301 break; 10302 } 10303 10304 case 2: 10305 { 10306 gl.deleteTextures(1, &m_view_view_to_id); 10307 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed."); 10308 10309 m_view_view_to_id = 0; 10310 break; 10311 } 10312 10313 default: 10314 TCU_FAIL("Invalid iteration index"); 10315 } /* switch (n_iteration) */ 10316 } /* for (all iterations) */ 10317 10318 /* Test case passed */ 10319 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 10320 10321 return STOP; 10322 } 10323 10324 /** Constructor. 10325 * 10326 * @param context Rendering context. 10327 **/ 10328 TextureViewTests::TextureViewTests(deqp::Context& context) 10329 : TestCaseGroup(context, "texture_view", "Verifies \"texture view\" functionality") 10330 { 10331 /* Left blank on purpose */ 10332 } 10333 10334 /** Initializes a texture_storage_multisample test group. 10335 * 10336 **/ 10337 void TextureViewTests::init(void) 10338 { 10339 addChild(new TextureViewTestGetTexParameter(m_context)); 10340 addChild(new TextureViewTestErrors(m_context)); 10341 addChild(new TextureViewTestViewSampling(m_context)); 10342 addChild(new TextureViewTestViewClasses(m_context)); 10343 addChild(new TextureViewTestCoherency(m_context)); 10344 addChild(new TextureViewTestBaseAndMaxLevels(m_context)); 10345 addChild(new TextureViewTestReferenceCounting(m_context)); 10346 } 10347 10348 } /* glcts namespace */ 10349