1 /*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2015-2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ /*! 20 * \file 21 * \brief 22 */ /*-------------------------------------------------------------------*/ 23 24 #include "gl4cCopyImageTests.hpp" 25 26 #include "gluDefs.hpp" 27 #include "gluStrUtil.hpp" 28 #include "glwEnums.hpp" 29 #include "glwFunctions.hpp" 30 #include "tcuFloat.hpp" 31 #include "tcuTestLog.hpp" 32 33 #include <algorithm> 34 #include <iomanip> 35 #include <sstream> 36 37 #include "deMath.h" 38 39 /* There are far too much combinations specified for FunctionalTest. 40 * 41 * Following flags controls what is enabled. Set as 1 to enable 42 * all test case from given category, 0 otherwise. 43 * 44 * By default everything is disabled - which still gives 14560 test cases. 45 * 46 * ALL_FORMAT - selects all internal formats, 61 x 61 47 * ALL_TARGETS - selects all valid targets, 10 x 10 48 * ALL_IMG_DIM - selects all image dimmensions, 9 x 9 49 * ALL_REG_DIM - selects all region dimmensions, 7 x 7 50 * ALL_REG_POS - selects all region positions, like left-top corner, 8 x 8 51 */ 52 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS 0 53 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS 0 54 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_IMG_DIM 0 55 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_DIM 0 56 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS 0 57 58 /* The following flags controls if workarounds are enabled */ 59 #define COPY_IMAGE_WRKARD_FORMATS 0 60 61 using namespace glw; 62 63 namespace gl4cts 64 { 65 namespace CopyImage 66 { 67 /** Various utilities used by all tests 68 * 69 **/ 70 class Utils 71 { 72 public: 73 /* Routines */ 74 static bool areFormatsCompatible(glw::GLenum src, glw::GLenum dst); 75 76 static bool comparePixels(glw::GLenum left_internal_format, const glw::GLdouble& left_red, 77 const glw::GLdouble& left_green, const glw::GLdouble& left_blue, 78 const glw::GLdouble& left_alpha, glw::GLenum right_internal_format, 79 const glw::GLdouble& right_red, const glw::GLdouble& right_green, 80 const glw::GLdouble& right_blue, const glw::GLdouble& right_alpha); 81 82 static bool comparePixels(glw::GLuint left_pixel_size, const glw::GLubyte* left_pixel_data, 83 glw::GLuint right_pixel_size, const glw::GLubyte* right_pixel_data); 84 85 static void deleteTexture(deqp::Context& context, glw::GLenum target, glw::GLuint name); 86 87 static bool isTargetMultilayer(glw::GLenum target); 88 static bool isTargetMultilevel(glw::GLenum target); 89 static bool isTargetMultisampled(glw::GLenum target); 90 91 static glw::GLuint generateTexture(deqp::Context& context, glw::GLenum target); 92 93 static void maskPixelForFormat(glw::GLenum internal_format, glw::GLubyte* pixel); 94 95 static glw::GLdouble getEpsilon(glw::GLenum internal_format); 96 static glw::GLuint getPixelSizeForFormat(glw::GLenum internal_format); 97 static glw::GLenum getFormat(glw::GLenum internal_format); 98 static glw::GLuint getNumberOfChannels(glw::GLenum internal_format); 99 100 static std::string getPixelString(glw::GLenum internal_format, const glw::GLubyte* pixel); 101 102 static glw::GLenum getType(glw::GLenum internal_format); 103 static void makeTextureComplete(deqp::Context& context, glw::GLenum target, glw::GLuint id, glw::GLint base_level, 104 glw::GLint max_level); 105 106 static glw::GLuint prepareCompressedTex(deqp::Context& context, glw::GLenum target, glw::GLenum internal_format); 107 108 static glw::GLuint prepareMultisampleTex(deqp::Context& context, glw::GLenum target, glw::GLsizei n_samples); 109 110 static glw::GLuint prepareRenderBuffer(deqp::Context& context, glw::GLenum internal_format); 111 112 static glw::GLuint prepareTex16x16x6(deqp::Context& context, glw::GLenum target, glw::GLenum internal_format, 113 glw::GLenum format, glw::GLenum type, glw::GLuint& out_buf_id); 114 115 static void prepareTexture(deqp::Context& context, glw::GLuint name, glw::GLenum target, 116 glw::GLenum internal_format, glw::GLenum format, glw::GLenum type, glw::GLuint level, 117 glw::GLuint width, glw::GLuint height, glw::GLuint depth, const glw::GLvoid* pixels, 118 glw::GLuint& out_buf_id); 119 120 static glw::GLenum transProxyToRealTarget(glw::GLenum target); 121 static glw::GLenum transRealToBindTarget(glw::GLenum target); 122 123 static void readChannel(glw::GLenum type, glw::GLuint channel, const glw::GLubyte* pixel, glw::GLdouble& out_value); 124 125 static void writeChannel(glw::GLenum type, glw::GLuint channel, glw::GLdouble value, glw::GLubyte* pixel); 126 127 static void packPixel(glw::GLenum internal_format, glw::GLenum type, glw::GLdouble red, glw::GLdouble green, 128 glw::GLdouble blue, glw::GLdouble alpha, glw::GLubyte* out_pixel); 129 130 static void unpackPixel(glw::GLenum format, glw::GLenum type, const glw::GLubyte* pixel, glw::GLdouble& out_red, 131 glw::GLdouble& out_green, glw::GLdouble& out_blue, glw::GLdouble& out_alpha); 132 133 static bool unpackAndComaprePixels(glw::GLenum left_format, glw::GLenum left_type, glw::GLenum left_internal_format, 134 const glw::GLubyte* left_pixel, glw::GLenum right_format, glw::GLenum right_type, 135 glw::GLenum right_internal_format, const glw::GLubyte* right_pixel); 136 137 static inline bool roundComponent(glw::GLenum internal_format, glw::GLenum component, glw::GLdouble& value); 138 }; 139 140 /* Global constants */ 141 static const GLenum s_internal_formats[] = { 142 /* R8 */ 143 GL_R8, GL_R8I, GL_R8UI, GL_R8_SNORM, 144 145 /* R16 */ 146 GL_R16, GL_R16F, GL_R16I, GL_R16UI, GL_R16_SNORM, 147 148 /* R32 */ 149 GL_R32F, GL_R32I, GL_R32UI, 150 151 /* RG8 */ 152 GL_RG8, GL_RG8I, GL_RG8UI, GL_RG8_SNORM, 153 154 /* RG16 */ 155 GL_RG16, GL_RG16F, GL_RG16I, GL_RG16UI, GL_RG16_SNORM, 156 157 /* RG32 */ 158 GL_RG32F, GL_RG32I, GL_RG32UI, 159 160 /* RGB8 */ 161 GL_RGB8, GL_RGB8I, GL_RGB8UI, GL_RGB8_SNORM, 162 163 /* RGB16 */ 164 GL_RGB16, GL_RGB16F, GL_RGB16I, GL_RGB16UI, GL_RGB16_SNORM, 165 166 /* RGB32 */ 167 GL_RGB32F, GL_RGB32I, GL_RGB32UI, 168 169 /* RGBA8 */ 170 GL_RGBA8, GL_RGBA8I, GL_RGBA8UI, GL_RGBA8_SNORM, 171 172 /* RGBA16 */ 173 GL_RGBA16, GL_RGBA16F, GL_RGBA16I, GL_RGBA16UI, GL_RGBA16_SNORM, 174 175 /* RGBA32 */ 176 GL_RGBA32F, GL_RGBA32I, GL_RGBA32UI, 177 178 /* 8 */ 179 GL_R3_G3_B2, GL_RGBA2, 180 181 /* 12 */ 182 GL_RGB4, 183 184 /* 15 */ 185 GL_RGB5, 186 187 /* 16 */ 188 GL_RGBA4, GL_RGB5_A1, 189 190 /* 30 */ 191 GL_RGB10, 192 193 /* 32 */ 194 GL_RGB10_A2, GL_RGB10_A2UI, GL_R11F_G11F_B10F, GL_RGB9_E5, 195 196 /* 36 */ 197 GL_RGB12, 198 199 /* 48 */ 200 GL_RGBA12, 201 }; 202 203 static const GLenum s_invalid_targets[] = { 204 GL_TEXTURE_BUFFER, 205 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 206 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 207 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 208 GL_TEXTURE_CUBE_MAP_POSITIVE_X, 209 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 210 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 211 GL_PROXY_TEXTURE_1D, 212 GL_PROXY_TEXTURE_1D_ARRAY, 213 GL_PROXY_TEXTURE_2D, 214 GL_PROXY_TEXTURE_2D_ARRAY, 215 GL_PROXY_TEXTURE_2D_MULTISAMPLE, 216 GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, 217 GL_PROXY_TEXTURE_3D, 218 GL_PROXY_TEXTURE_CUBE_MAP, 219 GL_PROXY_TEXTURE_CUBE_MAP_ARRAY, 220 GL_PROXY_TEXTURE_RECTANGLE, 221 }; 222 223 static const GLenum s_valid_targets[] = { 224 GL_RENDERBUFFER, 225 GL_TEXTURE_1D, 226 GL_TEXTURE_1D_ARRAY, 227 GL_TEXTURE_2D, 228 GL_TEXTURE_2D_ARRAY, 229 GL_TEXTURE_2D_MULTISAMPLE, 230 GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 231 GL_TEXTURE_3D, 232 GL_TEXTURE_CUBE_MAP, 233 GL_TEXTURE_CUBE_MAP_ARRAY, 234 GL_TEXTURE_RECTANGLE, 235 }; 236 237 static const GLuint s_n_internal_formats = sizeof(s_internal_formats) / sizeof(s_internal_formats[0]); 238 static const GLuint s_n_invalid_targets = sizeof(s_invalid_targets) / sizeof(s_invalid_targets[0]); 239 static const GLuint s_n_valid_targets = sizeof(s_valid_targets) / sizeof(s_valid_targets[0]); 240 241 /** 242 * Pixel compatibility depends on pixel size. However value returned by getPixelSizeForFormat 243 * needs some refinements 244 * 245 * @param internal_format Internal format of image 246 * 247 * @return Size of pixel for compatibility checks 248 **/ 249 GLuint getPixelSizeForCompatibilityVerification(GLenum internal_format) 250 { 251 GLuint size = Utils::getPixelSizeForFormat(internal_format); 252 253 switch (internal_format) 254 { 255 case GL_RGBA2: 256 size = 1; 257 break; 258 default: 259 break; 260 } 261 262 return size; 263 } 264 265 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS == 0 266 267 /** Filters out formats that should not be tested by FunctionalTest 268 * 269 * @param format Internal format 270 * 271 * @return true if format should be tested, false otherwise 272 **/ 273 bool filterFormats(GLenum format) 274 { 275 bool result = true; 276 277 switch (format) 278 { 279 /* R8 */ 280 case GL_R8I: 281 case GL_R8UI: 282 case GL_R8_SNORM: 283 284 /* R16 */ 285 case GL_R16: 286 case GL_R16F: 287 case GL_R16I: 288 case GL_R16UI: 289 case GL_R16_SNORM: 290 291 /* R32 */ 292 case GL_R32F: 293 case GL_R32I: 294 case GL_R32UI: 295 296 /* RG8 */ 297 case GL_RG8: 298 case GL_RG8I: 299 case GL_RG8UI: 300 case GL_RG8_SNORM: 301 302 /* RG16 */ 303 case GL_RG16: 304 case GL_RG16F: 305 case GL_RG16I: 306 case GL_RG16UI: 307 case GL_RG16_SNORM: 308 309 /* RG32 */ 310 case GL_RG32F: 311 case GL_RG32I: 312 case GL_RG32UI: 313 314 /* RGB8 */ 315 case GL_RGB8: 316 case GL_RGB8I: 317 case GL_RGB8UI: 318 case GL_RGB8_SNORM: 319 320 /* RGB16 */ 321 case GL_RGB16: 322 case GL_RGB16F: 323 case GL_RGB16I: 324 case GL_RGB16UI: 325 case GL_RGB16_SNORM: 326 327 /* RGB32 */ 328 case GL_RGB32I: 329 case GL_RGB32UI: 330 331 /* RGBA8 */ 332 case GL_RGBA8: 333 case GL_RGBA8I: 334 case GL_RGBA8UI: 335 case GL_RGBA8_SNORM: 336 337 /* RGBA16 */ 338 case GL_RGBA16: 339 case GL_RGBA16F: 340 case GL_RGBA16I: 341 case GL_RGBA16UI: 342 case GL_RGBA16_SNORM: 343 344 /* RGBA32 */ 345 case GL_RGBA32F: 346 case GL_RGBA32I: 347 case GL_RGBA32UI: 348 result = false; 349 break; 350 351 default: 352 result = true; 353 break; 354 } 355 356 return result; 357 } 358 359 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS */ 360 361 /** Checks if two internal_formats are compatible 362 * 363 * @param src Internal format of source image 364 * @param dst Internal format of destination image 365 * 366 * @return true for compatible formats, false otherwise 367 **/ 368 bool Utils::areFormatsCompatible(glw::GLenum src, glw::GLenum dst) 369 { 370 const GLuint dst_size = getPixelSizeForCompatibilityVerification(dst); 371 const GLuint src_size = getPixelSizeForCompatibilityVerification(src); 372 373 if (dst_size != src_size) 374 { 375 return false; 376 } 377 378 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS == 0 379 380 if ((false == filterFormats(src)) || (false == filterFormats(dst))) 381 { 382 return false; 383 } 384 385 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS */ 386 387 if (src != dst) 388 { 389 if ((GL_R3_G3_B2 == dst) || (GL_R3_G3_B2 == src) || (GL_RGBA2 == dst) || (GL_RGBA2 == src) || 390 (GL_RGBA4 == dst) || (GL_RGBA4 == src) || (GL_RGB5_A1 == dst) || (GL_RGB5_A1 == src) || (GL_RGB10 == dst) || 391 (GL_RGB10 == src)) 392 { 393 return false; 394 } 395 } 396 397 #if COPY_IMAGE_WRKARD_FORMATS 398 399 if ((GL_RGB10_A2 == src) && (GL_R11F_G11F_B10F == dst) || (GL_RGB10_A2 == src) && (GL_RGB9_E5 == dst) || 400 (GL_RGB10_A2UI == src) && (GL_R11F_G11F_B10F == dst) || (GL_RGB10_A2UI == src) && (GL_RGB9_E5 == dst) || 401 (GL_RGB9_E5 == src) && (GL_RGB10_A2 == dst) || (GL_RGB9_E5 == src) && (GL_RGB10_A2UI == dst) || 402 (GL_R11F_G11F_B10F == src) && (GL_RGB10_A2 == dst) || (GL_R11F_G11F_B10F == src) && (GL_RGB10_A2UI == dst)) 403 { 404 return false; 405 } 406 407 #endif /* COPY_IMAGE_WRKARD_FORMATS */ 408 409 if (2 == dst_size) 410 { 411 if (src == dst) 412 { 413 return true; 414 } 415 416 if (((GL_RGB4 == src) && (GL_RGB4 != dst)) || ((GL_RGB4 != src) && (GL_RGB4 == dst)) || 417 ((GL_RGB5 == src) && (GL_RGB5 != dst)) || ((GL_RGB5 != src) && (GL_RGB5 == dst))) 418 { 419 return false; 420 } 421 422 return true; 423 } 424 425 if (4 == dst_size) 426 { 427 if (src == dst) 428 { 429 return true; 430 } 431 432 return true; 433 } 434 435 return true; 436 } 437 438 /** Compare two pixels 439 * 440 * @param left_internal_format Internal format of left image 441 * @param left_red Red channel of left image 442 * @param left_green Green channel of left image 443 * @param left_blue Blue channel of left image 444 * @param left_alpha Alpha channel of left image 445 * @param right_internal_format Internal format of right image 446 * @param right_red Red channel of right image 447 * @param right_green Green channel of right image 448 * @param right_blue Blue channel of right image 449 * @param right_alpha Alpha channel of right image 450 * 451 * @return true if pixels match, false otherwise 452 **/ 453 bool Utils::comparePixels(GLenum left_internal_format, const GLdouble& left_red, const GLdouble& left_green, 454 const GLdouble& left_blue, const GLdouble& left_alpha, GLenum right_internal_format, 455 const GLdouble& right_red, const GLdouble& right_green, const GLdouble& right_blue, 456 const GLdouble& right_alpha) 457 { 458 const GLuint left_n_channels = getNumberOfChannels(left_internal_format); 459 const GLuint right_n_channels = getNumberOfChannels(right_internal_format); 460 const GLuint n_channels = (left_n_channels >= right_n_channels) ? right_n_channels : left_n_channels; 461 462 const GLdouble left_channels[4] = { left_red, left_green, left_blue, left_alpha }; 463 464 const GLdouble right_channels[4] = { right_red, right_green, right_blue, right_alpha }; 465 466 for (GLuint i = 0; i < n_channels; ++i) 467 { 468 const GLdouble left = left_channels[i]; 469 const GLdouble right = right_channels[i]; 470 const GLdouble left_eps = getEpsilon(left_internal_format); 471 const GLdouble right_eps = getEpsilon(right_internal_format); 472 const GLdouble eps = fabs(std::max(left_eps, right_eps)); 473 474 if (eps < fabs(left - right)) 475 { 476 return false; 477 } 478 } 479 480 return true; 481 } 482 483 /** Compare two pixels with memcmp 484 * 485 * @param left_pixel_size Size of left pixel 486 * @param left_pixel_data Data of left pixel 487 * @param right_pixel_size Size of right pixel 488 * @param right_pixel_data Data of right pixel 489 * 490 * @return true if memory match, false otherwise 491 **/ 492 bool Utils::comparePixels(GLuint left_pixel_size, const GLubyte* left_pixel_data, GLuint right_pixel_size, 493 const GLubyte* right_pixel_data) 494 { 495 const GLuint pixel_size = (left_pixel_size >= right_pixel_size) ? left_pixel_size : right_pixel_size; 496 497 return 0 == memcmp(left_pixel_data, right_pixel_data, pixel_size); 498 } 499 500 /** Delete texture or renderbuffer 501 * 502 * @param context Test context 503 * @param target Image target 504 * @param name Name of image 505 **/ 506 void Utils::deleteTexture(deqp::Context& context, GLenum target, GLuint name) 507 { 508 const Functions& gl = context.getRenderContext().getFunctions(); 509 510 if (GL_RENDERBUFFER == target) 511 { 512 gl.deleteRenderbuffers(1, &name); 513 } 514 else 515 { 516 gl.deleteTextures(1, &name); 517 } 518 } 519 520 /** Get epsilon for given internal_format 521 * 522 * @param internal_format Internal format of image 523 * 524 * @return Epsilon value 525 **/ 526 GLdouble Utils::getEpsilon(GLenum internal_format) 527 { 528 GLdouble epsilon; 529 530 switch (internal_format) 531 { 532 case GL_R8: 533 case GL_R8_SNORM: 534 case GL_R16: 535 case GL_R16F: 536 case GL_R16_SNORM: 537 case GL_R32F: 538 case GL_R8I: 539 case GL_R8UI: 540 case GL_R16I: 541 case GL_R16UI: 542 case GL_R32I: 543 case GL_R32UI: 544 case GL_RG8: 545 case GL_RG8_SNORM: 546 case GL_RG16: 547 case GL_RG16F: 548 case GL_RG16_SNORM: 549 case GL_RG32F: 550 case GL_RG8I: 551 case GL_RG8UI: 552 case GL_RG16I: 553 case GL_RG16UI: 554 case GL_RG32I: 555 case GL_RG32UI: 556 case GL_R3_G3_B2: 557 case GL_RGB4: 558 case GL_RGB5: 559 case GL_RGB8: 560 case GL_RGB8_SNORM: 561 case GL_R11F_G11F_B10F: 562 case GL_RGB16: 563 case GL_RGB16F: 564 case GL_RGB16_SNORM: 565 case GL_RGB32F: 566 case GL_RGB8I: 567 case GL_RGB8UI: 568 case GL_RGB10: 569 case GL_RGB16I: 570 case GL_RGB16UI: 571 case GL_RGB32I: 572 case GL_RGB32UI: 573 case GL_RGB9_E5: 574 case GL_RGBA2: 575 case GL_RGBA4: 576 case GL_RGB5_A1: 577 case GL_RGBA8: 578 case GL_RGBA8_SNORM: 579 case GL_RGB10_A2: 580 case GL_RGBA16: 581 case GL_RGBA16F: 582 case GL_RGBA16_SNORM: 583 case GL_RGBA32F: 584 case GL_RGBA8I: 585 case GL_RGBA8UI: 586 case GL_RGB10_A2UI: 587 case GL_RGBA16I: 588 case GL_RGBA16UI: 589 case GL_RGBA32I: 590 case GL_RGBA32UI: 591 epsilon = 0.0; 592 break; 593 case GL_RGB12: 594 case GL_RGBA12: 595 epsilon = 0.00390625; 596 break; 597 default: 598 TCU_FAIL("Invalid enum"); 599 break; 600 } 601 602 return epsilon; 603 } 604 605 /** Get format for given internal format 606 * 607 * @param internal_format Internal format 608 * 609 * @return Format 610 **/ 611 GLenum Utils::getFormat(GLenum internal_format) 612 { 613 GLenum format = 0; 614 615 switch (internal_format) 616 { 617 /* R */ 618 case GL_R8: 619 case GL_R8_SNORM: 620 case GL_R16: 621 case GL_R16F: 622 case GL_R16_SNORM: 623 case GL_R32F: 624 format = GL_RED; 625 break; 626 627 case GL_R8I: 628 case GL_R8UI: 629 case GL_R16I: 630 case GL_R16UI: 631 case GL_R32I: 632 case GL_R32UI: 633 format = GL_RED_INTEGER; 634 break; 635 636 /* RG */ 637 case GL_RG8: 638 case GL_RG8_SNORM: 639 case GL_RG16: 640 case GL_RG16F: 641 case GL_RG16_SNORM: 642 case GL_RG32F: 643 format = GL_RG; 644 break; 645 646 case GL_RG8I: 647 case GL_RG8UI: 648 case GL_RG16I: 649 case GL_RG16UI: 650 case GL_RG32I: 651 case GL_RG32UI: 652 format = GL_RG_INTEGER; 653 break; 654 655 /* RGB */ 656 case GL_R3_G3_B2: 657 case GL_RGB4: 658 case GL_RGB5: 659 case GL_RGB8: 660 case GL_RGB8_SNORM: 661 case GL_R11F_G11F_B10F: 662 case GL_RGB12: 663 case GL_RGB16: 664 case GL_RGB16F: 665 case GL_RGB16_SNORM: 666 case GL_RGB32F: 667 case GL_RGB9_E5: 668 format = GL_RGB; 669 break; 670 671 case GL_RGB8I: 672 case GL_RGB8UI: 673 case GL_RGB16I: 674 case GL_RGB16UI: 675 case GL_RGB32I: 676 case GL_RGB32UI: 677 format = GL_RGB_INTEGER; 678 break; 679 680 /* RGBA */ 681 case GL_RGB10: 682 case GL_RGBA2: 683 case GL_RGBA4: 684 case GL_RGB5_A1: 685 case GL_RGBA8: 686 case GL_RGBA8_SNORM: 687 case GL_RGB10_A2: 688 case GL_RGBA12: 689 case GL_RGBA16: 690 case GL_RGBA16F: 691 case GL_RGBA16_SNORM: 692 case GL_RGBA32F: 693 format = GL_RGBA; 694 break; 695 696 case GL_RGBA8I: 697 case GL_RGBA8UI: 698 case GL_RGB10_A2UI: 699 case GL_RGBA16I: 700 case GL_RGBA16UI: 701 case GL_RGBA32I: 702 case GL_RGBA32UI: 703 format = GL_RGBA_INTEGER; 704 break; 705 706 default: 707 TCU_FAIL("Invalid enum"); 708 break; 709 } 710 711 return format; 712 } 713 714 /** Get number of channels for given internal_format 715 * 716 * @param internal_format Internal format 717 * 718 * @return Number of channels 719 **/ 720 GLuint Utils::getNumberOfChannels(GLenum internal_format) 721 { 722 GLuint result = 0; 723 724 switch (internal_format) 725 { 726 case GL_R8: 727 case GL_R8_SNORM: 728 case GL_R16: 729 case GL_R16F: 730 case GL_R16_SNORM: 731 case GL_R32F: 732 case GL_R8I: 733 case GL_R8UI: 734 case GL_R16I: 735 case GL_R16UI: 736 case GL_R32I: 737 case GL_R32UI: 738 result = 1; 739 break; 740 741 case GL_RG8: 742 case GL_RG8_SNORM: 743 case GL_RG16: 744 case GL_RG16F: 745 case GL_RG16_SNORM: 746 case GL_RG32F: 747 case GL_RG8I: 748 case GL_RG8UI: 749 case GL_RG16I: 750 case GL_RG16UI: 751 case GL_RG32I: 752 case GL_RG32UI: 753 result = 2; 754 break; 755 756 case GL_R3_G3_B2: 757 case GL_RGB4: 758 case GL_RGB5: 759 case GL_RGB8: 760 case GL_RGB8_SNORM: 761 case GL_RGB10: 762 case GL_R11F_G11F_B10F: 763 case GL_RGB12: 764 case GL_RGB16: 765 case GL_RGB16F: 766 case GL_RGB16_SNORM: 767 case GL_RGB32F: 768 case GL_RGB9_E5: 769 case GL_RGB8I: 770 case GL_RGB8UI: 771 case GL_RGB16I: 772 case GL_RGB16UI: 773 case GL_RGB32I: 774 case GL_RGB32UI: 775 result = 3; 776 break; 777 778 case GL_RGBA2: 779 case GL_RGBA4: 780 case GL_RGB5_A1: 781 case GL_RGBA8: 782 case GL_RGBA8_SNORM: 783 case GL_RGB10_A2: 784 case GL_RGBA12: 785 case GL_RGBA16: 786 case GL_RGBA16F: 787 case GL_RGBA16_SNORM: 788 case GL_RGBA32F: 789 case GL_RGBA8I: 790 case GL_RGBA8UI: 791 case GL_RGB10_A2UI: 792 case GL_RGBA16I: 793 case GL_RGBA16UI: 794 case GL_RGBA32I: 795 case GL_RGBA32UI: 796 result = 4; 797 break; 798 799 default: 800 TCU_FAIL("Invalid enum"); 801 break; 802 } 803 804 return result; 805 } 806 807 /** Get type for given internal format 808 * 809 * @param internal_format Internal format 810 * 811 * @return Type 812 **/ 813 GLenum Utils::getType(GLenum internal_format) 814 { 815 GLenum type = 0; 816 817 switch (internal_format) 818 { 819 case GL_R8: 820 case GL_R8UI: 821 case GL_RG8: 822 case GL_RG8UI: 823 case GL_RGB8: 824 case GL_RGB8UI: 825 case GL_RGBA8: 826 case GL_RGBA8UI: 827 type = GL_UNSIGNED_BYTE; 828 break; 829 830 case GL_R8_SNORM: 831 case GL_R8I: 832 case GL_RG8_SNORM: 833 case GL_RG8I: 834 case GL_RGB8_SNORM: 835 case GL_RGB8I: 836 case GL_RGBA8_SNORM: 837 case GL_RGBA8I: 838 type = GL_BYTE; 839 break; 840 841 case GL_R3_G3_B2: 842 type = GL_UNSIGNED_BYTE_3_3_2; 843 break; 844 845 case GL_RGB4: 846 case GL_RGB5: 847 type = GL_UNSIGNED_SHORT_5_6_5; 848 break; 849 850 case GL_RGBA2: 851 case GL_RGBA4: 852 type = GL_UNSIGNED_SHORT_4_4_4_4; 853 break; 854 855 case GL_RGB5_A1: 856 type = GL_UNSIGNED_SHORT_5_5_5_1; 857 break; 858 859 case GL_RGB10: 860 case GL_RGB10_A2: 861 case GL_RGB10_A2UI: 862 type = GL_UNSIGNED_INT_2_10_10_10_REV; 863 break; 864 865 case GL_R16F: 866 case GL_RG16F: 867 case GL_RGB16F: 868 case GL_RGBA16F: 869 type = GL_HALF_FLOAT; 870 break; 871 872 case GL_R16: 873 case GL_R16UI: 874 case GL_RG16: 875 case GL_RG16UI: 876 case GL_RGB12: 877 case GL_RGB16: 878 case GL_RGB16UI: 879 case GL_RGBA12: 880 case GL_RGBA16: 881 case GL_RGBA16UI: 882 type = GL_UNSIGNED_SHORT; 883 break; 884 885 case GL_R16_SNORM: 886 case GL_R16I: 887 case GL_RG16_SNORM: 888 case GL_RG16I: 889 case GL_RGB16_SNORM: 890 case GL_RGB16I: 891 case GL_RGBA16_SNORM: 892 case GL_RGBA16I: 893 type = GL_SHORT; 894 break; 895 896 case GL_R32UI: 897 case GL_RG32UI: 898 case GL_RGB32UI: 899 case GL_RGBA32UI: 900 type = GL_UNSIGNED_INT; 901 break; 902 903 case GL_RGB9_E5: 904 type = GL_UNSIGNED_INT_5_9_9_9_REV; 905 break; 906 907 case GL_R32I: 908 case GL_RG32I: 909 case GL_RGB32I: 910 case GL_RGBA32I: 911 type = GL_INT; 912 break; 913 914 case GL_R32F: 915 case GL_RG32F: 916 case GL_RGB32F: 917 case GL_RGBA32F: 918 type = GL_FLOAT; 919 break; 920 921 case GL_R11F_G11F_B10F: 922 type = GL_UNSIGNED_INT_10F_11F_11F_REV; 923 break; 924 925 default: 926 TCU_FAIL("Invalid enum"); 927 break; 928 } 929 930 return type; 931 } 932 933 /** Returns mask that should be applied to pixel value 934 * 935 * @param internal_format Internal format of texture 936 * @param pixel Pixel data 937 * 938 * @return Mask 939 **/ 940 void Utils::maskPixelForFormat(GLenum internal_format, GLubyte* pixel) 941 { 942 switch (internal_format) 943 { 944 case GL_RGB10: 945 /* UINT_10_10_10_2 - ALPHA will be set to 3*/ 946 pixel[0] |= 0x03; 947 break; 948 949 default: 950 break; 951 } 952 } 953 954 /** Get size of pixel for given internal format 955 * 956 * @param internal_format Internal format 957 * 958 * @return Number of bytes used by given format 959 **/ 960 GLuint Utils::getPixelSizeForFormat(GLenum internal_format) 961 { 962 GLuint size = 0; 963 964 switch (internal_format) 965 { 966 /* 8 */ 967 case GL_R8: 968 case GL_R8I: 969 case GL_R8UI: 970 case GL_R8_SNORM: 971 case GL_R3_G3_B2: 972 size = 1; 973 break; 974 975 /* 8 */ 976 case GL_RGBA2: 977 size = 2; 978 break; 979 980 /* 12 */ 981 case GL_RGB4: 982 size = 2; 983 break; 984 985 /* 15 */ 986 case GL_RGB5: 987 size = 2; 988 break; 989 990 /* 16 */ 991 case GL_RG8: 992 case GL_RG8I: 993 case GL_RG8UI: 994 case GL_RG8_SNORM: 995 case GL_R16: 996 case GL_R16F: 997 case GL_R16I: 998 case GL_R16UI: 999 case GL_R16_SNORM: 1000 case GL_RGBA4: 1001 case GL_RGB5_A1: 1002 size = 2; 1003 break; 1004 1005 /* 24 */ 1006 case GL_RGB8: 1007 case GL_RGB8I: 1008 case GL_RGB8UI: 1009 case GL_RGB8_SNORM: 1010 size = 3; 1011 break; 1012 1013 /* 30 */ 1014 case GL_RGB10: 1015 size = 4; 1016 break; 1017 1018 /* 32 */ 1019 case GL_RGBA8: 1020 case GL_RGBA8I: 1021 case GL_RGBA8UI: 1022 case GL_RGBA8_SNORM: 1023 case GL_RG16: 1024 case GL_RG16F: 1025 case GL_RG16I: 1026 case GL_RG16UI: 1027 case GL_RG16_SNORM: 1028 case GL_R32F: 1029 case GL_R32I: 1030 case GL_R32UI: 1031 case GL_RGB10_A2: 1032 case GL_RGB10_A2UI: 1033 case GL_R11F_G11F_B10F: 1034 case GL_RGB9_E5: 1035 size = 4; 1036 break; 1037 1038 /* 36 */ 1039 case GL_RGB12: 1040 size = 6; 1041 break; 1042 1043 /* 48 */ 1044 case GL_RGB16: 1045 case GL_RGB16F: 1046 case GL_RGB16I: 1047 case GL_RGB16UI: 1048 case GL_RGB16_SNORM: 1049 size = 6; 1050 break; 1051 1052 /* 64 */ 1053 case GL_RGBA12: 1054 case GL_RGBA16: 1055 case GL_RGBA16F: 1056 case GL_RGBA16I: 1057 case GL_RGBA16UI: 1058 case GL_RGBA16_SNORM: 1059 case GL_RG32F: 1060 case GL_RG32I: 1061 case GL_RG32UI: 1062 size = 8; 1063 break; 1064 1065 /* 96 */ 1066 case GL_RGB32F: 1067 case GL_RGB32I: 1068 case GL_RGB32UI: 1069 size = 12; 1070 break; 1071 1072 /* 128 */ 1073 case GL_RGBA32F: 1074 case GL_RGBA32I: 1075 case GL_RGBA32UI: 1076 size = 16; 1077 break; 1078 1079 default: 1080 TCU_FAIL("Invalid enum"); 1081 break; 1082 } 1083 1084 return size; 1085 } 1086 1087 /** Prepare string that represents bytes of pixel 1088 * 1089 * @param internal_format Format 1090 * @param pixel Pixel data 1091 * 1092 * @return String 1093 **/ 1094 std::string Utils::getPixelString(GLenum internal_format, const GLubyte* pixel) 1095 { 1096 const GLuint pixel_size = Utils::getPixelSizeForFormat(internal_format); 1097 std::stringstream stream; 1098 1099 stream << "0x"; 1100 1101 for (GLint i = pixel_size - 1; i >= 0; --i) 1102 { 1103 stream << std::setbase(16) << std::setw(2) << std::setfill('0') << (GLuint)pixel[i]; 1104 } 1105 1106 return stream.str(); 1107 } 1108 1109 /** Check if target supports multiple layers 1110 * 1111 * @param target Texture target 1112 * 1113 * @return true if target is multilayered 1114 **/ 1115 bool Utils::isTargetMultilayer(GLenum target) 1116 { 1117 bool result = false; 1118 1119 switch (target) 1120 { 1121 case GL_TEXTURE_1D_ARRAY: 1122 case GL_TEXTURE_2D_ARRAY: 1123 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1124 case GL_TEXTURE_3D: 1125 case GL_TEXTURE_CUBE_MAP_ARRAY: 1126 result = true; 1127 break; 1128 1129 default: 1130 break; 1131 } 1132 1133 return result; 1134 } 1135 1136 /** Check if target supports multiple level 1137 * 1138 * @param target Texture target 1139 * 1140 * @return true if target supports mipmaps 1141 **/ 1142 bool Utils::isTargetMultilevel(GLenum target) 1143 { 1144 bool result = true; 1145 1146 switch (target) 1147 { 1148 case GL_TEXTURE_2D_MULTISAMPLE: 1149 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1150 case GL_TEXTURE_RECTANGLE: 1151 case GL_RENDERBUFFER: 1152 result = false; 1153 break; 1154 default: 1155 break; 1156 } 1157 1158 return result; 1159 } 1160 1161 /** Check if target is multisampled 1162 * 1163 * @param target Texture target 1164 * 1165 * @return true when for multisampled formats, false otherwise 1166 **/ 1167 bool Utils::isTargetMultisampled(GLenum target) 1168 { 1169 bool result = false; 1170 1171 switch (target) 1172 { 1173 case GL_TEXTURE_2D_MULTISAMPLE: 1174 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1175 result = true; 1176 break; 1177 default: 1178 break; 1179 } 1180 1181 return result; 1182 } 1183 1184 /** Generate texture object 1185 * 1186 * @param context Test context 1187 * @param target Target of texture 1188 * 1189 * @return Generated name 1190 **/ 1191 glw::GLuint Utils::generateTexture(deqp::Context& context, GLenum target) 1192 { 1193 const Functions& gl = context.getRenderContext().getFunctions(); 1194 GLuint name = 0; 1195 1196 switch (target) 1197 { 1198 case GL_RENDERBUFFER: 1199 gl.genRenderbuffers(1, &name); 1200 GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderbuffers"); 1201 break; 1202 1203 default: 1204 gl.genTextures(1, &name); 1205 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 1206 break; 1207 } 1208 1209 return name; 1210 } 1211 1212 /** Sets base and max level parameters of texture to make it complete 1213 * 1214 * @param context Test context 1215 * @param target GLenum representing target of texture that should be created 1216 * @param id Id of texture 1217 * @param base_level Base level value, eg 0 1218 * @param max_level Max level value, eg 0 1219 **/ 1220 void Utils::makeTextureComplete(deqp::Context& context, GLenum target, GLuint id, GLint base_level, GLint max_level) 1221 { 1222 const Functions& gl = context.getRenderContext().getFunctions(); 1223 1224 if (GL_RENDERBUFFER == target) 1225 { 1226 return; 1227 } 1228 1229 /* Translate proxies into real targets */ 1230 target = transRealToBindTarget(transProxyToRealTarget(target)); 1231 1232 gl.bindTexture(target, id); 1233 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1234 1235 /* Set levels */ 1236 if (GL_TEXTURE_BUFFER != target) 1237 { 1238 gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, base_level); 1239 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 1240 1241 gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, max_level); 1242 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 1243 1244 /* Integer textures won't be complete with the default min filter 1245 * of GL_NEAREST_MIPMAP_LINEAR (or GL_LINEAR for rectangle textures) 1246 * and default mag filter of GL_LINEAR, so switch to nearest. 1247 */ 1248 if (GL_TEXTURE_2D_MULTISAMPLE != target && GL_TEXTURE_2D_MULTISAMPLE_ARRAY != target) 1249 { 1250 gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1251 if (GL_TEXTURE_RECTANGLE != target) 1252 { 1253 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 1254 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 1255 } 1256 else 1257 { 1258 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1259 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 1260 } 1261 } 1262 } 1263 1264 /* Clean binding point */ 1265 gl.bindTexture(target, 0); 1266 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1267 } 1268 1269 /** Generate and initialize texture for given target 1270 * 1271 * @param context Test context 1272 * @param target GLenum representing target of texture that should be created 1273 * @param n_samples Number of samples 1274 * 1275 * @return "name" of texture 1276 **/ 1277 GLuint Utils::prepareMultisampleTex(deqp::Context& context, GLenum target, GLsizei n_samples) 1278 { 1279 static const GLuint depth = 6; 1280 const Functions& gl = context.getRenderContext().getFunctions(); 1281 static const GLuint height = 16; 1282 static const GLenum internal_format = GL_RGBA8; 1283 GLuint name = 0; 1284 static const GLuint width = 16; 1285 1286 gl.genTextures(1, &name); 1287 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 1288 1289 /* Initialize */ 1290 switch (target) 1291 { 1292 case GL_TEXTURE_2D_MULTISAMPLE: 1293 gl.bindTexture(target, name); 1294 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1295 1296 gl.texImage2DMultisample(target, n_samples, internal_format, width, height, GL_FALSE /* fixedsamplelocation */); 1297 GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2DMultisample"); 1298 1299 break; 1300 1301 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1302 gl.bindTexture(target, name); 1303 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1304 1305 gl.texImage3DMultisample(target, n_samples, internal_format, width, height, depth, 1306 GL_FALSE /* fixedsamplelocation */); 1307 GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage3DMultisample"); 1308 1309 break; 1310 1311 default: 1312 TCU_FAIL("Invalid enum"); 1313 break; 1314 } 1315 1316 /* Clean binding point */ 1317 gl.bindTexture(target, 0); 1318 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1319 1320 return name; 1321 } 1322 1323 /** Generate and initialize texture for given target 1324 * 1325 * @param context Test context 1326 * @param internal_format Internal format of render buffer 1327 * 1328 * @return "name" of texture 1329 **/ 1330 GLuint Utils::prepareRenderBuffer(deqp::Context& context, GLenum internal_format) 1331 { 1332 const Functions& gl = context.getRenderContext().getFunctions(); 1333 static const GLuint height = 16; 1334 GLuint name = 0; 1335 static const GLuint width = 16; 1336 1337 gl.genRenderbuffers(1, &name); 1338 GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderbuffers"); 1339 1340 /* Initialize */ 1341 gl.bindRenderbuffer(GL_RENDERBUFFER, name); 1342 GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderbuffer"); 1343 1344 gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, width, height); 1345 GLU_EXPECT_NO_ERROR(gl.getError(), "RenderbufferStorage"); 1346 1347 /* Clean binding point */ 1348 gl.bindRenderbuffer(GL_RENDERBUFFER, 0); 1349 GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderbuffer"); 1350 1351 return name; 1352 } 1353 1354 /** Generate and initialize texture for given target 1355 * 1356 * @param context Test context 1357 * @param target GLenum representing target of texture that should be created 1358 * @param internal_format <internalformat> 1359 * @param format <format> 1360 * @param type <type> 1361 * @param out_buf_id ID of buffer that will be used for TEXTURE_BUFFER 1362 * 1363 * @return "name" of texture 1364 **/ 1365 GLuint Utils::prepareTex16x16x6(deqp::Context& context, GLenum target, GLenum internal_format, GLenum format, 1366 GLenum type, GLuint& out_buf_id) 1367 { 1368 static const GLuint depth = 6; 1369 static const GLuint height = 16; 1370 static const GLuint level = 0; 1371 GLuint name = 0; 1372 static const GLchar* pixels = 0; 1373 static const GLuint width = 16; 1374 1375 name = generateTexture(context, target); 1376 1377 prepareTexture(context, name, target, internal_format, format, type, level, width, height, depth, pixels, 1378 out_buf_id); 1379 1380 return name; 1381 } 1382 1383 /** Initialize texture 1384 * 1385 * @param context Test context 1386 * @param name Name of texture object 1387 * @param target GLenum representing target of texture that should be created 1388 * @param internal_format <internalformat> 1389 * @param format <format> 1390 * @param type <type> 1391 * @param level <level> 1392 * @param width <width> 1393 * @param height <height> 1394 * @param depth <depth> 1395 * @param pixels <pixels> 1396 * @param out_buf_id ID of buffer that will be used for TEXTURE_BUFFER 1397 * 1398 * @return "name" of texture 1399 **/ 1400 void Utils::prepareTexture(deqp::Context& context, GLuint name, GLenum target, GLenum internal_format, GLenum format, 1401 GLenum type, GLuint level, GLuint width, GLuint height, GLuint depth, const GLvoid* pixels, 1402 GLuint& out_buf_id) 1403 { 1404 static const GLint border = 0; 1405 GLenum error = 0; 1406 const GLchar* function_name = "unknown"; 1407 const Functions& gl = context.getRenderContext().getFunctions(); 1408 static const GLsizei samples = 1; 1409 1410 /* Translate proxies into real targets */ 1411 target = transProxyToRealTarget(target); 1412 1413 /* Initialize */ 1414 switch (target) 1415 { 1416 case GL_RENDERBUFFER: 1417 gl.bindRenderbuffer(target, name); 1418 GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderbuffer"); 1419 1420 gl.renderbufferStorage(target, internal_format, width, height); 1421 GLU_EXPECT_NO_ERROR(gl.getError(), "RenderbufferStorage"); 1422 1423 gl.bindRenderbuffer(target, 0); 1424 GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderbuffer"); 1425 1426 break; 1427 1428 case GL_TEXTURE_1D: 1429 gl.bindTexture(target, name); 1430 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1431 1432 gl.texImage1D(target, level, internal_format, width, border, format, type, pixels); 1433 error = gl.getError(); 1434 function_name = "TexImage1D"; 1435 1436 break; 1437 1438 case GL_TEXTURE_1D_ARRAY: 1439 case GL_TEXTURE_2D: 1440 case GL_TEXTURE_RECTANGLE: 1441 gl.bindTexture(target, name); 1442 1443 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1444 1445 gl.texImage2D(target, level, internal_format, width, height, border, format, type, pixels); 1446 error = gl.getError(); 1447 function_name = "TexImage2D"; 1448 1449 break; 1450 1451 case GL_TEXTURE_2D_MULTISAMPLE: 1452 gl.bindTexture(target, name); 1453 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1454 1455 gl.texImage2DMultisample(target, samples, internal_format, width, height, GL_FALSE /* fixedsamplelocation */); 1456 error = gl.getError(); 1457 function_name = "TexImage2DMultisample"; 1458 1459 break; 1460 1461 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1462 gl.bindTexture(target, name); 1463 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1464 1465 gl.texImage3DMultisample(target, samples, internal_format, width, height, depth, 1466 GL_FALSE /* fixedsamplelocation */); 1467 error = gl.getError(); 1468 function_name = "TexImage3DMultisample"; 1469 1470 break; 1471 1472 case GL_TEXTURE_2D_ARRAY: 1473 case GL_TEXTURE_3D: 1474 case GL_TEXTURE_CUBE_MAP_ARRAY: 1475 gl.bindTexture(target, name); 1476 1477 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1478 1479 gl.texImage3D(target, level, internal_format, width, height, depth, border, format, type, pixels); 1480 error = gl.getError(); 1481 function_name = "TexImage3D"; 1482 1483 break; 1484 1485 case GL_TEXTURE_BUFFER: 1486 gl.genBuffers(1, &out_buf_id); 1487 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 1488 1489 gl.bindBuffer(GL_TEXTURE_BUFFER, out_buf_id); 1490 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 1491 1492 { 1493 GLsizei size = 16; 1494 const GLvoid* data = 0; 1495 1496 if (0 != pixels) 1497 { 1498 size = width; 1499 data = pixels; 1500 } 1501 1502 gl.bufferData(GL_TEXTURE_BUFFER, size, data, GL_DYNAMIC_COPY); 1503 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 1504 } 1505 1506 gl.bindTexture(GL_TEXTURE_BUFFER, name); 1507 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1508 1509 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, out_buf_id); 1510 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer"); 1511 1512 break; 1513 1514 case GL_TEXTURE_CUBE_MAP: 1515 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1516 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1517 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1518 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1519 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1520 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1521 /* Change target to CUBE_MAP, it will be used later to change base and max level */ 1522 target = GL_TEXTURE_CUBE_MAP; 1523 gl.bindTexture(target, name); 1524 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1525 1526 gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internal_format, width, height, border, format, type, 1527 pixels); 1528 gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internal_format, width, height, border, format, type, 1529 pixels); 1530 gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internal_format, width, height, border, format, type, 1531 pixels); 1532 gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internal_format, width, height, border, format, type, 1533 pixels); 1534 gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internal_format, width, height, border, format, type, 1535 pixels); 1536 gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internal_format, width, height, border, format, type, 1537 pixels); 1538 error = gl.getError(); 1539 function_name = "TexImage2D"; 1540 1541 break; 1542 1543 default: 1544 TCU_FAIL("Invalid enum"); 1545 break; 1546 } 1547 1548 if (GL_NO_ERROR != error) 1549 { 1550 context.getTestContext().getLog() 1551 << tcu::TestLog::Message << "Error: " << glu::getErrorStr(error) << ". Function: " << function_name 1552 << ". Target: " << glu::getTextureTargetStr(target) 1553 << ". Format: " << glu::getInternalFormatParameterStr(internal_format) << ", " 1554 << glu::getTextureFormatName(format) << ", " << glu::getTypeStr(type) << tcu::TestLog::EndMessage; 1555 TCU_FAIL("Failed to create texture"); 1556 } 1557 1558 if (GL_RENDERBUFFER != target) 1559 { 1560 /* Clean binding point */ 1561 gl.bindTexture(target, 0); 1562 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1563 } 1564 } 1565 1566 /** Translate proxies into real targets 1567 * 1568 * @param target Target to be converted 1569 * 1570 * @return Converted target for proxies, <target> otherwise 1571 **/ 1572 GLenum Utils::transProxyToRealTarget(GLenum target) 1573 { 1574 switch (target) 1575 { 1576 case GL_PROXY_TEXTURE_1D: 1577 target = GL_TEXTURE_1D; 1578 break; 1579 case GL_PROXY_TEXTURE_1D_ARRAY: 1580 target = GL_TEXTURE_1D_ARRAY; 1581 break; 1582 case GL_PROXY_TEXTURE_2D: 1583 target = GL_TEXTURE_2D; 1584 break; 1585 case GL_PROXY_TEXTURE_2D_ARRAY: 1586 target = GL_TEXTURE_2D_ARRAY; 1587 break; 1588 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 1589 target = GL_TEXTURE_2D_MULTISAMPLE; 1590 break; 1591 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 1592 target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; 1593 break; 1594 case GL_PROXY_TEXTURE_3D: 1595 target = GL_TEXTURE_3D; 1596 break; 1597 case GL_PROXY_TEXTURE_CUBE_MAP: 1598 target = GL_TEXTURE_CUBE_MAP; 1599 break; 1600 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1601 target = GL_TEXTURE_CUBE_MAP_ARRAY; 1602 break; 1603 case GL_PROXY_TEXTURE_RECTANGLE: 1604 target = GL_TEXTURE_RECTANGLE; 1605 break; 1606 default: 1607 break; 1608 } 1609 1610 return target; 1611 } 1612 1613 /** Translate real targets into binding targets 1614 * 1615 * @param target Target to be converted 1616 * 1617 * @return Converted target for cube map faces, <target> otherwise 1618 **/ 1619 GLenum Utils::transRealToBindTarget(GLenum target) 1620 { 1621 switch (target) 1622 { 1623 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1624 target = GL_TEXTURE_CUBE_MAP; 1625 break; 1626 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1627 target = GL_TEXTURE_CUBE_MAP; 1628 break; 1629 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1630 target = GL_TEXTURE_CUBE_MAP; 1631 break; 1632 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1633 target = GL_TEXTURE_CUBE_MAP; 1634 break; 1635 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1636 target = GL_TEXTURE_CUBE_MAP; 1637 break; 1638 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1639 target = GL_TEXTURE_CUBE_MAP; 1640 break; 1641 default: 1642 break; 1643 } 1644 1645 return target; 1646 } 1647 1648 /** Read value of channel 1649 * 1650 * @tparam T Type used to store channel value 1651 * 1652 * @param channel Channel index 1653 * @param pixel Pixel data 1654 * @param out_value Read value 1655 **/ 1656 template <typename T> 1657 void readBaseTypeFromUnsignedChannel(GLuint channel, const GLubyte* pixel, GLdouble& out_value) 1658 { 1659 static const T max = -1; 1660 1661 const GLdouble d_max = (GLdouble)max; 1662 const T* ptr = (T*)pixel; 1663 const T t_value = ptr[channel]; 1664 const GLdouble d_value = (GLdouble)t_value; 1665 1666 out_value = d_value / d_max; 1667 } 1668 1669 /** Read value of channel 1670 * 1671 * @tparam T Type used to store channel value 1672 * 1673 * @param channel Channel index 1674 * @param pixel Pixel data 1675 * @param out_value Read value 1676 **/ 1677 template <typename T> 1678 void readBaseTypeFromSignedChannel(GLuint channel, const GLubyte* pixel, GLdouble& out_value) 1679 { 1680 static const GLuint n_bytes = sizeof(T); 1681 static const GLuint n_bits = 8u * n_bytes; 1682 static const T max = (T)((1u << (n_bits - 1u)) - 1u); 1683 1684 const GLdouble d_max = (GLdouble)max; 1685 const T* ptr = (T*)pixel; 1686 const T t_value = ptr[channel]; 1687 const GLdouble d_value = (GLdouble)t_value; 1688 1689 out_value = d_value / d_max; 1690 } 1691 1692 /** Read value of channel 1693 * 1694 * @tparam T Type used to store channel value 1695 * 1696 * @param channel Channel index 1697 * @param pixel Pixel data 1698 * @param out_value Read value 1699 **/ 1700 void readBaseTypeFromFloatChannel(GLuint channel, const GLubyte* pixel, GLdouble& out_value) 1701 { 1702 const GLfloat* ptr = (const GLfloat*)pixel; 1703 const GLfloat t_value = ptr[channel]; 1704 const GLdouble d_value = (GLdouble)t_value; 1705 1706 out_value = d_value; 1707 } 1708 1709 /** Read value of channel 1710 * 1711 * @tparam T Type used to store channel value 1712 * 1713 * @param channel Channel index 1714 * @param pixel Pixel data 1715 * @param out_value Read value 1716 **/ 1717 void readBaseTypeFromHalfFloatChannel(GLuint channel, const GLubyte* pixel, GLdouble& out_value) 1718 { 1719 const deUint16* ptr = (const deUint16*)pixel; 1720 const deUint16 bits = ptr[channel]; 1721 tcu::Float16 val(bits); 1722 const GLdouble d_value = val.asDouble(); 1723 1724 out_value = d_value; 1725 } 1726 1727 /** Read value of channel 1728 * 1729 * @tparam T Type used to store pixel 1730 * @tparam size_1 Size of channel in bits 1731 * @tparam size_2 Size of channel in bits 1732 * @tparam size_3 Size of channel in bits 1733 * @tparam off_1 Offset of channel in bits 1734 * @tparam off_2 Offset of channel in bits 1735 * @tparam off_3 Offset of channel in bits 1736 * 1737 * @param channel Channel index 1738 * @param pixel Pixel data 1739 * @param out_value Read value 1740 **/ 1741 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int off_1, 1742 unsigned int off_2, unsigned int off_3> 1743 void read3Channel(GLuint channel, const GLubyte* pixel, GLdouble& out_value) 1744 { 1745 T mask = 0; 1746 T max = 0; 1747 T off = 0; 1748 const T* ptr = (T*)pixel; 1749 T result = 0; 1750 const T t_value = ptr[0]; 1751 1752 static const T max_1 = (1 << size_1) - 1; 1753 static const T max_2 = (1 << size_2) - 1; 1754 static const T max_3 = (1 << size_3) - 1; 1755 1756 switch (channel) 1757 { 1758 case 0: 1759 mask = max_1; 1760 max = max_1; 1761 off = off_1; 1762 break; 1763 case 1: 1764 mask = max_2; 1765 max = max_2; 1766 off = off_2; 1767 break; 1768 case 2: 1769 mask = max_3; 1770 max = max_3; 1771 off = off_3; 1772 break; 1773 default: 1774 TCU_FAIL("Invalid channel"); 1775 break; 1776 } 1777 1778 result = (T)((t_value >> off) & mask); 1779 1780 const GLdouble d_max = (GLdouble)max; 1781 const GLdouble d_value = (GLdouble)result; 1782 1783 out_value = d_value / d_max; 1784 } 1785 1786 /** Read value of channel 1787 * 1788 * @tparam T Type used to store pixel 1789 * @tparam size_1 Size of channel in bits 1790 * @tparam size_2 Size of channel in bits 1791 * @tparam size_3 Size of channel in bits 1792 * @tparam size_4 Size of channel in bits 1793 * @tparam off_1 Offset of channel in bits 1794 * @tparam off_2 Offset of channel in bits 1795 * @tparam off_3 Offset of channel in bits 1796 * @tparam off_4 Offset of channel in bits 1797 * 1798 * @param channel Channel index 1799 * @param pixel Pixel data 1800 * @param out_value Read value 1801 **/ 1802 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int size_4, 1803 unsigned int off_1, unsigned int off_2, unsigned int off_3, unsigned int off_4> 1804 void read4Channel(GLuint channel, const GLubyte* pixel, GLdouble& out_value) 1805 { 1806 T mask = 0; 1807 T max = 0; 1808 T off = 0; 1809 const T* ptr = (T*)pixel; 1810 T result = 0; 1811 const T t_value = ptr[0]; 1812 1813 static const T max_1 = (1 << size_1) - 1; 1814 static const T max_2 = (1 << size_2) - 1; 1815 static const T max_3 = (1 << size_3) - 1; 1816 static const T max_4 = (1 << size_4) - 1; 1817 1818 switch (channel) 1819 { 1820 case 0: 1821 mask = max_1; 1822 max = max_1; 1823 off = off_1; 1824 break; 1825 case 1: 1826 mask = max_2; 1827 max = max_2; 1828 off = off_2; 1829 break; 1830 case 2: 1831 mask = max_3; 1832 max = max_3; 1833 off = off_3; 1834 break; 1835 case 3: 1836 mask = max_4; 1837 max = max_4; 1838 off = off_4; 1839 break; 1840 default: 1841 TCU_FAIL("Invalid channel"); 1842 break; 1843 } 1844 1845 result = (T)((t_value >> off) & mask); 1846 1847 const GLdouble d_max = (GLdouble)max; 1848 const GLdouble d_value = (GLdouble)result; 1849 1850 out_value = d_value / d_max; 1851 } 1852 1853 /** Read value of channel 1854 * 1855 * @param channel Channel index 1856 * @param pixel Pixel data 1857 * @param out_value Read value 1858 **/ 1859 void read11F_11F_10F_Channel(GLuint channel, const GLubyte* pixel, GLdouble& out_value) 1860 { 1861 const deUint32* ptr = (deUint32*)pixel; 1862 deUint32 val = *ptr; 1863 1864 switch (channel) 1865 { 1866 case 0: 1867 { 1868 deUint32 bits = (val & 0x000007ff); 1869 tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> temp_val(bits); 1870 1871 out_value = temp_val.asDouble(); 1872 } 1873 break; 1874 case 1: 1875 { 1876 deUint32 bits = ((val >> 11) & 0x000007ff); 1877 tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> temp_val(bits); 1878 1879 out_value = temp_val.asDouble(); 1880 } 1881 break; 1882 case 2: 1883 { 1884 deUint32 bits = ((val >> 22) & 0x000003ff); 1885 tcu::Float<deUint32, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> temp_val(bits); 1886 1887 out_value = temp_val.asDouble(); 1888 } 1889 break; 1890 default: 1891 TCU_FAIL("Invalid channel"); 1892 break; 1893 } 1894 } 1895 1896 /** Write value of channel 1897 * 1898 * @tparam T Type used to store pixel 1899 * 1900 * @param channel Channel index 1901 * @param value Value to write 1902 * @param pixel Pixel data 1903 **/ 1904 template <typename T> 1905 void writeBaseTypeToUnsignedChannel(GLuint channel, GLdouble value, GLubyte* pixel) 1906 { 1907 static const T max = -1; 1908 1909 const GLdouble d_max = (GLdouble)max; 1910 const GLdouble d_value = value * d_max; 1911 const T t_value = (T)d_value; 1912 1913 T* ptr = (T*)pixel; 1914 1915 ptr[channel] = t_value; 1916 } 1917 1918 /** Write value of channel 1919 * 1920 * @tparam T Type used to store pixel 1921 * 1922 * @param channel Channel index 1923 * @param value Value to write 1924 * @param pixel Pixel data 1925 **/ 1926 template <typename T> 1927 void writeBaseTypeToSignedChannel(GLuint channel, GLdouble value, GLubyte* pixel) 1928 { 1929 static const GLuint n_bytes = sizeof(T); 1930 static const GLuint n_bits = 8u * n_bytes; 1931 static const T max = (T)((1u << (n_bits - 1u)) - 1u); 1932 1933 const GLdouble d_max = (GLdouble)max; 1934 const GLdouble d_value = value * d_max; 1935 const T t_value = (T)d_value; 1936 1937 T* ptr = (T*)pixel; 1938 1939 ptr[channel] = t_value; 1940 } 1941 1942 /** Write value of channel 1943 * 1944 * @param channel Channel index 1945 * @param value Value to write 1946 * @param pixel Pixel data 1947 **/ 1948 void writeBaseTypeToFloatChannel(GLuint channel, GLdouble value, GLubyte* pixel) 1949 { 1950 const GLfloat t_value = (GLfloat)value; 1951 1952 GLfloat* ptr = (GLfloat*)pixel; 1953 1954 ptr[channel] = t_value; 1955 } 1956 1957 /** Write value of channel 1958 * 1959 * @param channel Channel index 1960 * @param value Value to write 1961 * @param pixel Pixel data 1962 **/ 1963 void writeBaseTypeToHalfFloatChannel(GLuint channel, GLdouble value, GLubyte* pixel) 1964 { 1965 deUint16* ptr = (deUint16*)pixel; 1966 1967 tcu::Float16 val(value); 1968 1969 ptr[channel] = val.bits(); 1970 } 1971 1972 /** Write value of channel 1973 * 1974 * @tparam T Type used to store pixel 1975 * @tparam size_1 Size of channel in bits 1976 * @tparam size_2 Size of channel in bits 1977 * @tparam size_3 Size of channel in bits 1978 * @tparam off_1 Offset of channel in bits 1979 * @tparam off_2 Offset of channel in bits 1980 * @tparam off_3 Offset of channel in bits 1981 * 1982 * @param channel Channel index 1983 * @param value Value to write 1984 * @param pixel Pixel data 1985 **/ 1986 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int off_1, 1987 unsigned int off_2, unsigned int off_3> 1988 void write3Channel(GLuint channel, GLdouble value, GLubyte* pixel) 1989 { 1990 T mask = 0; 1991 T max = 0; 1992 T off = 0; 1993 T* ptr = (T*)pixel; 1994 T result = 0; 1995 1996 static const T max_1 = (1 << size_1) - 1; 1997 static const T max_2 = (1 << size_2) - 1; 1998 static const T max_3 = (1 << size_3) - 1; 1999 2000 switch (channel) 2001 { 2002 case 0: 2003 mask = max_1; 2004 max = max_1; 2005 off = off_1; 2006 break; 2007 case 1: 2008 mask = max_2; 2009 max = max_2; 2010 off = off_2; 2011 break; 2012 case 2: 2013 mask = max_3; 2014 max = max_3; 2015 off = off_3; 2016 break; 2017 default: 2018 TCU_FAIL("Invalid channel"); 2019 break; 2020 } 2021 2022 const GLdouble d_max = (GLdouble)max; 2023 const GLdouble d_value = value * d_max; 2024 const T t_value = (T)d_value; 2025 2026 result = (T)((t_value & mask) << off); 2027 2028 *ptr |= result; 2029 } 2030 2031 /** Write value of channel 2032 * 2033 * @tparam T Type used to store pixel 2034 * @tparam size_1 Size of channel in bits 2035 * @tparam size_2 Size of channel in bits 2036 * @tparam size_3 Size of channel in bits 2037 * @tparam size_4 Size of channel in bits 2038 * @tparam off_1 Offset of channel in bits 2039 * @tparam off_2 Offset of channel in bits 2040 * @tparam off_3 Offset of channel in bits 2041 * @tparam off_4 Offset of channel in bits 2042 * 2043 * @param channel Channel index 2044 * @param value Value to write 2045 * @param pixel Pixel data 2046 **/ 2047 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int size_4, 2048 unsigned int off_1, unsigned int off_2, unsigned int off_3, unsigned int off_4> 2049 void write4Channel(GLuint channel, GLdouble value, GLubyte* pixel) 2050 { 2051 T mask = 0; 2052 T max = 0; 2053 T off = 0; 2054 T* ptr = (T*)pixel; 2055 T result = 0; 2056 2057 static const T max_1 = (1 << size_1) - 1; 2058 static const T max_2 = (1 << size_2) - 1; 2059 static const T max_3 = (1 << size_3) - 1; 2060 static const T max_4 = (1 << size_4) - 1; 2061 2062 switch (channel) 2063 { 2064 case 0: 2065 mask = max_1; 2066 max = max_1; 2067 off = off_1; 2068 break; 2069 case 1: 2070 mask = max_2; 2071 max = max_2; 2072 off = off_2; 2073 break; 2074 case 2: 2075 mask = max_3; 2076 max = max_3; 2077 off = off_3; 2078 break; 2079 case 3: 2080 mask = max_4; 2081 max = max_4; 2082 off = off_4; 2083 break; 2084 default: 2085 TCU_FAIL("Invalid channel"); 2086 break; 2087 } 2088 2089 const GLdouble d_max = (GLdouble)max; 2090 const GLdouble d_value = value * d_max; 2091 const T t_value = (T)d_value; 2092 2093 result = (T)((t_value & mask) << off); 2094 2095 *ptr |= result; 2096 } 2097 2098 /** Write value of channel 2099 * 2100 * @param channel Channel index 2101 * @param value Value to write 2102 * @param pixel Pixel data 2103 **/ 2104 void write11F_11F_10F_Channel(GLuint channel, GLdouble value, GLubyte* pixel) 2105 { 2106 deUint32* ptr = (deUint32*)pixel; 2107 2108 switch (channel) 2109 { 2110 case 0: 2111 { 2112 tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> val(value); 2113 deUint32 bits = val.bits(); 2114 2115 *ptr |= bits; 2116 } 2117 break; 2118 case 1: 2119 { 2120 tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> val(value); 2121 deUint32 bits = val.bits(); 2122 2123 *ptr |= (bits << 11); 2124 } 2125 break; 2126 case 2: 2127 { 2128 tcu::Float<deUint32, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> val(value); 2129 deUint32 bits = val.bits(); 2130 2131 *ptr |= (bits << 22); 2132 } 2133 break; 2134 default: 2135 TCU_FAIL("Invalid channel"); 2136 break; 2137 } 2138 } 2139 2140 /** Read value of channel 2141 * 2142 * @param type Type used by pixel 2143 * @param channel Channel index 2144 * @param pixel Pixel data 2145 * @param value Read value 2146 **/ 2147 void Utils::readChannel(GLenum type, GLuint channel, const GLubyte* pixel, GLdouble& value) 2148 { 2149 switch (type) 2150 { 2151 /* Base types */ 2152 case GL_UNSIGNED_BYTE: 2153 readBaseTypeFromUnsignedChannel<GLubyte>(channel, pixel, value); 2154 break; 2155 case GL_UNSIGNED_SHORT: 2156 readBaseTypeFromUnsignedChannel<GLushort>(channel, pixel, value); 2157 break; 2158 case GL_UNSIGNED_INT: 2159 readBaseTypeFromUnsignedChannel<GLuint>(channel, pixel, value); 2160 break; 2161 case GL_BYTE: 2162 readBaseTypeFromSignedChannel<GLbyte>(channel, pixel, value); 2163 break; 2164 case GL_SHORT: 2165 readBaseTypeFromSignedChannel<GLshort>(channel, pixel, value); 2166 break; 2167 case GL_INT: 2168 readBaseTypeFromSignedChannel<GLint>(channel, pixel, value); 2169 break; 2170 case GL_HALF_FLOAT: 2171 readBaseTypeFromHalfFloatChannel(channel, pixel, value); 2172 break; 2173 case GL_FLOAT: 2174 readBaseTypeFromFloatChannel(channel, pixel, value); 2175 break; 2176 2177 /* Complicated */ 2178 /* 3 channles */ 2179 case GL_UNSIGNED_BYTE_3_3_2: 2180 read3Channel<GLubyte, 3, 3, 2, 5, 2, 0>(channel, pixel, value); 2181 break; 2182 case GL_UNSIGNED_SHORT_5_6_5: 2183 read3Channel<GLushort, 5, 6, 5, 11, 5, 0>(channel, pixel, value); 2184 break; 2185 2186 /* 4 channels */ 2187 case GL_UNSIGNED_SHORT_4_4_4_4: 2188 read4Channel<GLushort, 4, 4, 4, 4, 12, 8, 4, 0>(channel, pixel, value); 2189 break; 2190 case GL_UNSIGNED_SHORT_5_5_5_1: 2191 read4Channel<GLushort, 5, 5, 5, 1, 11, 6, 1, 0>(channel, pixel, value); 2192 break; 2193 case GL_UNSIGNED_INT_2_10_10_10_REV: 2194 read4Channel<GLuint, 2, 10, 10, 10, 30, 20, 10, 0>(3 - channel, pixel, value); 2195 break; 2196 case GL_UNSIGNED_INT_5_9_9_9_REV: 2197 read4Channel<GLuint, 5, 9, 9, 9, 27, 18, 9, 0>(3 - channel, pixel, value); 2198 break; 2199 2200 /* R11F_G11F_B10F - uber complicated */ 2201 case GL_UNSIGNED_INT_10F_11F_11F_REV: 2202 read11F_11F_10F_Channel(channel, pixel, value); 2203 break; 2204 2205 default: 2206 TCU_FAIL("Invalid enum"); 2207 break; 2208 } 2209 } 2210 2211 /** Write value of channel 2212 * 2213 * @param type Type used by pixel 2214 * @param channel Channel index 2215 * @param value Value to write 2216 * @param pixel Pixel data 2217 **/ 2218 void Utils::writeChannel(GLenum type, GLuint channel, GLdouble value, GLubyte* pixel) 2219 { 2220 switch (type) 2221 { 2222 /* Base types */ 2223 case GL_UNSIGNED_BYTE: 2224 writeBaseTypeToUnsignedChannel<GLubyte>(channel, value, pixel); 2225 break; 2226 case GL_UNSIGNED_SHORT: 2227 writeBaseTypeToUnsignedChannel<GLushort>(channel, value, pixel); 2228 break; 2229 case GL_UNSIGNED_INT: 2230 writeBaseTypeToUnsignedChannel<GLuint>(channel, value, pixel); 2231 break; 2232 case GL_BYTE: 2233 writeBaseTypeToSignedChannel<GLbyte>(channel, value, pixel); 2234 break; 2235 case GL_SHORT: 2236 writeBaseTypeToSignedChannel<GLshort>(channel, value, pixel); 2237 break; 2238 case GL_INT: 2239 writeBaseTypeToSignedChannel<GLint>(channel, value, pixel); 2240 break; 2241 case GL_HALF_FLOAT: 2242 writeBaseTypeToHalfFloatChannel(channel, value, pixel); 2243 break; 2244 case GL_FLOAT: 2245 writeBaseTypeToFloatChannel(channel, value, pixel); 2246 break; 2247 2248 /* Complicated */ 2249 2250 /* 3 channles */ 2251 case GL_UNSIGNED_BYTE_3_3_2: 2252 write3Channel<GLubyte, 3, 3, 2, 5, 2, 0>(channel, value, pixel); 2253 break; 2254 case GL_UNSIGNED_SHORT_5_6_5: 2255 write3Channel<GLushort, 5, 6, 5, 11, 5, 0>(channel, value, pixel); 2256 break; 2257 2258 /* 4 channels */ 2259 case GL_UNSIGNED_SHORT_4_4_4_4: 2260 write4Channel<GLushort, 4, 4, 4, 4, 12, 8, 4, 0>(channel, value, pixel); 2261 break; 2262 case GL_UNSIGNED_SHORT_5_5_5_1: 2263 write4Channel<GLushort, 5, 5, 5, 1, 11, 6, 1, 0>(channel, value, pixel); 2264 break; 2265 case GL_UNSIGNED_INT_2_10_10_10_REV: 2266 write4Channel<GLuint, 2, 10, 10, 10, 30, 20, 10, 0>(3 - channel, value, pixel); 2267 break; 2268 case GL_UNSIGNED_INT_5_9_9_9_REV: 2269 write4Channel<GLuint, 5, 9, 9, 9, 27, 18, 9, 0>(3 - channel, value, pixel); 2270 break; 2271 2272 /* R11F_G11F_B10F - uber complicated */ 2273 case GL_UNSIGNED_INT_10F_11F_11F_REV: 2274 write11F_11F_10F_Channel(channel, value, pixel); 2275 break; 2276 2277 default: 2278 TCU_FAIL("Invalid enum"); 2279 break; 2280 } 2281 } 2282 2283 /** Packs given channels to pixel 2284 * 2285 * @param internal_format Internal format of image 2286 * @param type Type used by image 2287 * @param red Red channel 2288 * @param green Green channel 2289 * @param blue Blue channel 2290 * @param alpha Alpha channel 2291 * @param out_pixel Pixel data 2292 **/ 2293 void Utils::packPixel(GLenum internal_format, GLenum type, GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha, 2294 GLubyte* out_pixel) 2295 { 2296 switch (internal_format) 2297 { 2298 case GL_R8: 2299 case GL_R8_SNORM: 2300 case GL_R16: 2301 case GL_R16F: 2302 case GL_R16_SNORM: 2303 case GL_R32F: 2304 case GL_R8I: 2305 case GL_R8UI: 2306 case GL_R16I: 2307 case GL_R16UI: 2308 case GL_R32I: 2309 case GL_R32UI: 2310 writeChannel(type, 0, red, out_pixel); 2311 break; 2312 2313 case GL_RG8: 2314 case GL_RG8_SNORM: 2315 case GL_RG16: 2316 case GL_RG16F: 2317 case GL_RG16_SNORM: 2318 case GL_RG32F: 2319 case GL_RG8I: 2320 case GL_RG8UI: 2321 case GL_RG16I: 2322 case GL_RG16UI: 2323 case GL_RG32I: 2324 case GL_RG32UI: 2325 writeChannel(type, 0, red, out_pixel); 2326 writeChannel(type, 1, green, out_pixel); 2327 break; 2328 2329 case GL_R3_G3_B2: 2330 case GL_RGB4: 2331 case GL_RGB5: 2332 case GL_RGB8: 2333 case GL_RGB8_SNORM: 2334 case GL_RGB10: 2335 case GL_R11F_G11F_B10F: 2336 case GL_RGB12: 2337 case GL_RGB16: 2338 case GL_RGB16F: 2339 case GL_RGB16_SNORM: 2340 case GL_RGB32F: 2341 case GL_RGB8I: 2342 case GL_RGB8UI: 2343 case GL_RGB16I: 2344 case GL_RGB16UI: 2345 case GL_RGB32I: 2346 case GL_RGB32UI: 2347 writeChannel(type, 0, red, out_pixel); 2348 writeChannel(type, 1, green, out_pixel); 2349 writeChannel(type, 2, blue, out_pixel); 2350 break; 2351 2352 case GL_RGB9_E5: 2353 case GL_RGBA2: 2354 case GL_RGBA4: 2355 case GL_RGB5_A1: 2356 case GL_RGBA8: 2357 case GL_RGBA8_SNORM: 2358 case GL_RGB10_A2: 2359 case GL_RGBA12: 2360 case GL_RGBA16: 2361 case GL_RGBA16F: 2362 case GL_RGBA16_SNORM: 2363 case GL_RGBA32F: 2364 case GL_RGBA8I: 2365 case GL_RGBA8UI: 2366 case GL_RGB10_A2UI: 2367 case GL_RGBA16I: 2368 case GL_RGBA16UI: 2369 case GL_RGBA32I: 2370 case GL_RGBA32UI: 2371 writeChannel(type, 0, red, out_pixel); 2372 writeChannel(type, 1, green, out_pixel); 2373 writeChannel(type, 2, blue, out_pixel); 2374 writeChannel(type, 3, alpha, out_pixel); 2375 break; 2376 2377 default: 2378 TCU_FAIL("Invalid enum"); 2379 break; 2380 } 2381 } 2382 2383 /** Unpacks channels from pixel 2384 * 2385 * @param internal_format Internal format of image 2386 * @param type Type used by image 2387 * @param pixel Pixel data 2388 * @param red Red channel 2389 * @param green Green channel 2390 * @param blue Blue channel 2391 * @param alpha Alpha channel 2392 **/ 2393 void Utils::unpackPixel(GLenum format, GLenum type, const GLubyte* pixel, GLdouble& out_red, GLdouble& out_green, 2394 GLdouble& out_blue, GLdouble& out_alpha) 2395 { 2396 switch (format) 2397 { 2398 case GL_RED: 2399 case GL_RED_INTEGER: 2400 readChannel(type, 0, pixel, out_red); 2401 out_green = 1.0; 2402 out_blue = 1.0; 2403 out_alpha = 1.0; 2404 break; 2405 case GL_RG: 2406 case GL_RG_INTEGER: 2407 readChannel(type, 0, pixel, out_red); 2408 readChannel(type, 1, pixel, out_green); 2409 out_blue = 1.0; 2410 out_alpha = 1.0; 2411 break; 2412 case GL_RGB: 2413 case GL_RGB_INTEGER: 2414 switch (type) 2415 { 2416 case GL_UNSIGNED_INT_5_9_9_9_REV: 2417 readChannel(type, 0, pixel, out_red); 2418 readChannel(type, 1, pixel, out_green); 2419 readChannel(type, 2, pixel, out_blue); 2420 readChannel(type, 3, pixel, out_alpha); 2421 break; 2422 default: 2423 readChannel(type, 0, pixel, out_red); 2424 readChannel(type, 1, pixel, out_green); 2425 readChannel(type, 2, pixel, out_blue); 2426 out_alpha = 1.0; 2427 break; 2428 } 2429 break; 2430 case GL_RGBA: 2431 case GL_RGBA_INTEGER: 2432 readChannel(type, 0, pixel, out_red); 2433 readChannel(type, 1, pixel, out_green); 2434 readChannel(type, 2, pixel, out_blue); 2435 readChannel(type, 3, pixel, out_alpha); 2436 break; 2437 default: 2438 TCU_FAIL("Invalid enum"); 2439 break; 2440 } 2441 } 2442 2443 inline bool Utils::roundComponent(GLenum internal_format, GLenum component, GLdouble& value) 2444 { 2445 int exponent = (internal_format == GL_RGB4 ? 4 : (internal_format == GL_RGB5 ? 5 : 0)); 2446 if (!exponent) 2447 return false; //Currently this only happens with GL_RGB4 and GL_RGB5 when stored as 565 type. 2448 2449 int rounded_value = static_cast<int>(floor((pow(2, exponent) - 1) * value + 0.5)); 2450 int multiplier = (component == GL_GREEN ? 2 : 1); 2451 if (internal_format == GL_RGB4) 2452 { 2453 multiplier *= 2; 2454 } 2455 value = rounded_value * multiplier; 2456 return true; 2457 } 2458 2459 /** Unpacks pixels and compars them 2460 * 2461 * @param left_format Format of left image 2462 * @param left_type Type of left image 2463 * @param left_internal_format Internal format of left image 2464 * @param left_pixel Data of left pixel 2465 * @param right_format Format of right image 2466 * @param right_type Type of right image 2467 * @param right_internal_format Internal format of right image 2468 * @param right_pixel Data of right pixel 2469 * 2470 * @return true if pixels match, false otherwise 2471 **/ 2472 bool Utils::unpackAndComaprePixels(GLenum left_format, GLenum left_type, GLenum left_internal_format, 2473 const GLubyte* left_pixel, GLenum right_format, GLenum right_type, 2474 GLenum right_internal_format, const GLubyte* right_pixel) 2475 { 2476 GLdouble left_red; 2477 GLdouble left_green; 2478 GLdouble left_blue; 2479 GLdouble left_alpha; 2480 GLdouble right_red; 2481 GLdouble right_green; 2482 GLdouble right_blue; 2483 GLdouble right_alpha; 2484 2485 unpackPixel(left_format, left_type, left_pixel, left_red, left_green, left_blue, left_alpha); 2486 2487 unpackPixel(right_format, right_type, right_pixel, right_red, right_green, right_blue, right_alpha); 2488 2489 roundComponent(left_internal_format, GL_RED, left_red); 2490 roundComponent(left_internal_format, GL_GREEN, left_green); 2491 roundComponent(left_internal_format, GL_BLUE, left_blue); 2492 2493 roundComponent(right_internal_format, GL_RED, right_red); 2494 roundComponent(right_internal_format, GL_GREEN, right_green); 2495 roundComponent(right_internal_format, GL_BLUE, right_blue); 2496 2497 return comparePixels(left_internal_format, left_red, left_green, left_blue, left_alpha, right_internal_format, 2498 right_red, right_green, right_blue, right_alpha); 2499 } 2500 2501 /* FunctionalTest */ 2502 #define FUNCTIONAL_TEST_N_LAYERS 12 2503 #define FUNCTIONAL_TEST_N_LEVELS 3 2504 2505 /** Constructor 2506 * 2507 * @param context Text context 2508 **/ 2509 FunctionalTest::FunctionalTest(deqp::Context& context) 2510 : TestCase(context, "functional", "Test verifies CopySubImageData copy data as requested") 2511 , m_dst_buf_name(0) 2512 , m_dst_tex_name(0) 2513 , m_rb_name(0) 2514 , m_src_buf_name(0) 2515 , m_src_tex_name(0) 2516 , m_test_case_index(0) 2517 { 2518 for (GLuint src_tgt_id = 0; src_tgt_id < s_n_valid_targets; ++src_tgt_id) 2519 { 2520 const GLenum src_target = s_valid_targets[src_tgt_id]; 2521 2522 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS == 0 2523 if ((GL_TEXTURE_1D == src_target) || (GL_TEXTURE_1D_ARRAY == src_target) || (GL_TEXTURE_2D == src_target) || 2524 (GL_TEXTURE_CUBE_MAP == src_target) || (GL_TEXTURE_CUBE_MAP_ARRAY == src_target)) 2525 { 2526 continue; 2527 } 2528 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS == 0 */ 2529 2530 for (GLuint dst_tgt_id = 0; dst_tgt_id < s_n_valid_targets; ++dst_tgt_id) 2531 { 2532 const GLenum dst_target = s_valid_targets[dst_tgt_id]; 2533 2534 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS == 0 2535 if ((GL_TEXTURE_1D == dst_target) || (GL_TEXTURE_1D_ARRAY == dst_target) || (GL_TEXTURE_2D == dst_target) || 2536 (GL_TEXTURE_CUBE_MAP == dst_target) || (GL_TEXTURE_CUBE_MAP_ARRAY == dst_target)) 2537 { 2538 continue; 2539 } 2540 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS == 0 */ 2541 2542 /* Skip render buffer as destination */ 2543 if (GL_RENDERBUFFER == dst_target) 2544 { 2545 continue; 2546 } 2547 2548 /* Skip multisampled */ 2549 if ((true == Utils::isTargetMultisampled(src_target)) || (true == Utils::isTargetMultisampled(dst_target))) 2550 { 2551 continue; 2552 } 2553 2554 for (GLuint src_frmt_id = 0; src_frmt_id < s_n_internal_formats; ++src_frmt_id) 2555 { 2556 const GLenum src_format = s_internal_formats[src_frmt_id]; 2557 2558 if (src_format == GL_RGB9_E5 && src_target == GL_RENDERBUFFER) 2559 { 2560 continue; 2561 } 2562 2563 for (GLuint dst_frmt_id = 0; dst_frmt_id < s_n_internal_formats; ++dst_frmt_id) 2564 { 2565 const GLenum dst_format = s_internal_formats[dst_frmt_id]; 2566 2567 /* Skip not compatible formats */ 2568 if (false == Utils::areFormatsCompatible(src_format, dst_format)) 2569 { 2570 continue; 2571 } 2572 2573 prepareTestCases(dst_format, dst_target, src_format, src_target); 2574 } 2575 } 2576 } 2577 } 2578 } 2579 2580 /** Execute test 2581 * 2582 * @return CONTINUE as long there are more test case, STOP otherwise 2583 **/ 2584 tcu::TestNode::IterateResult FunctionalTest::iterate() 2585 { 2586 GLubyte* dst_pixels[FUNCTIONAL_TEST_N_LEVELS] = { 0 }; 2587 const Functions& gl = m_context.getRenderContext().getFunctions(); 2588 tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP; 2589 bool result = false; 2590 GLubyte* src_pixels[FUNCTIONAL_TEST_N_LEVELS] = { 0 }; 2591 const testCase& test_case = m_test_cases[m_test_case_index]; 2592 2593 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 2594 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 2595 GLU_EXPECT_NO_ERROR(gl.getError(), "PixelStorei"); 2596 2597 try 2598 { 2599 /* Prepare pixels */ 2600 prepareDstPxls(test_case.m_dst, dst_pixels); 2601 prepareSrcPxls(test_case.m_src, test_case.m_dst.m_internal_format, src_pixels); 2602 2603 /* Prepare textures */ 2604 m_dst_tex_name = prepareTexture(test_case.m_dst, (const GLubyte**)dst_pixels, m_dst_buf_name); 2605 2606 if (GL_RENDERBUFFER == test_case.m_src.m_target) 2607 { 2608 targetDesc desc = test_case.m_src; 2609 desc.m_target = GL_TEXTURE_2D; 2610 2611 m_rb_name = prepareTexture(test_case.m_src, (const GLubyte**)src_pixels, m_src_buf_name); 2612 m_src_tex_name = prepareTexture(desc, (const GLubyte**)src_pixels, m_src_buf_name); 2613 } 2614 else 2615 { 2616 m_src_tex_name = prepareTexture(test_case.m_src, (const GLubyte**)src_pixels, m_src_buf_name); 2617 } 2618 2619 /* Copy images and verify results */ 2620 result = copyAndVerify(test_case, (const GLubyte**)dst_pixels, (const GLubyte**)src_pixels); 2621 } 2622 catch (tcu::Exception& exc) 2623 { 2624 clean(); 2625 cleanPixels((GLubyte**)dst_pixels); 2626 cleanPixels((GLubyte**)src_pixels); 2627 throw exc; 2628 } 2629 2630 /* Free resources */ 2631 clean(); 2632 cleanPixels((GLubyte**)dst_pixels); 2633 cleanPixels((GLubyte**)src_pixels); 2634 2635 /* Set result */ 2636 if (true == result) 2637 { 2638 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2639 2640 /* Increase index */ 2641 m_test_case_index += 1; 2642 2643 /* Are there any test cases left */ 2644 if (m_test_cases.size() > m_test_case_index) 2645 { 2646 it_result = tcu::TestNode::CONTINUE; 2647 } 2648 } 2649 else 2650 { 2651 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failure. " << tcu::TestLog::EndMessage; 2652 2653 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2654 } 2655 2656 /* Done */ 2657 return it_result; 2658 } 2659 2660 /** Calculate dimmensions of all levels based on size of specific level 2661 * 2662 * @param target Target of image 2663 * @param level Level index 2664 * @param width Width of image at <level> 2665 * @param height Height of image at <level> 2666 * @param out_widths Calcualted widths, array of FUNCTIONAL_TEST_N_LEVELS'th elements 2667 * @param out_heights Calculated heights, array of FUNCTIONAL_TEST_N_LEVELS'th elements 2668 * @param out_depths Calculated dephts, array of FUNCTIONAL_TEST_N_LEVELS'th elements 2669 **/ 2670 void FunctionalTest::calculateDimmensions(GLenum target, GLuint level, GLuint width, GLuint height, GLuint* out_widths, 2671 GLuint* out_heights, GLuint* out_depths) const 2672 { 2673 GLuint divide = 100; 2674 GLuint factors[FUNCTIONAL_TEST_N_LEVELS]; 2675 GLuint factor = divide; 2676 const bool is_multi_layer = Utils::isTargetMultilayer(target); 2677 const GLuint n_layers = (true == is_multi_layer) ? FUNCTIONAL_TEST_N_LAYERS : 1; 2678 2679 for (GLint i = (GLint)level; i >= 0; --i) 2680 { 2681 factors[i] = factor; 2682 factor *= 2; 2683 } 2684 2685 factor = divide / 2; 2686 for (GLuint i = level + 1; i < FUNCTIONAL_TEST_N_LEVELS; ++i) 2687 { 2688 factors[i] = factor; 2689 factor /= 2; 2690 } 2691 2692 for (GLuint i = 0; i < FUNCTIONAL_TEST_N_LEVELS; ++i) 2693 { 2694 out_widths[i] = width * factors[i] / divide; 2695 out_heights[i] = height * factors[i] / divide; 2696 2697 if (GL_TEXTURE_3D == target) 2698 { 2699 out_depths[i] = FUNCTIONAL_TEST_N_LAYERS * factors[i] / divide; 2700 } 2701 else 2702 { 2703 out_depths[i] = n_layers; 2704 } 2705 } 2706 } 2707 2708 /** Execute copyImageSubData for given test case and verify results 2709 * 2710 * @param test_case Test case 2711 * @param dst_pixels Data of destination image 2712 * @param src_pixels Data of source image 2713 * 2714 * @return true if there is no error and results match expectations, false otherwise 2715 **/ 2716 bool FunctionalTest::copyAndVerify(const testCase& test_case, const GLubyte** dst_pixels, const GLubyte** src_pixels) 2717 { 2718 GLenum error = GL_NO_ERROR; 2719 const Functions& gl = m_context.getRenderContext().getFunctions(); 2720 GLuint region_depth = 1; 2721 GLuint dst_layer_step = 0; 2722 const bool is_dst_multi_layer = Utils::isTargetMultilayer(test_case.m_dst.m_target); 2723 const bool is_src_multi_layer = Utils::isTargetMultilayer(test_case.m_src.m_target); 2724 bool result = false; 2725 GLuint src_layer_step = 0; 2726 GLuint n_layers = 1; 2727 2728 /* Configure layers */ 2729 if ((true == is_dst_multi_layer) || (true == is_src_multi_layer)) 2730 { 2731 if (is_src_multi_layer == is_dst_multi_layer) 2732 { 2733 /* Both objects are multilayered, copy all layers at once, verify at once */ 2734 region_depth = FUNCTIONAL_TEST_N_LAYERS; 2735 } 2736 else if (true == is_dst_multi_layer) 2737 { 2738 /* Destination is multilayered, copy each layer separetly, verify at once */ 2739 n_layers = FUNCTIONAL_TEST_N_LAYERS; 2740 dst_layer_step = 1; 2741 } 2742 else 2743 { 2744 /* Destination is multilayered, copy and verify each layer separetly */ 2745 n_layers = FUNCTIONAL_TEST_N_LAYERS; 2746 src_layer_step = 1; 2747 } 2748 } 2749 2750 /* Copy and verification */ 2751 { 2752 GLuint dst_layer = 0; 2753 GLuint src_layer = 0; 2754 2755 /* For each layer */ 2756 for (GLuint layer = 0; layer < n_layers; ++layer) 2757 { 2758 if (0 == m_rb_name) 2759 { 2760 gl.copyImageSubData(m_src_tex_name, test_case.m_src.m_target, test_case.m_src.m_level, 2761 test_case.m_src_x, test_case.m_src_y, src_layer, m_dst_tex_name, 2762 test_case.m_dst.m_target, test_case.m_dst.m_level, test_case.m_dst_x, 2763 test_case.m_dst_y, dst_layer, test_case.m_width, test_case.m_height, region_depth); 2764 } 2765 else /* Copy from src to rb and from rb to dst */ 2766 { 2767 /* Src and rb shares differs only on target */ 2768 gl.copyImageSubData(m_src_tex_name, GL_TEXTURE_2D, test_case.m_src.m_level, test_case.m_src_x, 2769 test_case.m_src_y, src_layer, m_rb_name, test_case.m_src.m_target, 2770 test_case.m_src.m_level, test_case.m_src_x, test_case.m_src_y, src_layer, 2771 test_case.m_width, test_case.m_height, region_depth); 2772 2773 gl.copyImageSubData(m_rb_name, test_case.m_src.m_target, test_case.m_src.m_level, test_case.m_src_x, 2774 test_case.m_src_y, src_layer, m_dst_tex_name, test_case.m_dst.m_target, 2775 test_case.m_dst.m_level, test_case.m_dst_x, test_case.m_dst_y, dst_layer, 2776 test_case.m_width, test_case.m_height, region_depth); 2777 } 2778 2779 /* Verify generated error */ 2780 error = gl.getError(); 2781 2782 if (GL_NO_ERROR == error) 2783 { 2784 /* Verify copy results */ 2785 result = verify(test_case, dst_layer, dst_pixels, src_layer, src_pixels, region_depth); 2786 } 2787 2788 if ((GL_NO_ERROR != error) || (false == result)) 2789 { 2790 m_context.getTestContext().getLog() 2791 << tcu::TestLog::Message 2792 << "Failure. Targets src: " << glu::getTextureTargetStr(test_case.m_src.m_target) 2793 << ", dst: " << glu::getTextureTargetStr(test_case.m_dst.m_target) 2794 << ". Levels src: " << test_case.m_src.m_level << ", dst: " << test_case.m_dst.m_level 2795 << ". Dimmensions src [" << test_case.m_src.m_width << ", " << test_case.m_src.m_height 2796 << "], dst [" << test_case.m_dst.m_width << ", " << test_case.m_dst.m_height << "]. Region [" 2797 << test_case.m_width << " x " << test_case.m_height << " x " << region_depth << "] from [" 2798 << test_case.m_src_x << ", " << test_case.m_src_y << ", " << src_layer << "] to [" 2799 << test_case.m_dst_x << ", " << test_case.m_dst_y << ", " << dst_layer 2800 << "]. Format src: " << glu::getInternalFormatParameterStr(test_case.m_src.m_internal_format) 2801 << ", dst: " << glu::getInternalFormatParameterStr(test_case.m_dst.m_internal_format) 2802 << tcu::TestLog::EndMessage; 2803 2804 if (GL_NO_ERROR != error) 2805 { 2806 m_context.getTestContext().getLog() << tcu::TestLog::Message 2807 << "Failed due to error: " << glu::getErrorStr(error) 2808 << tcu::TestLog::EndMessage; 2809 2810 TCU_FAIL("Copy operation failed"); 2811 } 2812 2813 return false; 2814 } 2815 2816 /* Step one layer */ 2817 dst_layer += dst_layer_step; 2818 src_layer += src_layer_step; 2819 } 2820 } 2821 2822 return true; 2823 } 2824 2825 /** Cleans resources 2826 * 2827 **/ 2828 void FunctionalTest::clean() 2829 { 2830 const Functions& gl = m_context.getRenderContext().getFunctions(); 2831 2832 /* Clean textures and buffers. Errors ignored */ 2833 gl.deleteTextures(1, &m_dst_tex_name); 2834 gl.deleteTextures(1, &m_src_tex_name); 2835 2836 m_dst_tex_name = 0; 2837 m_src_tex_name = 0; 2838 2839 if (0 != m_dst_buf_name) 2840 { 2841 gl.deleteBuffers(1, &m_dst_buf_name); 2842 m_dst_buf_name = 0; 2843 } 2844 2845 if (0 != m_rb_name) 2846 { 2847 gl.deleteRenderbuffers(1, &m_rb_name); 2848 m_rb_name = 0; 2849 } 2850 2851 if (0 != m_src_buf_name) 2852 { 2853 gl.deleteBuffers(1, &m_src_buf_name); 2854 m_src_buf_name = 0; 2855 } 2856 } 2857 2858 /** Free memory allocated for images 2859 * 2860 * @param pixels Array of pointers to image data 2861 **/ 2862 void FunctionalTest::cleanPixels(GLubyte** pixels) const 2863 { 2864 for (GLuint i = 0; i < FUNCTIONAL_TEST_N_LEVELS; ++i) 2865 { 2866 if (0 != pixels[i]) 2867 { 2868 delete[] pixels[i]; 2869 pixels[i] = 0; 2870 } 2871 } 2872 } 2873 2874 /** Compare two images 2875 * @param left_desc Descriptor of left image 2876 * @param left_data Data of left image 2877 * @param left_x X of left image 2878 * @param left_y Y of left image 2879 * @param left_layer Layer of left image 2880 * @param left_level Level of left image 2881 * @param right_desc Descriptor of right image 2882 * @param right_data Data of right image 2883 * @param right_x X of right image 2884 * @param right_y Y of right image 2885 * @param right_layer Layer of right image 2886 * @param right_level Level of right image 2887 * @param region_width Width of region to compare 2888 * @param region_height Height of region to compare 2889 * 2890 * @return true if images are considered idenctial, false otherwise 2891 **/ 2892 bool FunctionalTest::compareImages(const targetDesc& left_desc, const GLubyte* left_data, GLuint left_x, GLuint left_y, 2893 GLuint left_layer, GLuint left_level, const targetDesc& right_desc, 2894 const glw::GLubyte* right_data, GLuint right_x, GLuint right_y, GLuint right_layer, 2895 GLuint right_level, GLuint region_width, GLuint region_height) const 2896 { 2897 /* Get level dimmensions */ 2898 GLuint left_heights[FUNCTIONAL_TEST_N_LEVELS]; 2899 GLuint left_widths[FUNCTIONAL_TEST_N_LEVELS]; 2900 GLuint left_depths[FUNCTIONAL_TEST_N_LEVELS]; 2901 GLuint right_heights[FUNCTIONAL_TEST_N_LEVELS]; 2902 GLuint right_widths[FUNCTIONAL_TEST_N_LEVELS]; 2903 GLuint right_depths[FUNCTIONAL_TEST_N_LEVELS]; 2904 2905 calculateDimmensions(left_desc.m_target, left_desc.m_level, left_desc.m_width, left_desc.m_height, left_widths, 2906 left_heights, left_depths); 2907 2908 calculateDimmensions(right_desc.m_target, right_desc.m_level, right_desc.m_width, right_desc.m_height, right_widths, 2909 right_heights, right_depths); 2910 2911 /* Constants */ 2912 /* Dimmensions */ 2913 const GLuint left_height = left_heights[left_level]; 2914 const GLuint left_width = left_widths[left_level]; 2915 const GLuint right_height = right_heights[right_level]; 2916 const GLuint right_width = right_widths[right_level]; 2917 /* Sizes */ 2918 const GLuint left_pixel_size = Utils::getPixelSizeForFormat(left_desc.m_internal_format); 2919 const GLuint left_line_size = left_pixel_size * left_width; 2920 const GLuint left_layer_size = left_line_size * left_height; 2921 const GLuint right_pixel_size = Utils::getPixelSizeForFormat(right_desc.m_internal_format); 2922 const GLuint right_line_size = right_pixel_size * right_width; 2923 const GLuint right_layer_size = right_line_size * right_height; 2924 2925 /* Offsets */ 2926 const GLuint left_layer_offset = left_layer_size * left_layer; 2927 const GLuint left_reg_line_offset = left_line_size * left_y; 2928 const GLuint left_reg_pix_offset = left_pixel_size * left_x; 2929 const GLuint right_layer_offset = right_layer_size * right_layer; 2930 const GLuint right_reg_line_offset = right_line_size * right_y; 2931 const GLuint right_reg_pix_offset = right_pixel_size * right_x; 2932 2933 /* Pointers */ 2934 const GLubyte* left_layer_data = left_data + left_layer_offset; 2935 const GLubyte* right_layer_data = right_data + right_layer_offset; 2936 2937 /* For each line of region */ 2938 for (GLuint y = 0; y < region_height; ++y) 2939 { 2940 /* Offsets */ 2941 const GLuint left_line_offset = left_reg_line_offset + y * left_line_size; 2942 const GLuint right_line_offset = right_reg_line_offset + y * right_line_size; 2943 2944 /* Pointers */ 2945 const GLubyte* left_line_data = left_layer_data + left_line_offset; 2946 const GLubyte* right_line_data = right_layer_data + right_line_offset; 2947 2948 /* For each pixel of region */ 2949 for (GLuint x = 0; x < region_width; ++x) 2950 { 2951 /* Offsets */ 2952 const GLuint left_pixel_offset = left_reg_pix_offset + x * left_pixel_size; 2953 const GLuint right_pixel_offset = right_reg_pix_offset + x * right_pixel_size; 2954 2955 /* Pointers */ 2956 const GLubyte* left_pixel_data = left_line_data + left_pixel_offset; 2957 const GLubyte* right_pixel_data = right_line_data + right_pixel_offset; 2958 2959 /* Compare */ 2960 if (false == Utils::comparePixels(left_pixel_size, left_pixel_data, right_pixel_size, right_pixel_data)) 2961 { 2962 if (false == Utils::unpackAndComaprePixels(left_desc.m_format, left_desc.m_type, 2963 left_desc.m_internal_format, left_pixel_data, 2964 right_desc.m_format, right_desc.m_type, 2965 right_desc.m_internal_format, right_pixel_data)) 2966 { 2967 m_context.getTestContext().getLog() 2968 << tcu::TestLog::Message << "Not matching pixels found. Left: [" << x + left_x << ", " 2969 << y + left_y << ", " << left_layer << "] lvl:" << left_level 2970 << ", off: " << left_pixel_data - left_data 2971 << ", data: " << Utils::getPixelString(left_desc.m_internal_format, left_pixel_data) 2972 << ". Right: [" << x + right_x << ", " << y + right_y << ", " << right_layer 2973 << "] lvl: " << right_level << ", off: " << right_pixel_data - right_data 2974 << ", data: " << Utils::getPixelString(right_desc.m_internal_format, right_pixel_data) 2975 << tcu::TestLog::EndMessage; 2976 2977 return false; 2978 } 2979 } 2980 } 2981 } 2982 2983 return true; 2984 } 2985 2986 /** Prepare regions that should not be modified during test case 2987 * 2988 * @param test_case Test case descriptor 2989 * @param dst_level Level of destination image 2990 * @param out_regions Number of regions 2991 * @param out_n_regions Regions 2992 **/ 2993 void FunctionalTest::getCleanRegions(const testCase& test_case, GLuint dst_level, GLuint out_regions[4][4], 2994 GLuint& out_n_regions) const 2995 { 2996 GLuint dst_heights[FUNCTIONAL_TEST_N_LEVELS]; 2997 GLuint dst_widths[FUNCTIONAL_TEST_N_LEVELS]; 2998 GLuint dst_depths[FUNCTIONAL_TEST_N_LEVELS]; 2999 3000 out_n_regions = 0; 3001 3002 calculateDimmensions(test_case.m_dst.m_target, dst_level, test_case.m_dst.m_width, test_case.m_dst.m_height, 3003 dst_widths, dst_heights, dst_depths); 3004 3005 /* Constants */ 3006 /* Copied region */ 3007 const GLuint reg_x = test_case.m_dst_x; 3008 const GLuint reg_y = test_case.m_dst_y; 3009 const GLuint reg_w = test_case.m_width; 3010 const GLuint reg_h = test_case.m_height; 3011 const GLuint reg_r = reg_x + reg_w; 3012 const GLuint reg_t = reg_y + reg_h; 3013 3014 /* Image */ 3015 const GLuint img_w = dst_widths[dst_level]; 3016 const GLuint img_h = dst_heights[dst_level]; 3017 3018 /* Bottom row */ 3019 if (0 != reg_y) 3020 { 3021 out_regions[out_n_regions][0] = 0; 3022 out_regions[out_n_regions][1] = 0; 3023 out_regions[out_n_regions][2] = img_w; 3024 out_regions[out_n_regions][3] = reg_y; 3025 out_n_regions += 1; 3026 } 3027 3028 /* Left edge */ 3029 if (0 != reg_x) 3030 { 3031 out_regions[out_n_regions][0] = 0; 3032 out_regions[out_n_regions][1] = reg_y; 3033 out_regions[out_n_regions][2] = reg_x; 3034 out_regions[out_n_regions][3] = reg_h; 3035 out_n_regions += 1; 3036 } 3037 3038 /* Right edge */ 3039 if (img_w != reg_r) 3040 { 3041 out_regions[out_n_regions][0] = reg_r; 3042 out_regions[out_n_regions][1] = reg_y; 3043 out_regions[out_n_regions][2] = img_w - reg_r; 3044 out_regions[out_n_regions][3] = reg_h; 3045 out_n_regions += 1; 3046 } 3047 3048 /* Top row */ 3049 if (img_h != reg_t) 3050 { 3051 out_regions[out_n_regions][0] = 0; 3052 out_regions[out_n_regions][1] = reg_t; 3053 out_regions[out_n_regions][2] = img_w; 3054 out_regions[out_n_regions][3] = img_h - reg_t; 3055 out_n_regions += 1; 3056 } 3057 } 3058 3059 /** Get pixel data for image 3060 * 3061 * @param name Name of image 3062 * @param desc Descriptor of image 3063 * @param level Level to capture 3064 * @param out_pixels Pixels 3065 **/ 3066 void FunctionalTest::getPixels(GLuint name, const targetDesc& desc, GLuint level, GLubyte* out_pixels) const 3067 { 3068 const Functions& gl = m_context.getRenderContext().getFunctions(); 3069 3070 gl.bindTexture(desc.m_target, name); 3071 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3072 3073 gl.getTexImage(desc.m_target, level, desc.m_format, desc.m_type, out_pixels); 3074 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 3075 3076 gl.bindTexture(desc.m_target, 0); 3077 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3078 } 3079 3080 /** Prepare data for destination image 3081 * 3082 * @param desc Descriptor 3083 * @param out_pixels Array of pointer to image data 3084 **/ 3085 void FunctionalTest::prepareDstPxls(const FunctionalTest::targetDesc& desc, GLubyte** out_pixels) const 3086 { 3087 const GLenum internal_format = desc.m_internal_format; 3088 const bool is_multi_level = Utils::isTargetMultilevel(desc.m_target); 3089 GLuint n_levels = 1; 3090 const GLuint pixel_size = Utils::getPixelSizeForFormat(desc.m_internal_format); 3091 const GLenum type = desc.m_type; 3092 3093 /* Configure levels */ 3094 if (true == is_multi_level) 3095 { 3096 n_levels = FUNCTIONAL_TEST_N_LEVELS; 3097 } 3098 3099 /* Calculate dimmensions */ 3100 GLuint heights[FUNCTIONAL_TEST_N_LEVELS]; 3101 GLuint widths[FUNCTIONAL_TEST_N_LEVELS]; 3102 GLuint depths[FUNCTIONAL_TEST_N_LEVELS]; 3103 3104 calculateDimmensions(desc.m_target, desc.m_level, desc.m_width, desc.m_height, widths, heights, depths); 3105 3106 /* Prepare storage */ 3107 for (GLuint i = 0; i < n_levels; ++i) 3108 { 3109 const GLuint req_memory_per_layer = pixel_size * widths[i] * heights[i]; 3110 const GLuint req_memory_for_level = req_memory_per_layer * depths[i]; 3111 3112 out_pixels[i] = new GLubyte[req_memory_for_level]; 3113 3114 if (0 == out_pixels[i]) 3115 { 3116 TCU_FAIL("Memory allocation failed"); 3117 } 3118 3119 memset(out_pixels[i], 0, req_memory_for_level); 3120 } 3121 3122 /* Fill pixels */ 3123 for (GLuint i = 0; i < n_levels; ++i) 3124 { 3125 const GLuint n_layers = depths[i]; 3126 const GLuint n_pixels = widths[i] * heights[i]; 3127 GLubyte* ptr = (GLubyte*)out_pixels[i]; 3128 3129 for (GLuint j = 0; j < n_pixels * n_layers; ++j) 3130 { 3131 GLubyte* pixel_data = ptr + j * pixel_size; 3132 3133 Utils::packPixel(internal_format, type, 1.0, 1.0, 1.0, 1.0, pixel_data); 3134 } 3135 } 3136 } 3137 3138 /** Prepare data for source image 3139 * 3140 * @param desc Descriptor 3141 * @param dst_internal_format Internal format of destination image 3142 * @param out_pixels Array of pointer to image data 3143 **/ 3144 void FunctionalTest::prepareSrcPxls(const FunctionalTest::targetDesc& desc, GLenum /* dst_internal_format */, 3145 GLubyte** out_pixels) const 3146 { 3147 const GLenum internal_format = desc.m_internal_format; 3148 const bool is_multi_level = Utils::isTargetMultilevel(desc.m_target); 3149 GLuint n_levels = 1; 3150 const GLuint pixel_size = Utils::getPixelSizeForFormat(desc.m_internal_format); 3151 const GLenum type = desc.m_type; 3152 3153 /* Configure levels */ 3154 if (true == is_multi_level) 3155 { 3156 n_levels = FUNCTIONAL_TEST_N_LEVELS; 3157 } 3158 3159 /* Calculate dimmensions */ 3160 GLuint heights[FUNCTIONAL_TEST_N_LEVELS]; 3161 GLuint widths[FUNCTIONAL_TEST_N_LEVELS]; 3162 GLuint depths[FUNCTIONAL_TEST_N_LEVELS]; 3163 3164 calculateDimmensions(desc.m_target, desc.m_level, desc.m_width, desc.m_height, widths, heights, depths); 3165 3166 /* Prepare storage */ 3167 for (GLuint i = 0; i < n_levels; ++i) 3168 { 3169 const GLuint req_memory_per_layer = pixel_size * widths[i] * heights[i]; 3170 const GLuint req_memory_for_level = req_memory_per_layer * depths[i]; 3171 3172 out_pixels[i] = new GLubyte[req_memory_for_level]; 3173 3174 if (0 == out_pixels[i]) 3175 { 3176 TCU_FAIL("Memory allocation failed"); 3177 } 3178 3179 memset(out_pixels[i], 0, req_memory_for_level); 3180 } 3181 3182 for (GLuint lvl = 0; lvl < n_levels; ++lvl) 3183 { 3184 const GLuint n_layers = depths[lvl]; 3185 const GLuint line_size = pixel_size * widths[lvl]; 3186 const GLuint req_memory_per_layer = line_size * heights[lvl]; 3187 GLubyte* level = (GLubyte*)out_pixels[lvl]; 3188 3189 for (GLuint lay = 0; lay < n_layers; ++lay) 3190 { 3191 const GLuint layer_offset = lay * req_memory_per_layer; 3192 3193 GLubyte* layer = ((GLubyte*)level) + layer_offset; 3194 3195 for (GLuint y = 0; y < heights[lvl]; ++y) 3196 { 3197 const GLuint line_offset = line_size * y; 3198 3199 GLubyte* line = layer + line_offset; 3200 3201 for (GLuint x = 0; x < widths[lvl]; ++x) 3202 { 3203 const GLuint pixel_offset = x * pixel_size; 3204 3205 GLubyte* pixel = line + pixel_offset; 3206 3207 /* 255 is max ubyte. 1/15.9375 = 16/255 */ 3208 const GLdouble red = ((GLdouble)x) / 255.0 + (((GLdouble)y) / 15.9375); 3209 const GLdouble green = ((GLdouble)lay) / 255.0 + (((GLdouble)lvl) / 15.9375); 3210 const GLdouble blue = 0.125; 3211 const GLdouble alpha = 1.0; /* This value has special meaning for some internal_formats */ 3212 3213 Utils::packPixel(internal_format, type, red, green, blue, alpha, pixel); 3214 } 3215 } 3216 } 3217 } 3218 } 3219 3220 /** Prepare test cases for given targets and internal formats 3221 * 3222 * @param dst_internal_format Internal format of destination image 3223 * @param dst_target Target of destination image 3224 * @param src_internal_format Internal format of source image 3225 * @param src_target Target of source image 3226 **/ 3227 void FunctionalTest::prepareTestCases(GLenum dst_internal_format, GLenum dst_target, GLenum src_internal_format, 3228 GLenum src_target) 3229 { 3230 static const GLuint image_dimmensions[] = { 3231 7, 3232 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_IMG_DIM 3233 8, 3234 9, 3235 10, 3236 11, 3237 12, 3238 13, 3239 14, 3240 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_IMG_DIM */ 3241 15 3242 }; 3243 3244 static const GLuint region_dimmensions[] = { 3245 1, 3246 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_DIM 3247 2, 3248 3, 3249 4, 3250 5, 3251 6, 3252 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_DIM */ 3253 7 3254 }; 3255 3256 static const GLuint n_image_dimmensions = sizeof(image_dimmensions) / sizeof(image_dimmensions[0]); 3257 static const GLuint n_region_dimmensions = sizeof(region_dimmensions) / sizeof(region_dimmensions[0]); 3258 3259 const bool is_dst_multi_level = Utils::isTargetMultilevel(dst_target); 3260 const bool is_src_multi_level = Utils::isTargetMultilevel(src_target); 3261 const GLenum dst_format = Utils::getFormat(dst_internal_format); 3262 const GLuint dst_n_levels = (true == is_dst_multi_level) ? FUNCTIONAL_TEST_N_LEVELS : 1; 3263 const GLenum dst_type = Utils::getType(dst_internal_format); 3264 const GLenum src_format = Utils::getFormat(src_internal_format); 3265 const GLuint src_n_levels = (true == is_src_multi_level) ? FUNCTIONAL_TEST_N_LEVELS : 1; 3266 const GLenum src_type = Utils::getType(src_internal_format); 3267 3268 for (GLuint src_level = 0; src_level < src_n_levels; ++src_level) 3269 { 3270 for (GLuint dst_level = 0; dst_level < dst_n_levels; ++dst_level) 3271 { 3272 for (GLuint src_img_dim_id = 0; src_img_dim_id < n_image_dimmensions; ++src_img_dim_id) 3273 { 3274 const GLuint src_image_dimmension = image_dimmensions[src_img_dim_id]; 3275 3276 for (GLuint dst_img_dim_id = 0; dst_img_dim_id < n_image_dimmensions; ++dst_img_dim_id) 3277 { 3278 const GLuint dst_image_dimmension = image_dimmensions[dst_img_dim_id]; 3279 3280 for (GLuint reg_dim_id = 0; reg_dim_id < n_region_dimmensions; ++reg_dim_id) 3281 { 3282 const GLuint region_dimmension = region_dimmensions[reg_dim_id]; 3283 GLuint dst_coord[3] = { 0, 0, 0 }; 3284 const GLuint dst_dim_diff = dst_image_dimmension - region_dimmension; 3285 GLuint n_dst_coords = 1; 3286 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS 3287 GLuint n_src_coords = 1; 3288 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */ 3289 GLuint src_coord[3] = { 0, 0, 0 }; 3290 const GLuint src_dim_diff = src_image_dimmension - region_dimmension; 3291 3292 /* Calculate coords */ 3293 if (1 == dst_dim_diff) 3294 { 3295 dst_coord[1] = 1; 3296 n_dst_coords = 2; 3297 } 3298 else if (1 < dst_dim_diff) 3299 { 3300 dst_coord[1] = dst_dim_diff / 2; 3301 dst_coord[2] = dst_dim_diff; 3302 n_dst_coords = 3; 3303 } 3304 3305 if (1 == src_dim_diff) 3306 { 3307 src_coord[1] = 1; 3308 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS 3309 n_src_coords = 2; 3310 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */ 3311 } 3312 else if (1 < src_dim_diff) 3313 { 3314 src_coord[1] = src_dim_diff / 2; 3315 src_coord[2] = src_dim_diff; 3316 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS 3317 n_src_coords = 3; 3318 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */ 3319 } 3320 3321 testCase test_case = { 3322 { /* m_dst */ 3323 dst_target, dst_image_dimmension, /* width */ 3324 dst_image_dimmension, /* height */ 3325 dst_level, dst_internal_format, dst_format, dst_type }, 3326 0, /* dst_x */ 3327 0, /* dst_y */ 3328 { /* m_src */ 3329 src_target, src_image_dimmension, /* width */ 3330 src_image_dimmension, /* height */ 3331 src_level, src_internal_format, src_format, src_type }, 3332 0, /* src_x */ 3333 0, /* src_y */ 3334 region_dimmension, /* width */ 3335 region_dimmension, /* height */ 3336 }; 3337 3338 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS 3339 for (GLuint src_x = 0; src_x < n_src_coords; ++src_x) 3340 { 3341 for (GLuint src_y = 0; src_y < n_src_coords; ++src_y) 3342 { 3343 for (GLuint dst_x = 0; dst_x < n_dst_coords; ++dst_x) 3344 { 3345 for (GLuint dst_y = 0; dst_y < n_dst_coords; ++dst_y) 3346 { 3347 test_case.m_dst_x = dst_coord[dst_x]; 3348 test_case.m_dst_y = dst_coord[dst_y]; 3349 test_case.m_src_x = src_coord[src_x]; 3350 test_case.m_src_y = src_coord[src_y]; 3351 3352 m_test_cases.push_back(test_case); 3353 } 3354 } 3355 } 3356 } 3357 #else /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */ 3358 test_case.m_dst_x = dst_coord[n_dst_coords - 1]; 3359 test_case.m_dst_y = dst_coord[n_dst_coords - 1]; 3360 test_case.m_src_x = src_coord[0]; 3361 test_case.m_src_y = src_coord[0]; 3362 3363 m_test_cases.push_back(test_case); 3364 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */ 3365 3366 /* Whole image, for non 7x7 */ 3367 if ((dst_image_dimmension == src_image_dimmension) && 3368 (image_dimmensions[0] != dst_image_dimmension)) 3369 { 3370 test_case.m_dst_x = 0; 3371 test_case.m_dst_y = 0; 3372 test_case.m_src_x = 0; 3373 test_case.m_src_y = 0; 3374 test_case.m_width = dst_image_dimmension; 3375 test_case.m_height = dst_image_dimmension; 3376 3377 m_test_cases.push_back(test_case); 3378 } 3379 } 3380 } 3381 } 3382 } 3383 } 3384 } 3385 3386 /** Prepare texture 3387 * 3388 * @param desc Descriptor 3389 * @param pixels Image data 3390 * @param out_buf_id Id of buffer used by texture buffer 3391 * 3392 * @return Name of iamge 3393 **/ 3394 GLuint FunctionalTest::prepareTexture(const targetDesc& desc, const GLubyte** pixels, GLuint& out_buf_id) 3395 { 3396 GLuint name = Utils::generateTexture(m_context, desc.m_target); 3397 3398 if (false == Utils::isTargetMultilevel(desc.m_target)) 3399 { 3400 Utils::prepareTexture(m_context, name, desc.m_target, desc.m_internal_format, desc.m_format, desc.m_type, 3401 0 /* level */, desc.m_width, desc.m_height, 3402 FUNCTIONAL_TEST_N_LAYERS /* depth - 12 for multilayered, 1D and 2D will ignore that */, 3403 pixels[0], out_buf_id); 3404 3405 Utils::makeTextureComplete(m_context, desc.m_target, name, 0 /* base */, 0 /* max */); 3406 } 3407 else 3408 { 3409 /* Calculate dimmensions */ 3410 GLuint heights[FUNCTIONAL_TEST_N_LEVELS]; 3411 GLuint widths[FUNCTIONAL_TEST_N_LEVELS]; 3412 GLuint depths[FUNCTIONAL_TEST_N_LEVELS]; 3413 3414 calculateDimmensions(desc.m_target, desc.m_level, desc.m_width, desc.m_height, widths, heights, depths); 3415 3416 for (GLuint level = 0; level < FUNCTIONAL_TEST_N_LEVELS; ++level) 3417 { 3418 Utils::prepareTexture(m_context, name, desc.m_target, desc.m_internal_format, desc.m_format, desc.m_type, 3419 level, widths[level], heights[level], depths[level], pixels[level], out_buf_id); 3420 3421 Utils::makeTextureComplete(m_context, desc.m_target, name, 0 /* base */, 2 /* max */); 3422 } 3423 } 3424 3425 return name; 3426 } 3427 3428 /** Verify copy operation 3429 * 3430 * @param test_case Test case 3431 * @param dst_layer First layer modified by copy 3432 * @param dst_pixels Origiranl data of destination image 3433 * @param src_layer First layer read by copy 3434 * @param src_pixels Original data of source image 3435 * @param depth Number of copied layers 3436 * 3437 * @return true if everything is as expected, false otherwise 3438 **/ 3439 bool FunctionalTest::verify(const testCase& test_case, GLuint dst_layer, const GLubyte** dst_pixels, GLuint src_layer, 3440 const GLubyte** src_pixels, GLuint depth) 3441 { 3442 const bool is_dst_multi_level = Utils::isTargetMultilevel(test_case.m_dst.m_target); 3443 const bool is_src_multi_level = Utils::isTargetMultilevel(test_case.m_src.m_target); 3444 const GLuint dst_level = test_case.m_dst.m_level; 3445 std::vector<GLubyte> dst_level_data; 3446 const GLuint dst_pixel_size = Utils::getPixelSizeForFormat(test_case.m_dst.m_internal_format); 3447 targetDesc src_desc = test_case.m_src; 3448 const GLuint src_level = src_desc.m_level; 3449 std::vector<GLubyte> src_level_data; 3450 const GLuint src_pixel_size = Utils::getPixelSizeForFormat(src_desc.m_internal_format); 3451 3452 if (0 != m_rb_name) 3453 { 3454 src_desc.m_target = GL_TEXTURE_2D; 3455 } 3456 3457 /* Calculate storage requirements */ 3458 GLuint dst_req_mem_per_layer[FUNCTIONAL_TEST_N_LEVELS]; 3459 GLuint dst_heights[FUNCTIONAL_TEST_N_LEVELS]; 3460 GLuint dst_widths[FUNCTIONAL_TEST_N_LEVELS]; 3461 GLuint dst_depths[FUNCTIONAL_TEST_N_LEVELS]; 3462 GLuint src_req_mem_per_layer[FUNCTIONAL_TEST_N_LEVELS]; 3463 GLuint src_heights[FUNCTIONAL_TEST_N_LEVELS]; 3464 GLuint src_widths[FUNCTIONAL_TEST_N_LEVELS]; 3465 GLuint src_depths[FUNCTIONAL_TEST_N_LEVELS]; 3466 3467 calculateDimmensions(test_case.m_dst.m_target, dst_level, test_case.m_dst.m_width, test_case.m_dst.m_height, 3468 dst_widths, dst_heights, dst_depths); 3469 3470 calculateDimmensions(src_desc.m_target, src_level, src_desc.m_width, src_desc.m_height, src_widths, src_heights, 3471 src_depths); 3472 3473 for (GLuint i = 0; i < FUNCTIONAL_TEST_N_LEVELS; ++i) 3474 { 3475 dst_req_mem_per_layer[i] = dst_widths[i] * dst_heights[i] * dst_pixel_size; 3476 src_req_mem_per_layer[i] = src_widths[i] * src_heights[i] * src_pixel_size; 3477 } 3478 3479 /* Prepare storage, use 0 level as it is the biggest one */ 3480 dst_level_data.resize(dst_req_mem_per_layer[0] * dst_depths[0]); 3481 src_level_data.resize(src_req_mem_per_layer[0] * src_depths[0]); 3482 3483 /* Verification of contents 3484 * - source image - expect no modification 3485 * - destination image, mipmap before and after dst_level - expect no modification 3486 * - destination image, mipmap at dst_level: 3487 * * layers after dst_layer + depth - expect no modification 3488 * * layers <0, dst_layer + depth> - expect that contents at selected region were copied 3489 */ 3490 3491 /* Check if source image was not modified */ 3492 { 3493 const GLuint n_levels = (true == is_src_multi_level) ? FUNCTIONAL_TEST_N_LEVELS : 1; 3494 3495 for (GLuint level = 0; level < n_levels; ++level) 3496 { 3497 getPixels(m_src_tex_name, src_desc, level, &src_level_data[0]); 3498 3499 for (GLuint layer = 0; layer < src_depths[level]; ++layer) 3500 { 3501 if (false == compareImages(src_desc, src_pixels[level], 0, 0, layer, level, src_desc, 3502 &src_level_data[0], 0, 0, layer, level, src_widths[level], 3503 src_heights[level])) 3504 { 3505 m_context.getTestContext().getLog() 3506 << tcu::TestLog::Message 3507 << "CopyImageSubData modified contents of source image. Original data: left." 3508 << tcu::TestLog::EndMessage; 3509 return false; 3510 } 3511 } 3512 } 3513 } 3514 3515 /* Check if contents of destination at levels != dst_level were not modified */ 3516 { 3517 const GLuint n_levels = (true == is_dst_multi_level) ? FUNCTIONAL_TEST_N_LEVELS : 1; 3518 3519 for (GLuint level = 0; level < n_levels; ++level) 3520 { 3521 if (dst_level == level) 3522 { 3523 continue; 3524 } 3525 3526 getPixels(m_dst_tex_name, test_case.m_dst, level, &dst_level_data[0]); 3527 3528 for (GLuint layer = 0; layer < dst_depths[level]; ++layer) 3529 { 3530 if (false == compareImages(test_case.m_dst, dst_pixels[level], 0, 0, layer, level, test_case.m_dst, 3531 &dst_level_data[0], 0, 0, layer, level, dst_widths[level], 3532 dst_heights[level])) 3533 { 3534 m_context.getTestContext().getLog() 3535 << tcu::TestLog::Message 3536 << "CopyImageSubData modified contents of wrong mipmap level. Original data: left." 3537 << tcu::TestLog::EndMessage; 3538 3539 return false; 3540 } 3541 } 3542 } 3543 } 3544 3545 /* Check contents of modified level */ 3546 { 3547 getPixels(m_dst_tex_name, test_case.m_dst, dst_level, &dst_level_data[0]); 3548 3549 /* Check anything after dst_layer + depth */ 3550 { 3551 for (GLuint layer = dst_layer + depth; layer < dst_depths[dst_level]; ++layer) 3552 { 3553 if (false == compareImages(test_case.m_dst, dst_pixels[dst_level], 0, 0, layer, dst_level, 3554 test_case.m_dst, &dst_level_data[0], 0, 0, layer, dst_level, 3555 dst_widths[dst_level], dst_heights[dst_level])) 3556 { 3557 m_context.getTestContext().getLog() 3558 << tcu::TestLog::Message 3559 << "CopyImageSubData modified contents of wrong layer. Original data: left." 3560 << tcu::TestLog::EndMessage; 3561 3562 return false; 3563 } 3564 } 3565 } 3566 3567 /* Check modified layers */ 3568 for (GLuint layer = 0; layer < depth; ++layer) 3569 { 3570 /* Check contents outside of copied region */ 3571 { 3572 GLuint n_regions = 0; 3573 GLuint regions[4][4] = { { 0 } }; 3574 3575 getCleanRegions(test_case, dst_level, regions, n_regions); 3576 3577 for (GLuint region = 0; region < n_regions; ++region) 3578 { 3579 const GLuint x = regions[region][0]; 3580 const GLuint y = regions[region][1]; 3581 const GLuint w = regions[region][2]; 3582 const GLuint h = regions[region][3]; 3583 3584 if (false == compareImages(test_case.m_dst, dst_pixels[dst_level], x, y, layer + dst_layer, 3585 dst_level, test_case.m_dst, &dst_level_data[0], x, y, layer + dst_layer, 3586 dst_level, w, h)) 3587 { 3588 m_context.getTestContext().getLog() 3589 << tcu::TestLog::Message 3590 << "CopyImageSubData modified contents outside of copied region. Original data: left." 3591 << tcu::TestLog::EndMessage; 3592 return false; 3593 } 3594 } 3595 } 3596 3597 /* Check contents of copied region */ 3598 if (false == compareImages(test_case.m_dst, &dst_level_data[0], test_case.m_dst_x, test_case.m_dst_y, 3599 layer + dst_layer, dst_level, src_desc, src_pixels[src_level], test_case.m_src_x, 3600 test_case.m_src_y, layer + src_layer, src_level, test_case.m_width, 3601 test_case.m_height)) 3602 { 3603 m_context.getTestContext().getLog() 3604 << tcu::TestLog::Message 3605 << "CopyImageSubData stored invalid data in copied region. Destination data: left." 3606 << tcu::TestLog::EndMessage; 3607 return false; 3608 } 3609 } 3610 } 3611 3612 return true; 3613 } 3614 3615 /* SmokeTest */ 3616 /* Constants */ 3617 const GLuint SmokeTest::m_width = 16; 3618 const GLuint SmokeTest::m_height = 16; 3619 const GLuint SmokeTest::m_depth = 1; 3620 3621 /** Constructor 3622 * 3623 * @param context Text context 3624 **/ 3625 SmokeTest::SmokeTest(deqp::Context& context) 3626 : TestCase(context, "smoke_test", "Test tries all formats and targets") 3627 , m_dst_buf_name(0) 3628 , m_dst_tex_name(0) 3629 , m_rb_name(0) 3630 , m_src_buf_name(0) 3631 , m_src_tex_name(0) 3632 , m_test_case_index(0) 3633 { 3634 /* Iterate over valid targets */ 3635 for (GLuint tgt_id = 0; tgt_id < s_n_valid_targets; ++tgt_id) 3636 { 3637 const GLenum target = s_valid_targets[tgt_id]; 3638 3639 if (true == Utils::isTargetMultisampled(target)) 3640 { 3641 continue; 3642 } 3643 3644 const testCase test_case = { target, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT }; 3645 3646 m_test_cases.push_back(test_case); 3647 } 3648 3649 /* Iterate over internal formats */ 3650 for (GLuint fmt_id = 0; fmt_id < s_n_internal_formats; ++fmt_id) 3651 { 3652 const GLenum internal_format = s_internal_formats[fmt_id]; 3653 const GLenum format = Utils::getFormat(internal_format); 3654 const GLenum type = Utils::getType(internal_format); 3655 3656 const testCase test_case = { GL_TEXTURE_2D, internal_format, format, type }; 3657 3658 m_test_cases.push_back(test_case); 3659 } 3660 } 3661 3662 /** Cleans resources 3663 * 3664 **/ 3665 void SmokeTest::clean() 3666 { 3667 const Functions& gl = m_context.getRenderContext().getFunctions(); 3668 3669 /* Clean textures and buffers. Errors ignored */ 3670 gl.deleteTextures(1, &m_dst_tex_name); 3671 gl.deleteTextures(1, &m_src_tex_name); 3672 3673 m_dst_tex_name = 0; 3674 m_src_tex_name = 0; 3675 3676 if (0 != m_dst_buf_name) 3677 { 3678 gl.deleteBuffers(1, &m_dst_buf_name); 3679 m_dst_buf_name = 0; 3680 } 3681 3682 if (0 != m_rb_name) 3683 { 3684 gl.deleteRenderbuffers(1, &m_rb_name); 3685 m_rb_name = 0; 3686 } 3687 3688 if (0 != m_src_buf_name) 3689 { 3690 gl.deleteBuffers(1, &m_src_buf_name); 3691 m_src_buf_name = 0; 3692 } 3693 } 3694 3695 /** Free memory allocated for images 3696 * 3697 * @param pixels Pointers to image data 3698 **/ 3699 void SmokeTest::cleanPixels(GLubyte*& pixels) const 3700 { 3701 if (0 == pixels) 3702 { 3703 return; 3704 } 3705 3706 delete[] pixels; 3707 pixels = 0; 3708 } 3709 3710 /** Compare two images 3711 * @param test_case Test case descriptor 3712 * @param left_data Data of left image 3713 * @param right_data Data of right image 3714 * 3715 * @return true if images are considered idenctial, false otherwise 3716 **/ 3717 bool SmokeTest::compareImages(const testCase& test_case, const GLubyte* left_data, const GLubyte* right_data) const 3718 { 3719 /* Constants */ 3720 /* Sizes */ 3721 const GLuint pixel_size = Utils::getPixelSizeForFormat(test_case.m_internal_format); 3722 const GLuint line_size = pixel_size * m_width; 3723 3724 GLuint height = m_height; 3725 3726 if ((GL_TEXTURE_1D == test_case.m_target) || (GL_TEXTURE_1D_ARRAY == test_case.m_target)) 3727 { 3728 height = 1; 3729 } 3730 3731 /* For each line */ 3732 for (GLuint y = 0; y < height; ++y) 3733 { 3734 /* Offsets */ 3735 const GLuint line_offset = y * line_size; 3736 3737 /* Pointers */ 3738 const GLubyte* left_line_data = left_data + line_offset; 3739 const GLubyte* right_line_data = right_data + line_offset; 3740 3741 /* For each pixel of region */ 3742 for (GLuint x = 0; x < m_width; ++x) 3743 { 3744 /* Offsets */ 3745 const GLuint pixel_offset = x * pixel_size; 3746 3747 /* Pointers */ 3748 const GLubyte* left_pixel_data = left_line_data + pixel_offset; 3749 const GLubyte* right_pixel_data = right_line_data + pixel_offset; 3750 3751 /* Compare */ 3752 if (false == Utils::comparePixels(pixel_size, left_pixel_data, pixel_size, right_pixel_data)) 3753 { 3754 if (false == Utils::unpackAndComaprePixels( 3755 test_case.m_format, test_case.m_type, test_case.m_internal_format, left_pixel_data, 3756 test_case.m_format, test_case.m_type, test_case.m_internal_format, right_pixel_data)) 3757 { 3758 m_context.getTestContext().getLog() 3759 << tcu::TestLog::Message << "Not matching pixels found. " 3760 << "[" << x << ", " << y << "], off: " << left_pixel_data - left_data 3761 << ". Data left: " << Utils::getPixelString(test_case.m_internal_format, left_pixel_data) 3762 << ", right: " << Utils::getPixelString(test_case.m_internal_format, right_pixel_data) 3763 << tcu::TestLog::EndMessage; 3764 3765 return false; 3766 } 3767 } 3768 } 3769 } 3770 3771 return true; 3772 } 3773 3774 /** Execute copyImageSubData for given test case and verify results 3775 * 3776 * @param test_case Test case 3777 * @param src_pixels Data of source image 3778 * 3779 * @return true if there is no error and results match expectations, false otherwise 3780 **/ 3781 bool SmokeTest::copyAndVerify(const testCase& test_case, const GLubyte* src_pixels) 3782 { 3783 GLenum error = GL_NO_ERROR; 3784 const Functions& gl = m_context.getRenderContext().getFunctions(); 3785 bool result = false; 3786 3787 /* Copy and verification */ 3788 { 3789 if (0 == m_rb_name) 3790 { 3791 GLuint height = m_height; 3792 3793 if ((GL_TEXTURE_1D == test_case.m_target) || (GL_TEXTURE_1D_ARRAY == test_case.m_target)) 3794 { 3795 height = 1; 3796 } 3797 3798 gl.copyImageSubData(m_src_tex_name, test_case.m_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */, 3799 0 /* srcZ */, m_dst_tex_name, test_case.m_target, 0 /* dstLevel */, 0 /* dstX */, 3800 0 /* dstY */, 0 /* dstZ */, m_width, height, m_depth); 3801 } 3802 else /* Copy from src to rb and from rb to dst */ 3803 { 3804 /* Src and rb shares differs only on target */ 3805 gl.copyImageSubData(m_src_tex_name, GL_TEXTURE_2D, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */, 3806 0 /* srcZ */, m_rb_name, test_case.m_target, 0 /* dstLevel */, 0 /* dstX */, 3807 0 /* dstY */, 0 /* dstZ */, m_width, m_height, m_depth); 3808 3809 gl.copyImageSubData(m_rb_name, test_case.m_target, 0 /* dstLevel */, 0 /* dstX */, 0 /* dstY */, 3810 0 /* dstZ */, m_dst_tex_name, GL_TEXTURE_2D, 0 /* dstLevel */, 0 /* dstX */, 3811 0 /* dstY */, 0 /* dstZ */, m_width, m_height, m_depth); 3812 } 3813 3814 /* Verify generated error */ 3815 error = gl.getError(); 3816 3817 if (GL_NO_ERROR == error) 3818 { 3819 /* Verify copy results */ 3820 result = verify(test_case, src_pixels); 3821 } 3822 3823 if ((GL_NO_ERROR != error) || (false == result)) 3824 { 3825 m_context.getTestContext().getLog() 3826 << tcu::TestLog::Message << "Failure. Target: " << glu::getTextureTargetStr(test_case.m_target) 3827 << ". Format: " << glu::getInternalFormatParameterStr(test_case.m_internal_format) 3828 << tcu::TestLog::EndMessage; 3829 3830 if (GL_NO_ERROR != error) 3831 { 3832 m_context.getTestContext().getLog() << tcu::TestLog::Message 3833 << "Failed due to error: " << glu::getErrorStr(error) 3834 << tcu::TestLog::EndMessage; 3835 3836 TCU_FAIL("Copy operation failed"); 3837 } 3838 3839 return false; 3840 } 3841 } 3842 3843 return true; 3844 } 3845 3846 /** Get pixel data for image 3847 * 3848 * @param name Name of image 3849 * @param test_case Test case descriptor 3850 * @param out_pixels Pixels 3851 **/ 3852 void SmokeTest::getPixels(GLuint name, const SmokeTest::testCase& test_case, GLubyte* out_pixels) const 3853 { 3854 const Functions& gl = m_context.getRenderContext().getFunctions(); 3855 GLenum tgt_bind = test_case.m_target; 3856 GLenum tgt_get = test_case.m_target; 3857 3858 if (GL_RENDERBUFFER == test_case.m_target) 3859 { 3860 tgt_bind = GL_TEXTURE_2D; 3861 tgt_get = GL_TEXTURE_2D; 3862 } 3863 else if (GL_TEXTURE_CUBE_MAP == test_case.m_target) 3864 { 3865 tgt_get = GL_TEXTURE_CUBE_MAP_POSITIVE_X; 3866 } 3867 3868 gl.bindTexture(tgt_bind, name); 3869 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3870 3871 gl.getTexImage(tgt_get, 0 /* level */, test_case.m_format, test_case.m_type, out_pixels); 3872 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 3873 3874 gl.bindTexture(tgt_bind, 0); 3875 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3876 } 3877 3878 /** Execute test 3879 * 3880 * @return CONTINUE as long there are more test case, STOP otherwise 3881 **/ 3882 tcu::TestNode::IterateResult SmokeTest::iterate() 3883 { 3884 GLubyte* dst_pixels = 0; 3885 const Functions& gl = m_context.getRenderContext().getFunctions(); 3886 tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP; 3887 bool result = false; 3888 GLubyte* src_pixels = 0; 3889 const testCase& test_case = m_test_cases[m_test_case_index]; 3890 3891 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 3892 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 3893 GLU_EXPECT_NO_ERROR(gl.getError(), "PixelStorei"); 3894 3895 try 3896 { 3897 /* Prepare pixels */ 3898 prepareDstPxls(test_case, dst_pixels); 3899 prepareSrcPxls(test_case, src_pixels); 3900 3901 /* Prepare textures */ 3902 if (GL_RENDERBUFFER == test_case.m_target) 3903 { 3904 testCase desc = test_case; 3905 GLuint ignored = 0; 3906 3907 desc.m_target = GL_TEXTURE_2D; 3908 3909 m_rb_name = prepareTexture(test_case, 0 /* pixels */, ignored /* buffer name */); 3910 m_dst_tex_name = prepareTexture(desc, dst_pixels, m_dst_buf_name); 3911 m_src_tex_name = prepareTexture(desc, src_pixels, m_src_buf_name); 3912 } 3913 else 3914 { 3915 m_dst_tex_name = prepareTexture(test_case, dst_pixels, m_dst_buf_name); 3916 m_src_tex_name = prepareTexture(test_case, src_pixels, m_src_buf_name); 3917 } 3918 3919 /* Copy images and verify results */ 3920 result = copyAndVerify(test_case, src_pixels); 3921 } 3922 catch (tcu::Exception& exc) 3923 { 3924 clean(); 3925 cleanPixels(dst_pixels); 3926 cleanPixels(src_pixels); 3927 throw exc; 3928 } 3929 3930 /* Free resources */ 3931 clean(); 3932 cleanPixels(dst_pixels); 3933 cleanPixels(src_pixels); 3934 3935 /* Set result */ 3936 if (true == result) 3937 { 3938 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3939 3940 /* Increase index */ 3941 m_test_case_index += 1; 3942 3943 /* Are there any test cases left */ 3944 if (m_test_cases.size() > m_test_case_index) 3945 { 3946 it_result = tcu::TestNode::CONTINUE; 3947 } 3948 } 3949 else 3950 { 3951 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failure. " << tcu::TestLog::EndMessage; 3952 3953 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3954 } 3955 3956 /* Done */ 3957 return it_result; 3958 } 3959 3960 /** Prepare data for destination image 3961 * 3962 * @param test_case Test case descriptor 3963 * @param out_pixels Pointer to image data 3964 **/ 3965 void SmokeTest::prepareDstPxls(const SmokeTest::testCase& test_case, GLubyte*& out_pixels) const 3966 { 3967 static const GLuint n_pixels_per_layer = m_width * m_height; 3968 3969 const GLenum internal_format = test_case.m_internal_format; 3970 const GLuint n_layers = (GL_TEXTURE_CUBE_MAP_ARRAY != test_case.m_target) ? m_depth : 6; 3971 const GLuint n_pixels = n_pixels_per_layer * n_layers; 3972 const GLuint pixel_size = Utils::getPixelSizeForFormat(internal_format); 3973 const GLuint req_memory = pixel_size * n_pixels; 3974 const GLenum type = test_case.m_type; 3975 3976 /* Prepare storage */ 3977 out_pixels = new GLubyte[req_memory]; 3978 3979 if (0 == out_pixels) 3980 { 3981 TCU_FAIL("Memory allocation failed"); 3982 } 3983 3984 memset(out_pixels, 0, req_memory); 3985 3986 /* Fill pixels */ 3987 for (GLuint j = 0; j < n_pixels; ++j) 3988 { 3989 GLubyte* pixel_data = out_pixels + j * pixel_size; 3990 3991 Utils::packPixel(internal_format, type, 1.0, 1.0, 1.0, 1.0, pixel_data); 3992 } 3993 } 3994 3995 /** Prepare data for source image 3996 * 3997 * @param test_case Test case descriptor 3998 * @param out_pixels Pointer to image data 3999 **/ 4000 void SmokeTest::prepareSrcPxls(const SmokeTest::testCase& test_case, GLubyte*& out_pixels) const 4001 { 4002 static const GLuint n_pixels_per_layer = m_width * m_height; 4003 4004 const GLenum internal_format = test_case.m_internal_format; 4005 const GLuint n_layers = (GL_TEXTURE_CUBE_MAP_ARRAY != test_case.m_target) ? m_depth : 6; 4006 const GLuint n_pixels = n_pixels_per_layer * n_layers; 4007 const GLuint pixel_size = Utils::getPixelSizeForFormat(internal_format); 4008 const GLuint layer_size = pixel_size * n_pixels_per_layer; 4009 const GLuint line_size = pixel_size * m_width; 4010 const GLuint req_memory = pixel_size * n_pixels; 4011 const GLenum type = test_case.m_type; 4012 4013 /* Prepare storage */ 4014 out_pixels = new GLubyte[req_memory]; 4015 4016 if (0 == out_pixels) 4017 { 4018 TCU_FAIL("Memory allocation failed"); 4019 } 4020 4021 memset(out_pixels, 0, req_memory); 4022 4023 /* Fill pixels */ 4024 for (GLuint layer = 0; layer < n_layers; ++layer) 4025 { 4026 const GLuint layer_offset = layer * layer_size; 4027 4028 GLubyte* layer_data = out_pixels + layer_offset; 4029 4030 for (GLuint y = 0; y < m_height; ++y) 4031 { 4032 const GLuint line_offset = line_size * y; 4033 4034 GLubyte* line_data = layer_data + line_offset; 4035 4036 for (GLuint x = 0; x < m_width; ++x) 4037 { 4038 const GLuint pixel_offset = x * pixel_size; 4039 4040 GLubyte* pixel_data = line_data + pixel_offset; 4041 4042 /* 255 is max ubyte. 1/15.9375 = 16/255 */ 4043 const GLdouble red = ((GLdouble)x) / 255.0 + (((GLdouble)y) / 15.9375); 4044 const GLdouble green = ((GLdouble)layer) / 255.0 + (1.0 / 15.9375); 4045 const GLdouble blue = 0.125; 4046 const GLdouble alpha = 1.0; /* This value has special meaning for some internal_formats */ 4047 4048 Utils::packPixel(internal_format, type, red, green, blue, alpha, pixel_data); 4049 } 4050 } 4051 } 4052 } 4053 4054 /** Prepare texture 4055 * 4056 * @param desc Descriptor 4057 * @param pixels Image data 4058 * @param out_buf_id Id of buffer used by texture buffer 4059 * 4060 * @return Name of iamge 4061 **/ 4062 GLuint SmokeTest::prepareTexture(const testCase& test_case, const GLubyte* pixels, GLuint& out_buf_id) 4063 { 4064 const GLuint n_layers = (GL_TEXTURE_CUBE_MAP_ARRAY != test_case.m_target) ? m_depth : 6; 4065 GLuint name = Utils::generateTexture(m_context, test_case.m_target); 4066 4067 Utils::prepareTexture(m_context, name, test_case.m_target, test_case.m_internal_format, test_case.m_format, 4068 test_case.m_type, 0 /* level */, m_width, m_height, n_layers, pixels, out_buf_id); 4069 4070 Utils::makeTextureComplete(m_context, test_case.m_target, name, 0 /* base */, 0 /* max */); 4071 4072 return name; 4073 } 4074 4075 /** Verify copy operation 4076 * 4077 * @param test_case Test case 4078 * @param src_pixels Original data of source image 4079 * 4080 * @return true if everything is as expected, false otherwise 4081 **/ 4082 bool SmokeTest::verify(const testCase& test_case, const GLubyte* src_pixels) 4083 { 4084 std::vector<GLubyte> dst_data; 4085 const GLuint n_layers = (GL_TEXTURE_CUBE_MAP_ARRAY != test_case.m_target) ? m_depth : 6; 4086 const GLuint pixel_size = Utils::getPixelSizeForFormat(test_case.m_internal_format); 4087 const GLuint line_size = pixel_size * m_width; 4088 const GLuint req_memory = line_size * m_height * n_layers; 4089 std::vector<GLubyte> src_data; 4090 4091 /* Prepare storage */ 4092 dst_data.resize(req_memory); 4093 src_data.resize(req_memory); 4094 4095 /* Check if source image was not modified */ 4096 { 4097 getPixels(m_src_tex_name, test_case, &src_data[0]); 4098 4099 if (false == compareImages(test_case, src_pixels, &src_data[0])) 4100 { 4101 m_context.getTestContext().getLog() 4102 << tcu::TestLog::Message << "CopyImageSubData modified contents of source image. Original data: left." 4103 << tcu::TestLog::EndMessage; 4104 return false; 4105 } 4106 } 4107 4108 /* Check contents of destination image */ 4109 { 4110 getPixels(m_dst_tex_name, test_case, &dst_data[0]); 4111 4112 if (false == compareImages(test_case, src_pixels, &dst_data[0])) 4113 { 4114 m_context.getTestContext().getLog() 4115 << tcu::TestLog::Message 4116 << "CopyImageSubData stored invalid contents in destination image. Source data: left." 4117 << tcu::TestLog::EndMessage; 4118 4119 return false; 4120 } 4121 } 4122 4123 return true; 4124 } 4125 4126 /* InvalidTargetTest */ 4127 /** Constructor 4128 * 4129 * @param context Text context 4130 **/ 4131 InvalidTargetTest::InvalidTargetTest(deqp::Context& context) 4132 : TestCase(context, "invalid_target", 4133 "Test verifies if INVALID_ENUM is generated when invalid target is provided to CopySubImageData") 4134 , m_dst_buf_name(0) 4135 , m_dst_tex_name(0) 4136 , m_src_buf_name(0) 4137 , m_src_tex_name(0) 4138 , m_test_case_index(0) 4139 { 4140 4141 /* Valid source, valid dst */ 4142 for (GLuint src = 0; src < s_n_valid_targets; ++src) 4143 { 4144 for (GLuint dst = 0; dst < s_n_valid_targets; ++dst) 4145 { 4146 const GLenum src_target = s_valid_targets[src]; 4147 const GLenum dst_target = s_valid_targets[dst]; 4148 testCase test_case = { src_target, dst_target, GL_NO_ERROR }; 4149 4150 if (Utils::isTargetMultisampled(dst_target) != Utils::isTargetMultisampled(src_target)) 4151 { 4152 test_case.m_expected_result = GL_INVALID_OPERATION; 4153 } 4154 4155 m_test_cases.push_back(test_case); 4156 } 4157 } 4158 4159 /* Invalid source, invalid dst */ 4160 for (GLuint src = 0; src < s_n_invalid_targets; ++src) 4161 { 4162 for (GLuint dst = 0; dst < s_n_invalid_targets; ++dst) 4163 { 4164 const GLenum src_target = s_invalid_targets[src]; 4165 const GLenum dst_target = s_invalid_targets[dst]; 4166 const testCase test_case = { src_target, dst_target, GL_INVALID_ENUM }; 4167 4168 m_test_cases.push_back(test_case); 4169 } 4170 } 4171 4172 /* Invalid source, valid dst */ 4173 for (GLuint src = 0; src < s_n_invalid_targets; ++src) 4174 { 4175 for (GLuint dst = 0; dst < s_n_valid_targets; ++dst) 4176 { 4177 const GLenum src_target = s_invalid_targets[src]; 4178 const GLenum dst_target = s_valid_targets[dst]; 4179 const testCase test_case = { src_target, dst_target, GL_INVALID_ENUM }; 4180 4181 m_test_cases.push_back(test_case); 4182 } 4183 } 4184 4185 /* Valid source, invalid dst */ 4186 for (GLuint src = 0; src < s_n_valid_targets; ++src) 4187 { 4188 for (GLuint dst = 0; dst < s_n_invalid_targets; ++dst) 4189 { 4190 const GLenum src_target = s_valid_targets[src]; 4191 const GLenum dst_target = s_invalid_targets[dst]; 4192 const testCase test_case = { src_target, dst_target, GL_INVALID_ENUM }; 4193 4194 m_test_cases.push_back(test_case); 4195 } 4196 } 4197 } 4198 4199 /** Execute test 4200 * 4201 * @return CONTINUE as long there are more test case, STOP otherwise 4202 **/ 4203 tcu::TestNode::IterateResult InvalidTargetTest::iterate() 4204 { 4205 GLenum error = GL_NO_ERROR; 4206 const Functions& gl = m_context.getRenderContext().getFunctions(); 4207 tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP; 4208 bool result = false; 4209 const testCase& test_case = m_test_cases[m_test_case_index]; 4210 4211 try 4212 { 4213 /* Prepare textures */ 4214 m_dst_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_dst_target, GL_RGBA8, GL_RGBA, 4215 GL_UNSIGNED_BYTE, m_dst_buf_name); 4216 m_src_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_src_target, GL_RGBA8, GL_RGBA, 4217 GL_UNSIGNED_BYTE, m_src_buf_name); 4218 4219 /* Make textures complete */ 4220 Utils::makeTextureComplete(m_context, test_case.m_dst_target, m_dst_tex_name, 0 /* base */, 0 /* max */); 4221 Utils::makeTextureComplete(m_context, test_case.m_src_target, m_src_tex_name, 0 /* base */, 0 /* max */); 4222 } 4223 catch (tcu::Exception& exc) 4224 { 4225 clean(); 4226 throw exc; 4227 } 4228 4229 /* Execute CopyImageSubData */ 4230 gl.copyImageSubData(m_src_tex_name, test_case.m_src_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */, 4231 0 /* srcZ */, m_dst_tex_name, test_case.m_dst_target, 0 /* dstLevel */, 0 /* dstX */, 4232 0 /* dstY */, 0 /* dstZ */, 1 /* srcWidth */, 1 /* srcHeight */, 1 /* srcDepth */); 4233 4234 /* Verify generated error */ 4235 error = gl.getError(); 4236 result = (test_case.m_expected_result == error); 4237 4238 /* Free resources */ 4239 clean(); 4240 4241 /* Set result */ 4242 if (true == result) 4243 { 4244 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4245 4246 /* Increase index */ 4247 m_test_case_index += 1; 4248 4249 /* Are there any test cases left */ 4250 if (m_test_cases.size() > m_test_case_index) 4251 { 4252 it_result = tcu::TestNode::CONTINUE; 4253 } 4254 } 4255 else 4256 { 4257 m_context.getTestContext().getLog() 4258 << tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result) 4259 << " got: " << glu::getErrorStr(error) 4260 << ". Source target: " << glu::getTextureTargetStr(test_case.m_src_target) 4261 << ", destination target: " << glu::getTextureTargetStr(test_case.m_dst_target) << tcu::TestLog::EndMessage; 4262 4263 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4264 } 4265 4266 /* Done */ 4267 return it_result; 4268 } 4269 4270 /** Cleans resources 4271 * 4272 **/ 4273 void InvalidTargetTest::clean() 4274 { 4275 const Functions& gl = m_context.getRenderContext().getFunctions(); 4276 const testCase& test_case = m_test_cases[m_test_case_index]; 4277 4278 /* Clean textures and buffers. Errors ignored */ 4279 Utils::deleteTexture(m_context, test_case.m_dst_target, m_dst_tex_name); 4280 Utils::deleteTexture(m_context, test_case.m_src_target, m_src_tex_name); 4281 4282 m_dst_tex_name = 0; 4283 m_src_tex_name = 0; 4284 4285 if (0 != m_dst_buf_name) 4286 { 4287 gl.deleteBuffers(1, &m_dst_buf_name); 4288 m_dst_buf_name = 0; 4289 } 4290 4291 if (0 != m_src_buf_name) 4292 { 4293 gl.deleteBuffers(1, &m_src_buf_name); 4294 m_src_buf_name = 0; 4295 } 4296 } 4297 4298 /* TargetMissMatchTest */ 4299 /** Constructor 4300 * 4301 * @param context Text context 4302 **/ 4303 TargetMissMatchTest::TargetMissMatchTest(deqp::Context& context) 4304 : TestCase( 4305 context, "target_miss_match", 4306 "Test verifies if INVALID_ENUM is generated when target provided to CopySubImageData does not match texture") 4307 , m_dst_buf_name(0) 4308 , m_dst_tex_name(0) 4309 , m_src_buf_name(0) 4310 , m_src_tex_name(0) 4311 , m_test_case_index(0) 4312 { 4313 /* Wrong dst target */ 4314 for (GLuint target = 0; target < s_n_valid_targets; ++target) 4315 { 4316 for (GLuint dst = 0; dst < s_n_valid_targets; ++dst) 4317 { 4318 const GLenum dst_target = s_valid_targets[dst]; 4319 const GLenum src_target = s_valid_targets[target]; 4320 const GLenum tex_target = s_valid_targets[target]; 4321 testCase test_case = { tex_target, src_target, dst_target, GL_INVALID_ENUM }; 4322 4323 /* Skip renderbuffers */ 4324 if ((GL_RENDERBUFFER == tex_target) || (GL_RENDERBUFFER == dst_target) || (GL_RENDERBUFFER == src_target)) 4325 { 4326 continue; 4327 } 4328 4329 /* Valid case */ 4330 if (dst_target == tex_target) 4331 { 4332 test_case.m_expected_result = GL_NO_ERROR; 4333 } 4334 4335 /* Skip cases with multisampling conflict */ 4336 if (Utils::isTargetMultisampled(dst_target) != Utils::isTargetMultisampled(src_target)) 4337 { 4338 continue; 4339 } 4340 4341 m_test_cases.push_back(test_case); 4342 } 4343 } 4344 4345 /* Wrong src target */ 4346 for (GLuint target = 0; target < s_n_valid_targets; ++target) 4347 { 4348 for (GLuint src = 0; src < s_n_valid_targets; ++src) 4349 { 4350 const GLenum dst_target = s_valid_targets[target]; 4351 const GLenum src_target = s_valid_targets[src]; 4352 const GLenum tex_target = s_valid_targets[target]; 4353 testCase test_case = { tex_target, src_target, dst_target, GL_INVALID_ENUM }; 4354 4355 /* Skip renderbuffers */ 4356 if ((GL_RENDERBUFFER == tex_target) || (GL_RENDERBUFFER == dst_target) || (GL_RENDERBUFFER == src_target)) 4357 { 4358 continue; 4359 } 4360 4361 /* Valid case */ 4362 if (src_target == tex_target) 4363 { 4364 test_case.m_expected_result = GL_NO_ERROR; 4365 } 4366 4367 /* Skip cases with multisampling conflict */ 4368 if (Utils::isTargetMultisampled(dst_target) != Utils::isTargetMultisampled(src_target)) 4369 { 4370 continue; 4371 } 4372 4373 m_test_cases.push_back(test_case); 4374 } 4375 } 4376 } 4377 4378 /** Execute test 4379 * 4380 * @return CONTINUE as long there are more test case, STOP otherwise 4381 **/ 4382 tcu::TestNode::IterateResult TargetMissMatchTest::iterate() 4383 { 4384 GLenum error = GL_NO_ERROR; 4385 const Functions& gl = m_context.getRenderContext().getFunctions(); 4386 tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP; 4387 bool result = false; 4388 const testCase& test_case = m_test_cases[m_test_case_index]; 4389 4390 try 4391 { 4392 /* Prepare textures */ 4393 m_dst_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA, 4394 GL_UNSIGNED_BYTE, m_dst_buf_name); 4395 m_src_tex_name = Utils::prepareTex16x16x6(