xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cCopyImageTests.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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);
~FunctionalTest()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);
~SmokeTest()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);
~InvalidTargetTest()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 TargetMismatchTest : public deqp::TestCase
296 {
297 public:
298     TargetMismatchTest(deqp::Context &context);
~TargetMismatchTest()299     virtual ~TargetMismatchTest()
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  * [C]
331  * * Verify that INVALID_OPERATION is generated when the texture provided
332  *   to CopyImageSubData is incomplete
333  **/
334 class IncompleteTexTest : public deqp::TestCase
335 {
336 public:
337     IncompleteTexTest(deqp::Context &context);
~IncompleteTexTest()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);
~IncompatibleFormatsTest()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 SamplesMismatchTest : public deqp::TestCase
418 {
419 public:
420     SamplesMismatchTest(deqp::Context &context);
~SamplesMismatchTest()421     virtual ~SamplesMismatchTest()
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);
~IncompatibleFormatsCompressionTest()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 an invalid <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 InvalidObjectTest : public deqp::TestCase
501 {
502 public:
503     InvalidObjectTest(deqp::Context &context);
~InvalidObjectTest()504     virtual ~InvalidObjectTest()
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_dst_target;
516         bool m_dst_valid;
517         glw::GLenum m_src_target;
518         bool m_src_valid;
519         glw::GLenum m_expected_result;
520     };
521 
522     /* Private methods */
523     void clean();
524 
525     /* Private fields */
526     glw::GLuint m_dst_name;
527     glw::GLuint m_src_name;
528     glw::GLuint m_test_case_index;
529     std::vector<testCase> m_test_cases;
530 };
531 
532 /** Implements negative test H. Description follows:
533  *
534  * [H]
535  * * Make sure that GL_INVALID_VALUE error is generated if <level> argument
536  *   refers to a non-existent mip-map level for either the source or the
537  *   destination object. In particular, make sure that using any value other
538  *   than 0 for render-buffers is considered an erroneous action.
539  **/
540 class NonExistentMipMapTest : public deqp::TestCase
541 {
542 public:
543     NonExistentMipMapTest(deqp::Context &context);
~NonExistentMipMapTest()544     virtual ~NonExistentMipMapTest()
545     {
546     }
547 
548     /* Implementation of tcu::TestNode methods */
549     virtual IterateResult iterate(void);
550 
551 private:
552     /* Private types */
553     struct testCase
554     {
555         glw::GLenum m_tex_target;
556         glw::GLuint m_src_level;
557         glw::GLuint m_dst_level;
558         glw::GLenum m_expected_result;
559     };
560 
561     /* Private methods */
562     void clean();
563 
564     /* Private fields */
565     glw::GLuint m_dst_tex_name;
566     glw::GLuint m_src_tex_name;
567     glw::GLuint m_test_case_index;
568     std::vector<testCase> m_test_cases;
569 };
570 
571 /** Implements negative test I. Description follows:
572  *
573  * [I]
574  * * Make sure that using source/destination subregions that exceed the
575  *   boundaries of the relevant object generates a GL_INVALID_VALUE error.
576  **/
577 class ExceedingBoundariesTest : public deqp::TestCase
578 {
579 public:
580     ExceedingBoundariesTest(deqp::Context &context);
~ExceedingBoundariesTest()581     virtual ~ExceedingBoundariesTest()
582     {
583     }
584 
585     /* Implementation of tcu::TestNode methods */
586     virtual IterateResult iterate(void);
587 
588 private:
589     /* Private types */
590     struct testCase
591     {
592         glw::GLenum m_tex_target;
593         glw::GLuint m_depth;
594         glw::GLuint m_height;
595         glw::GLuint m_src_x;
596         glw::GLuint m_src_y;
597         glw::GLuint m_src_z;
598         glw::GLuint m_dst_x;
599         glw::GLuint m_dst_y;
600         glw::GLuint m_dst_z;
601         glw::GLenum m_expected_result;
602     };
603 
604     /* Private methods */
605     void clean();
606 
607     /* Private fields */
608     glw::GLuint m_dst_tex_name;
609     glw::GLuint m_src_tex_name;
610     glw::GLuint m_test_case_index;
611     std::vector<testCase> m_test_cases;
612 
613     /* Private constants */
614     static const glw::GLuint m_region_depth;
615     static const glw::GLuint m_region_height;
616     static const glw::GLuint m_region_width;
617 };
618 
619 /** Implements negative test J. Description follows:
620  *
621  * [J]
622  * * Assume the source and/or the destination object(s) use(s) a compressed
623  *   internal format. Make sure that copy operations requested to operate on
624  *   subregions that do not meet the alignment constraints of the internal
625  *   format in question, generate GL_INVALID_VALUE error.
626  **/
627 class InvalidAlignmentTest : public deqp::TestCase
628 {
629 public:
630     InvalidAlignmentTest(deqp::Context &context);
~InvalidAlignmentTest()631     virtual ~InvalidAlignmentTest()
632     {
633     }
634 
635     /* Implementation of tcu::TestNode methods */
636     virtual IterateResult iterate(void);
637 
638 private:
639     /* Private types */
640     struct testCase
641     {
642         glw::GLuint m_height;
643         glw::GLuint m_width;
644         glw::GLuint m_src_x;
645         glw::GLuint m_src_y;
646         glw::GLuint m_dst_x;
647         glw::GLuint m_dst_y;
648         glw::GLenum m_expected_result;
649     };
650 
651     /* Private methods */
652     void clean();
653 
654     /* Private fields */
655     glw::GLuint m_dst_tex_name;
656     glw::GLuint m_src_tex_name;
657     glw::GLuint m_test_case_index;
658     std::vector<testCase> m_test_cases;
659 };
660 
661 /** Implements functional test. Description follows:
662  *
663  * [B]
664  * 1. Create a single level integer texture, with BASE_LEVEL and MAX_LEVEL set to 0.
665  * 2. Leave the mipmap filters at the default of GL_NEAREST_MIPMAP_LINEAR and GL_LINEAR.
666  * 3. Do glCopyImageSubData to or from that texture.
667  * 4. Make sure it succeeds and does not raise GL_INVALID_OPERATION.
668  **/
669 class IntegerTexTest : public deqp::TestCase
670 {
671 public:
672     IntegerTexTest(deqp::Context &context);
~IntegerTexTest()673     virtual ~IntegerTexTest()
674     {
675     }
676 
677     /* Implementation of tcu::TestNode methods */
678     virtual IterateResult iterate(void);
679 
680 private:
681     /* Private types */
682     struct testCase
683     {
684         glw::GLint m_internal_format;
685         glw::GLuint m_type;
686     };
687 
688     /* Private methods */
689     unsigned int createTexture(int width, int height, glw::GLint internalFormat, glw::GLuint type, const void *data,
690                                int minFilter, int magFilter);
691     void clean();
692 
693     /* Private fields */
694     glw::GLuint m_dst_buf_name;
695     glw::GLuint m_dst_tex_name;
696     glw::GLuint m_src_buf_name;
697     glw::GLuint m_src_tex_name;
698     glw::GLuint m_test_case_index;
699 };
700 } // namespace CopyImage
701 
702 class CopyImageTests : public deqp::TestCaseGroup
703 {
704 public:
705     CopyImageTests(deqp::Context &context);
706     ~CopyImageTests(void);
707 
708     virtual void init(void);
709 
710 private:
711     CopyImageTests(const CopyImageTests &other);
712     CopyImageTests &operator=(const CopyImageTests &other);
713 };
714 } /* namespace gl4cts */
715 
716 #endif // _GL4CCOPYIMAGETESTS_HPP
717