• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 gl4cCopyImageTests.hpp
23  * \brief CopyImageSubData functional tests.
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, glw::GLenum dst_format, glw::GLenum dst_target, glw::GLenum src_format,
96                    glw::GLenum src_target);
~FunctionalTest()97     virtual ~FunctionalTest()
98     {
99     }
100 
101     /* Implementation of tcu::TestNode methods */
102     virtual IterateResult iterate(void);
103 
104 private:
105     /* Private types */
106     struct targetDesc
107     {
108         glw::GLenum m_target;
109         glw::GLuint m_width;
110         glw::GLuint m_height;
111         glw::GLuint m_level;
112         glw::GLenum m_internal_format;
113         glw::GLenum m_format;
114         glw::GLenum m_type;
115     };
116 
117     struct testCase
118     {
119         targetDesc m_dst;
120         glw::GLuint m_dst_x;
121         glw::GLuint m_dst_y;
122         targetDesc m_src;
123         glw::GLuint m_src_x;
124         glw::GLuint m_src_y;
125         glw::GLuint m_width;
126         glw::GLuint m_height;
127     };
128 
129     /* Private methods */
130     void calculateDimmensions(glw::GLenum target, glw::GLuint level, glw::GLuint width, glw::GLuint height,
131                               glw::GLuint *out_widths, glw::GLuint *out_heights, glw::GLuint *out_depths) const;
132 
133     void clean();
134     void cleanPixels(glw::GLubyte **pixels) const;
135 
136     bool compareImages(const targetDesc &left_desc, const glw::GLubyte *left_data, glw::GLuint left_x,
137                        glw::GLuint left_y, glw::GLuint left_layer, glw::GLuint left_level, const targetDesc &right_desc,
138                        const glw::GLubyte *right_data, glw::GLuint right_x, glw::GLuint right_y,
139                        glw::GLuint right_layer, glw::GLuint right_level, glw::GLuint region_width,
140                        glw::GLuint region_height) const;
141 
142     bool copyAndVerify(const testCase &test_case, const glw::GLubyte **dst_pixels, const glw::GLubyte **src_pixels);
143 
144     void getCleanRegions(const testCase &test_case, glw::GLuint dst_level, glw::GLuint out_corners[4][4],
145                          glw::GLuint &out_n_corners) const;
146 
147     void getPixels(glw::GLuint name, const targetDesc &desc, glw::GLuint level, glw::GLubyte *out_pixels) const;
148 
149     void prepareDstPxls(const targetDesc &desc, glw::GLubyte **out_pixels) const;
150 
151     void prepareSrcPxls(const targetDesc &desc, glw::GLenum dst_internal_format, glw::GLubyte **out_pixels) const;
152 
153     void prepareTestCases(glw::GLenum dst_internal_format, glw::GLenum dst_target, glw::GLenum src_internal_format,
154                           glw::GLenum src_target);
155 
156     glw::GLuint prepareTexture(const targetDesc &desc, const glw::GLubyte **pixels, glw::GLuint &out_buf_id);
157 
158     bool verify(const testCase &test_case, glw::GLuint dst_layer, const glw::GLubyte **dst_pixels,
159                 glw::GLuint src_layer, const glw::GLubyte **src_pixels, glw::GLuint depth);
160 
161     /* Private fields */
162     glw::GLuint m_dst_buf_name;
163     glw::GLuint m_dst_tex_name;
164     glw::GLuint m_rb_name;
165     glw::GLuint m_src_buf_name;
166     glw::GLuint m_src_tex_name;
167     glw::GLuint m_test_case_index;
168     std::vector<testCase> m_test_cases;
169 };
170 
171 /** Implements functional test. Description follows:
172  *
173  * Smoke test:
174  * Tests if function CopyImageSubData accepts and works correctly with:
175  *     - all internal formats,
176  *     - all valid targets.
177  * Point of the test is to check each internal format and target separately.
178  *
179  * Steps:
180  *     - create source and destination image objects using same format and
181  *     target for both;
182  *     - fill 0 level mipmap of both image objects with different content, also
183  *     each pixel should be unique;
184  *     - make both image objects complete;
185  *     - execute CopyImageSubData on both image objects, to copy contents from
186  *     source image to a destination image;
187  *     - inspect content of both image objects;
188  *
189  * Test pass if:
190  *     - destination image contains data from source image,
191  *     - source image contents were not modified.
192  *
193  * Repeat steps for all internal formats, using TEXTURE_2D target.
194  *
195  * Repeat steps for all valid targets, using RGBA32UI internal format.
196  **/
197 class SmokeTest : public deqp::TestCase
198 {
199 public:
200     SmokeTest(deqp::Context &context);
~SmokeTest()201     virtual ~SmokeTest()
202     {
203     }
204 
205     /* Implementation of tcu::TestNode methods */
206     virtual IterateResult iterate(void);
207 
208 private:
209     /* Private types */
210     struct testCase
211     {
212         glw::GLenum m_target;
213         glw::GLenum m_internal_format;
214         glw::GLenum m_format;
215         glw::GLenum m_type;
216     };
217 
218     /* Private methods */
219     void clean();
220     void cleanPixels(glw::GLubyte *&pixels) const;
221 
222     bool compareImages(const testCase &test_case, const glw::GLubyte *left_data, const glw::GLubyte *right_data) const;
223 
224     bool copyAndVerify(const testCase &test_case, const glw::GLubyte *src_pixels);
225 
226     void getPixels(glw::GLuint name, const testCase &test_case, glw::GLubyte *out_pixels) const;
227 
228     void prepareDstPxls(const testCase &test_case, glw::GLubyte *&out_pixels) const;
229 
230     void prepareSrcPxls(const testCase &test_case, glw::GLubyte *&out_pixels) const;
231 
232     glw::GLuint prepareTexture(const testCase &test_case, const glw::GLubyte *pixels, glw::GLuint &out_buf_id);
233 
234     bool verify(const testCase &test_case, const glw::GLubyte *src_pixels);
235 
236     /* Private fields */
237     glw::GLuint m_dst_buf_name;
238     glw::GLuint m_dst_tex_name;
239     glw::GLuint m_rb_name;
240     glw::GLuint m_src_buf_name;
241     glw::GLuint m_src_tex_name;
242     glw::GLuint m_test_case_index;
243     std::vector<testCase> m_test_cases;
244 
245     /* Constants */
246     static const glw::GLuint m_width;
247     static const glw::GLuint m_height;
248     static const glw::GLuint m_depth;
249 };
250 
251 /** Implements negative test A. Description follows:
252  *
253  * [A]
254  * * Verify that GL_INVALID_ENUM error is generated if either <srcTarget> or
255  *   <dstTarget> is set to any of the proxy texture targets, GL_TEXTURE_BUFFER
256  *   or one of the cube-map face selectors.
257  **/
258 class InvalidTargetTest : public deqp::TestCase
259 {
260 public:
261     InvalidTargetTest(deqp::Context &context);
~InvalidTargetTest()262     virtual ~InvalidTargetTest()
263     {
264     }
265 
266     /* Implementation of tcu::TestNode methods */
267     virtual IterateResult iterate(void);
268 
269 private:
270     /* Private types */
271     struct testCase
272     {
273         glw::GLenum m_src_target;
274         glw::GLenum m_dst_target;
275         glw::GLenum m_expected_result;
276     };
277 
278     /* Private methods */
279     void clean();
280 
281     /* Private fields */
282     glw::GLuint m_dst_buf_name;
283     glw::GLuint m_dst_tex_name;
284     glw::GLuint m_src_buf_name;
285     glw::GLuint m_src_tex_name;
286     glw::GLuint m_test_case_index;
287     std::vector<testCase> m_test_cases;
288 };
289 
290 /** Implements negative test B. Description follows:
291  *
292  * [B]
293  * * Verify that usage of a non-matching target for either the source or
294  *   destination objects results in a GL_INVALID_ENUM error.
295  **/
296 class TargetMismatchTest : public deqp::TestCase
297 {
298 public:
299     TargetMismatchTest(deqp::Context &context);
~TargetMismatchTest()300     virtual ~TargetMismatchTest()
301     {
302     }
303 
304     /* Implementation of tcu::TestNode methods */
305     virtual IterateResult iterate(void);
306 
307 private:
308     /* Private types */
309     struct testCase
310     {
311         glw::GLenum m_tex_target;
312         glw::GLenum m_src_target;
313         glw::GLenum m_dst_target;
314         glw::GLenum m_expected_result;
315     };
316 
317     /* Private methods */
318     void clean();
319 
320     /* Private fields */
321     glw::GLuint m_dst_buf_name;
322     glw::GLuint m_dst_tex_name;
323     glw::GLuint m_src_buf_name;
324     glw::GLuint m_src_tex_name;
325     glw::GLuint m_test_case_index;
326     std::vector<testCase> m_test_cases;
327 };
328 
329 /** Implements negative test C. Description follows:
330  *
331  * [C]
332  * * Verify that INVALID_OPERATION is generated when the texture provided
333  *   to CopyImageSubData is incomplete
334  **/
335 class IncompleteTexTest : public deqp::TestCase
336 {
337 public:
338     IncompleteTexTest(deqp::Context &context);
~IncompleteTexTest()339     virtual ~IncompleteTexTest()
340     {
341     }
342 
343     /* Implementation of tcu::TestNode methods */
344     virtual IterateResult iterate(void);
345 
346 private:
347     /* Private types */
348     struct testCase
349     {
350         glw::GLenum m_tex_target;
351         bool m_is_dst_complete;
352         bool m_is_src_complete;
353         glw::GLenum m_expected_result;
354     };
355 
356     /* Private methods */
357     void clean();
358 
359     /* Private fields */
360     glw::GLuint m_dst_buf_name;
361     glw::GLuint m_dst_tex_name;
362     glw::GLuint m_src_buf_name;
363     glw::GLuint m_src_tex_name;
364     glw::GLuint m_test_case_index;
365     std::vector<testCase> m_test_cases;
366 };
367 
368 /** Implements negative test D. Description follows:
369  *
370  * [D]
371  * * Verify that usage of source/destination objects, internal formats of which
372  *   are not compatible, results in GL_INVALID_OPERATION error.
373  **/
374 class IncompatibleFormatsTest : public deqp::TestCase
375 {
376 public:
377     IncompatibleFormatsTest(deqp::Context &context);
~IncompatibleFormatsTest()378     virtual ~IncompatibleFormatsTest()
379     {
380     }
381 
382     /* Implementation of tcu::TestNode methods */
383     virtual IterateResult iterate(void);
384 
385 private:
386     /* Private types */
387     struct testCase
388     {
389         glw::GLenum m_tex_target;
390         glw::GLenum m_dst_internal_format;
391         glw::GLenum m_dst_format;
392         glw::GLenum m_dst_type;
393         glw::GLenum m_src_internal_format;
394         glw::GLenum m_src_format;
395         glw::GLenum m_src_type;
396         glw::GLenum m_expected_result;
397     };
398 
399     /* Private methods */
400     void clean();
401 
402     /* Private fields */
403     glw::GLuint m_dst_buf_name;
404     glw::GLuint m_dst_tex_name;
405     glw::GLuint m_src_buf_name;
406     glw::GLuint m_src_tex_name;
407     glw::GLuint m_test_case_index;
408     std::vector<testCase> m_test_cases;
409 };
410 
411 /** Implements negative test E. Description follows:
412  *
413  * [E]
414  * * Verify that usage of source/destination objects, internal formats of which
415  *   do not match in terms of number of samples they can hold, results in
416  *   GL_INVALID_OPERATION error.
417  **/
418 class SamplesMismatchTest : public deqp::TestCase
419 {
420 public:
421     SamplesMismatchTest(deqp::Context &context);
~SamplesMismatchTest()422     virtual ~SamplesMismatchTest()
423     {
424     }
425 
426     /* Implementation of tcu::TestNode methods */
427     virtual IterateResult iterate(void);
428 
429 private:
430     /* Private types */
431     struct testCase
432     {
433         glw::GLenum m_src_target;
434         glw::GLsizei m_src_n_samples;
435         glw::GLenum m_dst_target;
436         glw::GLsizei m_dst_n_samples;
437         glw::GLenum m_expected_result;
438     };
439 
440     /* Private methods */
441     void clean();
442 
443     /* Private fields */
444     glw::GLuint m_dst_tex_name;
445     glw::GLuint m_src_tex_name;
446     glw::GLuint m_test_case_index;
447     std::vector<testCase> m_test_cases;
448 };
449 
450 /** Implements negative test F. Description follows:
451  *
452  * [F]
453  * * Verify that usage of a pair of objects, one of which is defined by
454  *   compressed data and the other one has a non-compressed representation,
455  *   results in a GL_INVALID_OPERATION error, if the block size of compressed
456  *   image is not equal to the texel size of the compressed image.
457  **/
458 class IncompatibleFormatsCompressionTest : public deqp::TestCase
459 {
460 public:
461     IncompatibleFormatsCompressionTest(deqp::Context &context);
~IncompatibleFormatsCompressionTest()462     virtual ~IncompatibleFormatsCompressionTest()
463     {
464     }
465 
466     /* Implementation of tcu::TestNode methods */
467     virtual IterateResult iterate(void);
468 
469 private:
470     /* Private types */
471     struct testCase
472     {
473         glw::GLenum m_tex_target;
474         glw::GLenum m_dst_internal_format;
475         glw::GLenum m_dst_format;
476         glw::GLenum m_dst_type;
477         glw::GLenum m_src_internal_format;
478         glw::GLenum m_src_format;
479         glw::GLenum m_src_type;
480         glw::GLenum m_expected_result;
481     };
482 
483     /* Private methods */
484     void clean();
485 
486     /* Private fields */
487     glw::GLuint m_dst_tex_name;
488     glw::GLuint m_src_tex_name;
489     glw::GLuint m_test_case_index;
490     std::vector<testCase> m_test_cases;
491 };
492 
493 /** Implements negative test G. Description follows:
494  *
495  * [G]
496  * * Verify that usage of an invalid <srcTarget> or <dstTarget> argument
497  *   generates GL_INVALID_VALUE error. For the purpose of the test, make sure
498  *   to iterate over the set of all objects that can be used as source or
499  *   destination objects.
500  **/
501 class InvalidObjectTest : public deqp::TestCase
502 {
503 public:
504     InvalidObjectTest(deqp::Context &context);
~InvalidObjectTest()505     virtual ~InvalidObjectTest()
506     {
507     }
508 
509     /* Implementation of tcu::TestNode methods */
510     virtual IterateResult iterate(void);
511 
512 private:
513     /* Private types */
514     struct testCase
515     {
516         glw::GLenum m_dst_target;
517         bool m_dst_valid;
518         glw::GLenum m_src_target;
519         bool m_src_valid;
520         glw::GLenum m_expected_result;
521     };
522 
523     /* Private methods */
524     void clean();
525 
526     /* Private fields */
527     glw::GLuint m_dst_name;
528     glw::GLuint m_src_name;
529     glw::GLuint m_test_case_index;
530     std::vector<testCase> m_test_cases;
531 };
532 
533 /** Implements negative test H. Description follows:
534  *
535  * [H]
536  * * Make sure that GL_INVALID_VALUE error is generated if <level> argument
537  *   refers to a non-existent mip-map level for either the source or the
538  *   destination object. In particular, make sure that using any value other
539  *   than 0 for render-buffers is considered an erroneous action.
540  **/
541 class NonExistentMipMapTest : public deqp::TestCase
542 {
543 public:
544     NonExistentMipMapTest(deqp::Context &context);
~NonExistentMipMapTest()545     virtual ~NonExistentMipMapTest()
546     {
547     }
548 
549     /* Implementation of tcu::TestNode methods */
550     virtual IterateResult iterate(void);
551 
552 private:
553     /* Private types */
554     struct testCase
555     {
556         glw::GLenum m_tex_target;
557         glw::GLuint m_src_level;
558         glw::GLuint m_dst_level;
559         glw::GLenum m_expected_result;
560     };
561 
562     /* Private methods */
563     void clean();
564 
565     /* Private fields */
566     glw::GLuint m_dst_tex_name;
567     glw::GLuint m_src_tex_name;
568     glw::GLuint m_test_case_index;
569     std::vector<testCase> m_test_cases;
570 };
571 
572 /** Implements negative test I. Description follows:
573  *
574  * [I]
575  * * Make sure that using source/destination subregions that exceed the
576  *   boundaries of the relevant object generates a GL_INVALID_VALUE error.
577  **/
578 class ExceedingBoundariesTest : public deqp::TestCase
579 {
580 public:
581     ExceedingBoundariesTest(deqp::Context &context);
~ExceedingBoundariesTest()582     virtual ~ExceedingBoundariesTest()
583     {
584     }
585 
586     /* Implementation of tcu::TestNode methods */
587     virtual IterateResult iterate(void);
588 
589 private:
590     /* Private types */
591     struct testCase
592     {
593         glw::GLenum m_tex_target;
594         glw::GLuint m_depth;
595         glw::GLuint m_height;
596         glw::GLuint m_src_x;
597         glw::GLuint m_src_y;
598         glw::GLuint m_src_z;
599         glw::GLuint m_dst_x;
600         glw::GLuint m_dst_y;
601         glw::GLuint m_dst_z;
602         glw::GLenum m_expected_result;
603     };
604 
605     /* Private methods */
606     void clean();
607 
608     /* Private fields */
609     glw::GLuint m_dst_tex_name;
610     glw::GLuint m_src_tex_name;
611     glw::GLuint m_test_case_index;
612     std::vector<testCase> m_test_cases;
613 
614     /* Private constants */
615     static const glw::GLuint m_region_depth;
616     static const glw::GLuint m_region_height;
617     static const glw::GLuint m_region_width;
618 };
619 
620 /** Implements negative test J. Description follows:
621  *
622  * [J]
623  * * Assume the source and/or the destination object(s) use(s) a compressed
624  *   internal format. Make sure that copy operations requested to operate on
625  *   subregions that do not meet the alignment constraints of the internal
626  *   format in question, generate GL_INVALID_VALUE error.
627  **/
628 class InvalidAlignmentTest : public deqp::TestCase
629 {
630 public:
631     InvalidAlignmentTest(deqp::Context &context);
~InvalidAlignmentTest()632     virtual ~InvalidAlignmentTest()
633     {
634     }
635 
636     /* Implementation of tcu::TestNode methods */
637     virtual IterateResult iterate(void);
638 
639 private:
640     /* Private types */
641     struct testCase
642     {
643         glw::GLuint m_height;
644         glw::GLuint m_width;
645         glw::GLuint m_src_x;
646         glw::GLuint m_src_y;
647         glw::GLuint m_dst_x;
648         glw::GLuint m_dst_y;
649         glw::GLenum m_expected_result;
650     };
651 
652     /* Private methods */
653     void clean();
654 
655     /* Private fields */
656     glw::GLuint m_dst_tex_name;
657     glw::GLuint m_src_tex_name;
658     glw::GLuint m_test_case_index;
659     std::vector<testCase> m_test_cases;
660 };
661 
662 /** Implements functional test. Description follows:
663  *
664  * [B]
665  * 1. Create a single level integer texture, with BASE_LEVEL and MAX_LEVEL set to 0.
666  * 2. Leave the mipmap filters at the default of GL_NEAREST_MIPMAP_LINEAR and GL_LINEAR.
667  * 3. Do glCopyImageSubData to or from that texture.
668  * 4. Make sure it succeeds and does not raise GL_INVALID_OPERATION.
669  **/
670 class IntegerTexTest : public deqp::TestCase
671 {
672 public:
673     IntegerTexTest(deqp::Context &context);
~IntegerTexTest()674     virtual ~IntegerTexTest()
675     {
676     }
677 
678     /* Implementation of tcu::TestNode methods */
679     virtual IterateResult iterate(void);
680 
681 private:
682     /* Private types */
683     struct testCase
684     {
685         glw::GLint m_internal_format;
686         glw::GLuint m_type;
687     };
688 
689     /* Private methods */
690     unsigned int createTexture(int width, int height, glw::GLint internalFormat, glw::GLuint type, const void *data,
691                                int minFilter, int magFilter);
692     void clean();
693 
694     /* Private fields */
695     glw::GLuint m_dst_buf_name;
696     glw::GLuint m_dst_tex_name;
697     glw::GLuint m_src_buf_name;
698     glw::GLuint m_src_tex_name;
699     glw::GLuint m_test_case_index;
700 };
701 } // namespace CopyImage
702 
703 class CopyImageTests : public deqp::TestCaseGroup
704 {
705 public:
706     CopyImageTests(deqp::Context &context);
707     ~CopyImageTests(void);
708 
709     virtual void init(void);
710 
711 private:
712     CopyImageTests(const CopyImageTests &other);
713     CopyImageTests &operator=(const CopyImageTests &other);
714 
715     void addFunctionalTest();
716 };
717 } /* namespace gl4cts */
718 
719 #endif // _GL4CCOPYIMAGETESTS_HPP
720