1 #ifndef _GL4CCOPYIMAGETESTS_HPP 2 #define _GL4CCOPYIMAGETESTS_HPP 3 /*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 2015-2016 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ /*! 22 * \file 23 * \brief 24 */ /*-------------------------------------------------------------------*/ 25 26 #include "glcTestCase.hpp" 27 #include "glwDefs.hpp" 28 29 namespace gl4cts 30 { 31 namespace CopyImage 32 { 33 /** Implements functional test. Description follows: 34 * 35 * This test verifies that CopyImageSubData function works as expected. 36 * 37 * Steps: 38 * - create source and destination image objects; 39 * - fill both image objects with different content, also each pixel should 40 * be unique; 41 * - execute CopyImageSubData on both image objects, to copy region from 42 * source image to a region in destination image; 43 * - inspect content of both image objects; 44 * 45 * Test pass if: 46 * - no part of destination image, that is outside of destination region, 47 * was modified, 48 * - destination region contains data from source region, 49 * - source image contents were not modified. 50 * 51 * Use TexImage* routines to create textures. It is required that textures are 52 * complete, therefore TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL have to be 53 * updated with TexParameter manually. 54 * 55 * Use draw operation to update contents of Renderbuffers. 56 * 57 * Tested image dimensions should be NxM where N and M are <7:15>. 58 * 59 * Multi-layered targets should have twelve slices. 60 * 61 * Test with the following mipmap levels: 62 * - 0, 63 * - 1, 64 * - 2. 65 * 66 * Test with the following region locations: 67 * - all four corners, 68 * - all four edge centres, 69 * - image centre, 70 * - whole image. 71 * 72 * Tested region dimensions should be NxN where N is <1:7>. Depth should be 73 * selected so as to affect all image slices. In cases when one image has 74 * single layer and second is multi-layered, than copy operation and inspection 75 * must be repeated for each layer. 76 * 77 * This test should iterate over: 78 * - all valid internal format combinations, 79 * - all valid object target combinations, 80 * - all mipmap level combinations, 81 * - all image dimensions combinations, 82 * - all valid copied regions combinations, 83 * - all valid copied region dimensions combinations. 84 * 85 * Moreover this test should also execute CopyImageSubData to copy image to 86 * itself. In this case it expected that source image will be modified. 87 * 88 * 89 * Implementation notes 90 * There are some configuration preprocessor flags available in cpp file. 91 **/ 92 class FunctionalTest : public deqp::TestCase 93 { 94 public: 95 FunctionalTest(deqp::Context& context); 96 virtual ~FunctionalTest() 97 { 98 } 99 100 /* Implementation of tcu::TestNode methods */ 101 virtual IterateResult iterate(void); 102 103 private: 104 /* Private types */ 105 struct targetDesc 106 { 107 glw::GLenum m_target; 108 glw::GLuint m_width; 109 glw::GLuint m_height; 110 glw::GLuint m_level; 111 glw::GLenum m_internal_format; 112 glw::GLenum m_format; 113 glw::GLenum m_type; 114 }; 115 116 struct testCase 117 { 118 targetDesc m_dst; 119 glw::GLuint m_dst_x; 120 glw::GLuint m_dst_y; 121 targetDesc m_src; 122 glw::GLuint m_src_x; 123 glw::GLuint m_src_y; 124 glw::GLuint m_width; 125 glw::GLuint m_height; 126 }; 127 128 /* Private methods */ 129 void calculateDimmensions(glw::GLenum target, glw::GLuint level, glw::GLuint width, glw::GLuint height, 130 glw::GLuint* out_widths, glw::GLuint* out_heights, glw::GLuint* out_depths) const; 131 132 void clean(); 133 void cleanPixels(glw::GLubyte** pixels) const; 134 135 bool compareImages(const targetDesc& left_desc, const glw::GLubyte* left_data, glw::GLuint left_x, 136 glw::GLuint left_y, glw::GLuint left_layer, glw::GLuint left_level, const targetDesc& right_desc, 137 const glw::GLubyte* right_data, glw::GLuint right_x, glw::GLuint right_y, 138 glw::GLuint right_layer, glw::GLuint right_level, glw::GLuint region_width, 139 glw::GLuint region_height) const; 140 141 bool copyAndVerify(const testCase& test_case, const glw::GLubyte** dst_pixels, const glw::GLubyte** src_pixels); 142 143 void getCleanRegions(const testCase& test_case, glw::GLuint dst_level, glw::GLuint out_corners[4][4], 144 glw::GLuint& out_n_corners) const; 145 146 void getPixels(glw::GLuint name, const targetDesc& desc, glw::GLuint level, glw::GLubyte* out_pixels) const; 147 148 void prepareDstPxls(const targetDesc& desc, glw::GLubyte** out_pixels) const; 149 150 void prepareSrcPxls(const targetDesc& desc, glw::GLenum dst_internal_format, glw::GLubyte** out_pixels) const; 151 152 void prepareTestCases(glw::GLenum dst_internal_format, glw::GLenum dst_target, glw::GLenum src_internal_format, 153 glw::GLenum src_target); 154 155 glw::GLuint prepareTexture(const targetDesc& desc, const glw::GLubyte** pixels, glw::GLuint& out_buf_id); 156 157 bool verify(const testCase& test_case, glw::GLuint dst_layer, const glw::GLubyte** dst_pixels, 158 glw::GLuint src_layer, const glw::GLubyte** src_pixels, glw::GLuint depth); 159 160 /* Private fields */ 161 glw::GLuint m_dst_buf_name; 162 glw::GLuint m_dst_tex_name; 163 glw::GLuint m_rb_name; 164 glw::GLuint m_src_buf_name; 165 glw::GLuint m_src_tex_name; 166 glw::GLuint m_test_case_index; 167 std::vector<testCase> m_test_cases; 168 }; 169 170 /** Implements functional test. Description follows: 171 * 172 * Smoke test: 173 * Tests if function CopyImageSubData accepts and works correctly with: 174 * - all internal formats, 175 * - all valid targets. 176 * Point of the test is to check each internal format and target separately. 177 * 178 * Steps: 179 * - create source and destination image objects using same format and 180 * target for both; 181 * - fill 0 level mipmap of both image objects with different content, also 182 * each pixel should be unique; 183 * - make both image objects complete; 184 * - execute CopyImageSubData on both image objects, to copy contents from 185 * source image to a destination image; 186 * - inspect content of both image objects; 187 * 188 * Test pass if: 189 * - destination image contains data from source image, 190 * - source image contents were not modified. 191 * 192 * Repeat steps for all internal formats, using TEXTURE_2D target. 193 * 194 * Repeat steps for all valid targets, using RGBA32UI internal format. 195 **/ 196 class SmokeTest : public deqp::TestCase 197 { 198 public: 199 SmokeTest(deqp::Context& context); 200 virtual ~SmokeTest() 201 { 202 } 203 204 /* Implementation of tcu::TestNode methods */ 205 virtual IterateResult iterate(void); 206 207 private: 208 /* Private types */ 209 struct testCase 210 { 211 glw::GLenum m_target; 212 glw::GLenum m_internal_format; 213 glw::GLenum m_format; 214 glw::GLenum m_type; 215 }; 216 217 /* Private methods */ 218 void clean(); 219 void cleanPixels(glw::GLubyte*& pixels) const; 220 221 bool compareImages(const testCase& test_case, const glw::GLubyte* left_data, const glw::GLubyte* right_data) const; 222 223 bool copyAndVerify(const testCase& test_case, const glw::GLubyte* src_pixels); 224 225 void getPixels(glw::GLuint name, const testCase& test_case, glw::GLubyte* out_pixels) const; 226 227 void prepareDstPxls(const testCase& test_case, glw::GLubyte*& out_pixels) const; 228 229 void prepareSrcPxls(const testCase& test_case, glw::GLubyte*& out_pixels) const; 230 231 glw::GLuint prepareTexture(const testCase& test_case, const glw::GLubyte* pixels, glw::GLuint& out_buf_id); 232 233 bool verify(const testCase& test_case, const glw::GLubyte* src_pixels); 234 235 /* Private fields */ 236 glw::GLuint m_dst_buf_name; 237 glw::GLuint m_dst_tex_name; 238 glw::GLuint m_rb_name; 239 glw::GLuint m_src_buf_name; 240 glw::GLuint m_src_tex_name; 241 glw::GLuint m_test_case_index; 242 std::vector<testCase> m_test_cases; 243 244 /* Constants */ 245 static const glw::GLuint m_width; 246 static const glw::GLuint m_height; 247 static const glw::GLuint m_depth; 248 }; 249 250 /** Implements negative test A. Description follows: 251 * 252 * [A] 253 * * Verify that GL_INVALID_ENUM error is generated if either <srcTarget> or 254 * <dstTarget> is set to any of the proxy texture targets, GL_TEXTURE_BUFFER 255 * or one of the cube-map face selectors. 256 **/ 257 class InvalidTargetTest : public deqp::TestCase 258 { 259 public: 260 InvalidTargetTest(deqp::Context& context); 261 virtual ~InvalidTargetTest() 262 { 263 } 264 265 /* Implementation of tcu::TestNode methods */ 266 virtual IterateResult iterate(void); 267 268 private: 269 /* Private types */ 270 struct testCase 271 { 272 glw::GLenum m_src_target; 273 glw::GLenum m_dst_target; 274 glw::GLenum m_expected_result; 275 }; 276 277 /* Private methods */ 278 void clean(); 279 280 /* Private fields */ 281 glw::GLuint m_dst_buf_name; 282 glw::GLuint m_dst_tex_name; 283 glw::GLuint m_src_buf_name; 284 glw::GLuint m_src_tex_name; 285 glw::GLuint m_test_case_index; 286 std::vector<testCase> m_test_cases; 287 }; 288 289 /** Implements negative test B. Description follows: 290 * 291 * [B] 292 * * Verify that usage of a non-matching target for either the source or 293 * destination objects results in a GL_INVALID_ENUM error. 294 **/ 295 class TargetMissMatchTest : public deqp::TestCase 296 { 297 public: 298 TargetMissMatchTest(deqp::Context& context); 299 virtual ~TargetMissMatchTest() 300 { 301 } 302 303 /* Implementation of tcu::TestNode methods */ 304 virtual IterateResult iterate(void); 305 306 private: 307 /* Private types */ 308 struct testCase 309 { 310 glw::GLenum m_tex_target; 311 glw::GLenum m_src_target; 312 glw::GLenum m_dst_target; 313 glw::GLenum m_expected_result; 314 }; 315 316 /* Private methods */ 317 void clean(); 318 319 /* Private fields */ 320 glw::GLuint m_dst_buf_name; 321 glw::GLuint m_dst_tex_name; 322 glw::GLuint m_src_buf_name; 323 glw::GLuint m_src_tex_name; 324 glw::GLuint m_test_case_index; 325 std::vector<testCase> m_test_cases; 326 }; 327 328 /** Implements negative test C. Description follows: 329 * 330 * [B] 331 * * Verify that usage of a non-matching target for either the source or 332 * destination objects results in a GL_INVALID_ENUM error. 333 **/ 334 class IncompleteTexTest : public deqp::TestCase 335 { 336 public: 337 IncompleteTexTest(deqp::Context& context); 338 virtual ~IncompleteTexTest() 339 { 340 } 341 342 /* Implementation of tcu::TestNode methods */ 343 virtual IterateResult iterate(void); 344 345 private: 346 /* Private types */ 347 struct testCase 348 { 349 glw::GLenum m_tex_target; 350 bool m_is_dst_complete; 351 bool m_is_src_complete; 352 glw::GLenum m_expected_result; 353 }; 354 355 /* Private methods */ 356 void clean(); 357 358 /* Private fields */ 359 glw::GLuint m_dst_buf_name; 360 glw::GLuint m_dst_tex_name; 361 glw::GLuint m_src_buf_name; 362 glw::GLuint m_src_tex_name; 363 glw::GLuint m_test_case_index; 364 std::vector<testCase> m_test_cases; 365 }; 366 367 /** Implements negative test D. Description follows: 368 * 369 * [D] 370 * * Verify that usage of source/destination objects, internal formats of which 371 * are not compatible, results in GL_INVALID_OPERATION error. 372 **/ 373 class IncompatibleFormatsTest : public deqp::TestCase 374 { 375 public: 376 IncompatibleFormatsTest(deqp::Context& context); 377 virtual ~IncompatibleFormatsTest() 378 { 379 } 380 381 /* Implementation of tcu::TestNode methods */ 382 virtual IterateResult iterate(void); 383 384 private: 385 /* Private types */ 386 struct testCase 387 { 388 glw::GLenum m_tex_target; 389 glw::GLenum m_dst_internal_format; 390 glw::GLenum m_dst_format; 391 glw::GLenum m_dst_type; 392 glw::GLenum m_src_internal_format; 393 glw::GLenum m_src_format; 394 glw::GLenum m_src_type; 395 glw::GLenum m_expected_result; 396 }; 397 398 /* Private methods */ 399 void clean(); 400 401 /* Private fields */ 402 glw::GLuint m_dst_buf_name; 403 glw::GLuint m_dst_tex_name; 404 glw::GLuint m_src_buf_name; 405 glw::GLuint m_src_tex_name; 406 glw::GLuint m_test_case_index; 407 std::vector<testCase> m_test_cases; 408 }; 409 410 /** Implements negative test E. Description follows: 411 * 412 * [E] 413 * * Verify that usage of source/destination objects, internal formats of which 414 * do not match in terms of number of samples they can hold, results in 415 * GL_INVALID_OPERATION error. 416 **/ 417 class SamplesMissMatchTest : public deqp::TestCase 418 { 419 public: 420 SamplesMissMatchTest(deqp::Context& context); 421 virtual ~SamplesMissMatchTest() 422 { 423 } 424 425 /* Implementation of tcu::TestNode methods */ 426 virtual IterateResult iterate(void); 427 428 private: 429 /* Private types */ 430 struct testCase 431 { 432 glw::GLenum m_src_target; 433 glw::GLsizei m_src_n_samples; 434 glw::GLenum m_dst_target; 435 glw::GLsizei m_dst_n_samples; 436 glw::GLenum m_expected_result; 437 }; 438 439 /* Private methods */ 440 void clean(); 441 442 /* Private fields */ 443 glw::GLuint m_dst_tex_name; 444 glw::GLuint m_src_tex_name; 445 glw::GLuint m_test_case_index; 446 std::vector<testCase> m_test_cases; 447 }; 448 449 /** Implements negative test F. Description follows: 450 * 451 * [F] 452 * * Verify that usage of a pair of objects, one of which is defined by 453 * compressed data and the other one has a non-compressed representation, 454 * results in a GL_INVALID_OPERATION error, if the block size of compressed 455 * image is not equal to the texel size of the compressed image. 456 **/ 457 class IncompatibleFormatsCompressionTest : public deqp::TestCase 458 { 459 public: 460 IncompatibleFormatsCompressionTest(deqp::Context& context); 461 virtual ~IncompatibleFormatsCompressionTest() 462 { 463 } 464 465 /* Implementation of tcu::TestNode methods */ 466 virtual IterateResult iterate(void); 467 468 private: 469 /* Private types */ 470 struct testCase 471 { 472 glw::GLenum m_tex_target; 473 glw::GLenum m_dst_internal_format; 474 glw::GLenum m_dst_format; 475 glw::GLenum m_dst_type; 476 glw::GLenum m_src_internal_format; 477 glw::GLenum m_src_format; 478 glw::GLenum m_src_type; 479 glw::GLenum m_expected_result; 480 }; 481 482 /* Private methods */ 483 void clean(); 484 485 /* Private fields */ 486 glw::GLuint m_dst_tex_name; 487 glw::GLuint m_src_tex_name; 488 glw::GLuint m_test_case_index; 489 std::vector<testCase> m_test_cases; 490 }; 491 492 /** Implements negative test G. Description follows: 493 * 494 * [G] 495 * * Verify that usage of a mismatching <srcTarget> or <dstTarget> argument 496 * generates GL_INVALID_VALUE error. For the purpose of the test, make sure 497 * to iterate over the set of all objects that can be used as source or 498 * destination objects. 499 **/ 500 class MissMatchObjectTest : public deqp::TestCase 501 { 502 public: 503 MissMatchObjectTest(deqp::Context& context); 504 virtual ~MissMatchObjectTest() 505 { 506 } 507 508 /* Implementation of tcu::TestNode methods */ 509 virtual IterateResult iterate(void); 510 511 private: 512 /* Private types */ 513 struct testCase 514 { 515 glw::GLenum m_obj_target; 516 glw::GLenum m_dst_target; 517 glw::GLenum m_src_target; 518 glw::GLenum m_expected_result; 519 }; 520 521 /* Private methods */ 522 void clean(); 523 524 /* Private fields */ 525 glw::GLuint m_dst_name; 526 glw::GLuint m_src_name; 527 glw::GLuint m_test_case_index; 528 std::vector<testCase> m_test_cases; 529 }; 530 531 /** Implements negative test H. Description follows: 532 * 533 * [H] 534 * * Make sure that GL_INVALID_VALUE error is generated if <level> argument 535 * refers to a non-existent mip-map level for either the source or the 536 * destination object. In particular, make sure that using any value other 537 * than 0 for render-buffers is considered an erroneous action. 538 **/ 539 class NonExistentMipMapTest : public deqp::TestCase 540 { 541 public: 542 NonExistentMipMapTest(deqp::Context& context); 543 virtual ~NonExistentMipMapTest() 544 { 545 } 546 547 /* Implementation of tcu::TestNode methods */ 548 virtual IterateResult iterate(void); 549 550 private: 551 /* Private types */ 552 struct testCase 553 { 554 glw::GLenum m_tex_target; 555 glw::GLuint m_src_level; 556 glw::GLuint m_dst_level; 557 glw::GLenum m_expected_result; 558 }; 559 560 /* Private methods */ 561 void clean(); 562 563 /* Private fields */ 564 glw::GLuint m_dst_tex_name; 565 glw::GLuint m_src_tex_name; 566 glw::GLuint m_test_case_index; 567 std::vector<testCase> m_test_cases; 568 }; 569 570 /** Implements negative test I. Description follows: 571 * 572 * [I] 573 * * Make sure that using source/destination subregions that exceed the 574 * boundaries of the relevant object generates a GL_INVALID_VALUE error. 575 **/ 576 class ExceedingBoundariesTest : public deqp::TestCase 577 { 578 public: 579 ExceedingBoundariesTest(deqp::Context& context); 580 virtual ~ExceedingBoundariesTest() 581 { 582 } 583 584 /* Implementation of tcu::TestNode methods */ 585 virtual IterateResult iterate(void); 586 587 private: 588 /* Private types */ 589 struct testCase 590 { 591 glw::GLenum m_tex_target; 592 glw::GLuint m_depth; 593 glw::GLuint m_height; 594 glw::GLuint m_src_x; 595 glw::GLuint m_src_y; 596 glw::GLuint m_src_z; 597 glw::GLuint m_dst_x; 598 glw::GLuint m_dst_y; 599 glw::GLuint m_dst_z; 600 glw::GLenum m_expected_result; 601 }; 602 603 /* Private methods */ 604 void clean(); 605 606 /* Private fields */ 607 glw::GLuint m_dst_tex_name; 608 glw::GLuint m_src_tex_name; 609 glw::GLuint m_test_case_index; 610 std::vector<testCase> m_test_cases; 611 612 /* Private constants */ 613 static const glw::GLuint m_region_depth; 614 static const glw::GLuint m_region_height; 615 static const glw::GLuint m_region_width; 616 }; 617 618 /** Implements negative test J. Description follows: 619 * 620 * [J] 621 * * Assume the source and/or the destination object(s) use(s) a compressed 622 * internal format. Make sure that copy operations requested to operate on 623 * subregions that do not meet the alignment constraints of the internal 624 * format in question, generate GL_INVALID_VALUE error. 625 **/ 626 class InvalidAlignmentTest : public deqp::TestCase 627 { 628 public: 629 InvalidAlignmentTest(deqp::Context& context); 630 virtual ~InvalidAlignmentTest() 631 { 632 } 633 634 /* Implementation of tcu::TestNode methods */ 635 virtual IterateResult iterate(void); 636 637 private: 638 /* Private types */ 639 struct testCase 640 { 641 glw::GLuint m_height; 642 glw::GLuint m_width; 643 glw::GLuint m_src_x; 644 glw::GLuint m_src_y; 645 glw::GLuint m_dst_x; 646 glw::GLuint m_dst_y; 647 glw::GLenum m_expected_result; 648 }; 649 650 /* Private methods */ 651 void clean(); 652 653 /* Private fields */ 654 glw::GLuint m_dst_tex_name; 655 glw::GLuint m_src_tex_name; 656 glw::GLuint m_test_case_index; 657 std::vector<testCase> m_test_cases; 658 }; 659 } 660 661 class CopyImageTests : public deqp::TestCaseGroup 662 { 663 public: 664 CopyImageTests(deqp::Context& context); 665 ~CopyImageTests(void); 666 667 virtual void init(void); 668 669 private: 670 CopyImageTests(const CopyImageTests& other); 671 CopyImageTests& operator=(const CopyImageTests& other); 672 }; 673 } /* namespace gl4cts */ 674 675 #endif // _GL4CCOPYIMAGETESTS_HPP 676