xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gles3/es3cCopyTexImageConversionsTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2018 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 es3cCopyTexImageConversionsTests.cpp
21  * \brief Tests verifying glCopyTexImage2D..
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "es3cCopyTexImageConversionsTests.hpp"
25 #include "deMath.h"
26 #include "deSharedPtr.hpp"
27 #include "gluContextInfo.hpp"
28 #include "gluDefs.hpp"
29 #include "gluStrUtil.hpp"
30 #include "glwEnums.hpp"
31 #include "glwFunctions.hpp"
32 #include "tcuStringTemplate.hpp"
33 #include "tcuTestLog.hpp"
34 #include <cstring>
35 #include <limits>
36 #include <map>
37 
38 using namespace glw;
39 
40 namespace es3cts
41 {
42 
43 // Amount of entries database should allocate for its entries upon creation.
44 #define N_START_CONVERSION_DATABASE_ENTRIES (32)
45 
46 // Should 3D textures be used as source attachments, this field defines
47 //  their depth. It MUST be at least 2, because the test implementation
48 //  also uses second array (counted from one) to store the data-set information.
49 #define TEXTURE_DEPTH (2)
50 // Data set height
51 #define TEXTURE_HEIGHT (2)
52 // Data set width
53 #define TEXTURE_WIDTH (2)
54 
55 // Defines for non color-renderable textures support
56 #define NUMBER_OF_ELEMENTS_IN_VEC4 (4)
57 #define NUMBER_OF_POINTS_TO_DRAW (TEXTURE_WIDTH * TEXTURE_HEIGHT)
58 #define TEXTURE_COORDINATES_ARRAY_SIZE (TEXTURE_WIDTH * TEXTURE_HEIGHT * NUMBER_OF_ELEMENTS_IN_VEC4 * sizeof(float))
59 #define TEXTURE_2D_SAMPLER_TYPE (0)
60 #define TEXTURE_3D_SAMPLER_TYPE (1)
61 #define TEXTURE_2D_ARRAY_SAMPLER_TYPE (2)
62 #define TEXTURE_CUBE_SAMPLER_TYPE (3)
63 #define SRC_TEXTURE_COORDS_ATTRIB_INDEX (1)
64 #define DST_TEXTURE_COORDS_ATTRIB_INDEX (0)
65 
66 // Buffer object indices used for non color-renderable textures support.
67 #define COMPARISON_RESULT_BUFFER_OBJECT_INDEX (0)
68 #define SOURCE_TEXTURE_PIXELS_BUFFER_OBJECT_INDEX (1)
69 #define DESTINATION_TEXTURE_PIXELS_BUFFER_OBJECT_INDEX (2)
70 
71 // Stores detailed information about:
72 // 1) what FBO effective internalformats can be used for glCopyTexImage2D(), assuming
73 //    specific result texture's internalformat as passed by one of the arguments.
74 // 2) what internalformat the result texture object should use.
75 const GLenum conversionArray[] = {
76     /*                     GL_RGBA        GL_RGB       GL_LUMINANCE_ALPHA         GL_LUMINANCE        GL_ALPHA       GL_R8    GL_R8_SNORM  GL_RG8       GL_RG8_SNORM  GL_RGB8  GL_RGB8_SNORM  GL_RGB565  GL_RGBA4  GL_RGB5_A1  GL_RGBA8  GL_RGBA8_SNORM  GL_RGB10_A2  GL_RGB10_A2UI  GL_SRGB8  GL_SRGB8_ALPHA8  GL_R16F  GL_RG16F  GL_RGB16F  GL_RGBA16F  GL_R32F   GL_RG32F  GL_RGB32F  GL_RGBA32F  GL_R11F_G11F_B10F  GL_RGB9_E5   GL_R8I    GL_R8UI   GL_R16I   GL_R16UI  GL_R32I   GL_R32UI  GL_RG8I   GL_RG8UI  GL_RG16I  GL_RG16UI  GL_RG32I   GL_RG32UI  GL_RGB8I  GL_RGB8UI  GL_RGB16I  GL_RGB16UI  GL_RGB32I  GL_RGB32UI  GL_RGBA8I  GL_RGBA8UI  GL_RGBA16I  GL_RGBA16UI  GL_RGBA32I  GL_RGBA32UI */
77     /* GL_R8, */ GL_NONE,
78     GL_NONE,
79     GL_NONE,
80     GL_LUMINANCE8_OES,
81     GL_NONE,
82     GL_R8,
83     GL_NONE,
84     GL_NONE,
85     GL_NONE,
86     GL_NONE,
87     GL_NONE,
88     GL_NONE,
89     GL_NONE,
90     GL_NONE,
91     GL_NONE,
92     GL_NONE,
93     GL_NONE,
94     GL_NONE,
95     GL_NONE,
96     GL_NONE,
97     GL_NONE,
98     GL_NONE,
99     GL_NONE,
100     GL_NONE,
101     GL_NONE,
102     GL_NONE,
103     GL_NONE,
104     GL_NONE,
105     GL_NONE,
106     GL_NONE,
107     GL_NONE,
108     GL_NONE,
109     GL_NONE,
110     GL_NONE,
111     GL_NONE,
112     GL_NONE,
113     GL_NONE,
114     GL_NONE,
115     GL_NONE,
116     GL_NONE,
117     GL_NONE,
118     GL_NONE,
119     GL_NONE,
120     GL_NONE,
121     GL_NONE,
122     GL_NONE,
123     GL_NONE,
124     GL_NONE,
125     GL_NONE,
126     GL_NONE,
127     GL_NONE,
128     GL_NONE,
129     GL_NONE,
130     GL_NONE,
131     /* GL_RG8, */ GL_NONE,
132     GL_NONE,
133     GL_NONE,
134     GL_LUMINANCE8_OES,
135     GL_NONE,
136     GL_R8,
137     GL_NONE,
138     GL_RG8,
139     GL_NONE,
140     GL_NONE,
141     GL_NONE,
142     GL_NONE,
143     GL_NONE,
144     GL_NONE,
145     GL_NONE,
146     GL_NONE,
147     GL_NONE,
148     GL_NONE,
149     GL_NONE,
150     GL_NONE,
151     GL_NONE,
152     GL_NONE,
153     GL_NONE,
154     GL_NONE,
155     GL_NONE,
156     GL_NONE,
157     GL_NONE,
158     GL_NONE,
159     GL_NONE,
160     GL_NONE,
161     GL_NONE,
162     GL_NONE,
163     GL_NONE,
164     GL_NONE,
165     GL_NONE,
166     GL_NONE,
167     GL_NONE,
168     GL_NONE,
169     GL_NONE,
170     GL_NONE,
171     GL_NONE,
172     GL_NONE,
173     GL_NONE,
174     GL_NONE,
175     GL_NONE,
176     GL_NONE,
177     GL_NONE,
178     GL_NONE,
179     GL_NONE,
180     GL_NONE,
181     GL_NONE,
182     GL_NONE,
183     GL_NONE,
184     GL_NONE,
185     /* GL_RGB8, */ GL_NONE,
186     GL_RGB8,
187     GL_NONE,
188     GL_LUMINANCE8_OES,
189     GL_NONE,
190     GL_R8,
191     GL_NONE,
192     GL_RG8,
193     GL_NONE,
194     GL_RGB8,
195     GL_NONE,
196     GL_NONE,
197     GL_NONE,
198     GL_NONE,
199     GL_NONE,
200     GL_NONE,
201     GL_NONE,
202     GL_NONE,
203     GL_NONE,
204     GL_NONE,
205     GL_NONE,
206     GL_NONE,
207     GL_NONE,
208     GL_NONE,
209     GL_NONE,
210     GL_NONE,
211     GL_NONE,
212     GL_NONE,
213     GL_NONE,
214     GL_NONE,
215     GL_NONE,
216     GL_NONE,
217     GL_NONE,
218     GL_NONE,
219     GL_NONE,
220     GL_NONE,
221     GL_NONE,
222     GL_NONE,
223     GL_NONE,
224     GL_NONE,
225     GL_NONE,
226     GL_NONE,
227     GL_NONE,
228     GL_NONE,
229     GL_NONE,
230     GL_NONE,
231     GL_NONE,
232     GL_NONE,
233     GL_NONE,
234     GL_NONE,
235     GL_NONE,
236     GL_NONE,
237     GL_NONE,
238     GL_NONE,
239     /* GL_RGB565, */ GL_NONE,
240     GL_RGB565,
241     GL_NONE,
242     GL_LUMINANCE8_OES,
243     GL_NONE,
244     GL_NONE,
245     GL_NONE,
246     GL_NONE,
247     GL_NONE,
248     GL_NONE,
249     GL_NONE,
250     GL_RGB565,
251     GL_NONE,
252     GL_NONE,
253     GL_NONE,
254     GL_NONE,
255     GL_NONE,
256     GL_NONE,
257     GL_NONE,
258     GL_NONE,
259     GL_NONE,
260     GL_NONE,
261     GL_NONE,
262     GL_NONE,
263     GL_NONE,
264     GL_NONE,
265     GL_NONE,
266     GL_NONE,
267     GL_NONE,
268     GL_NONE,
269     GL_NONE,
270     GL_NONE,
271     GL_NONE,
272     GL_NONE,
273     GL_NONE,
274     GL_NONE,
275     GL_NONE,
276     GL_NONE,
277     GL_NONE,
278     GL_NONE,
279     GL_NONE,
280     GL_NONE,
281     GL_NONE,
282     GL_NONE,
283     GL_NONE,
284     GL_NONE,
285     GL_NONE,
286     GL_NONE,
287     GL_NONE,
288     GL_NONE,
289     GL_NONE,
290     GL_NONE,
291     GL_NONE,
292     GL_NONE,
293     /* GL_RGBA4, */ GL_RGBA4,
294     GL_RGB565,
295     GL_LUMINANCE8_ALPHA8_OES,
296     GL_LUMINANCE8_OES,
297     GL_ALPHA8_OES,
298     GL_NONE,
299     GL_NONE,
300     GL_NONE,
301     GL_NONE,
302     GL_NONE,
303     GL_NONE,
304     GL_NONE,
305     GL_RGBA4,
306     GL_NONE,
307     GL_NONE,
308     GL_NONE,
309     GL_NONE,
310     GL_NONE,
311     GL_NONE,
312     GL_NONE,
313     GL_NONE,
314     GL_NONE,
315     GL_NONE,
316     GL_NONE,
317     GL_NONE,
318     GL_NONE,
319     GL_NONE,
320     GL_NONE,
321     GL_NONE,
322     GL_NONE,
323     GL_NONE,
324     GL_NONE,
325     GL_NONE,
326     GL_NONE,
327     GL_NONE,
328     GL_NONE,
329     GL_NONE,
330     GL_NONE,
331     GL_NONE,
332     GL_NONE,
333     GL_NONE,
334     GL_NONE,
335     GL_NONE,
336     GL_NONE,
337     GL_NONE,
338     GL_NONE,
339     GL_NONE,
340     GL_NONE,
341     GL_NONE,
342     GL_NONE,
343     GL_NONE,
344     GL_NONE,
345     GL_NONE,
346     GL_NONE,
347     /* GL_RGB5_A1, */ GL_RGB5_A1,
348     GL_RGB565,
349     GL_LUMINANCE8_ALPHA8_OES,
350     GL_LUMINANCE8_OES,
351     GL_ALPHA8_OES,
352     GL_NONE,
353     GL_NONE,
354     GL_NONE,
355     GL_NONE,
356     GL_NONE,
357     GL_NONE,
358     GL_NONE,
359     GL_NONE,
360     GL_RGB5_A1,
361     GL_NONE,
362     GL_NONE,
363     GL_NONE,
364     GL_NONE,
365     GL_NONE,
366     GL_NONE,
367     GL_NONE,
368     GL_NONE,
369     GL_NONE,
370     GL_NONE,
371     GL_NONE,
372     GL_NONE,
373     GL_NONE,
374     GL_NONE,
375     GL_NONE,
376     GL_NONE,
377     GL_NONE,
378     GL_NONE,
379     GL_NONE,
380     GL_NONE,
381     GL_NONE,
382     GL_NONE,
383     GL_NONE,
384     GL_NONE,
385     GL_NONE,
386     GL_NONE,
387     GL_NONE,
388     GL_NONE,
389     GL_NONE,
390     GL_NONE,
391     GL_NONE,
392     GL_NONE,
393     GL_NONE,
394     GL_NONE,
395     GL_NONE,
396     GL_NONE,
397     GL_NONE,
398     GL_NONE,
399     GL_NONE,
400     GL_NONE,
401     /* GL_RGBA8, */ GL_RGBA8,
402     GL_RGB8,
403     GL_LUMINANCE8_ALPHA8_OES,
404     GL_LUMINANCE8_OES,
405     GL_ALPHA8_OES,
406     GL_R8,
407     GL_NONE,
408     GL_RG8,
409     GL_NONE,
410     GL_RGB8,
411     GL_NONE,
412     GL_NONE,
413     GL_NONE,
414     GL_NONE,
415     GL_RGBA8,
416     GL_NONE,
417     GL_NONE,
418     GL_NONE,
419     GL_NONE,
420     GL_NONE,
421     GL_NONE,
422     GL_NONE,
423     GL_NONE,
424     GL_NONE,
425     GL_NONE,
426     GL_NONE,
427     GL_NONE,
428     GL_NONE,
429     GL_NONE,
430     GL_NONE,
431     GL_NONE,
432     GL_NONE,
433     GL_NONE,
434     GL_NONE,
435     GL_NONE,
436     GL_NONE,
437     GL_NONE,
438     GL_NONE,
439     GL_NONE,
440     GL_NONE,
441     GL_NONE,
442     GL_NONE,
443     GL_NONE,
444     GL_NONE,
445     GL_NONE,
446     GL_NONE,
447     GL_NONE,
448     GL_NONE,
449     GL_NONE,
450     GL_NONE,
451     GL_NONE,
452     GL_NONE,
453     GL_NONE,
454     GL_NONE,
455     /* GL_RGB10_A2, */ GL_NONE,
456     GL_RGB8,
457     GL_NONE,
458     GL_LUMINANCE8_OES,
459     GL_ALPHA8_OES,
460     GL_NONE,
461     GL_NONE,
462     GL_NONE,
463     GL_NONE,
464     GL_NONE,
465     GL_NONE,
466     GL_NONE,
467     GL_NONE,
468     GL_NONE,
469     GL_NONE,
470     GL_NONE,
471     GL_RGB10_A2,
472     GL_NONE,
473     GL_NONE,
474     GL_NONE,
475     GL_NONE,
476     GL_NONE,
477     GL_NONE,
478     GL_NONE,
479     GL_NONE,
480     GL_NONE,
481     GL_NONE,
482     GL_NONE,
483     GL_NONE,
484     GL_NONE,
485     GL_NONE,
486     GL_NONE,
487     GL_NONE,
488     GL_NONE,
489     GL_NONE,
490     GL_NONE,
491     GL_NONE,
492     GL_NONE,
493     GL_NONE,
494     GL_NONE,
495     GL_NONE,
496     GL_NONE,
497     GL_NONE,
498     GL_NONE,
499     GL_NONE,
500     GL_NONE,
501     GL_NONE,
502     GL_NONE,
503     GL_NONE,
504     GL_NONE,
505     GL_NONE,
506     GL_NONE,
507     GL_NONE,
508     GL_NONE,
509     /* GL_RGB10_A2UI, */ GL_NONE,
510     GL_NONE,
511     GL_NONE,
512     GL_NONE,
513     GL_NONE,
514     GL_NONE,
515     GL_NONE,
516     GL_NONE,
517     GL_NONE,
518     GL_NONE,
519     GL_NONE,
520     GL_NONE,
521     GL_NONE,
522     GL_NONE,
523     GL_NONE,
524     GL_NONE,
525     GL_NONE,
526     GL_RGB10_A2UI,
527     GL_NONE,
528     GL_NONE,
529     GL_NONE,
530     GL_NONE,
531     GL_NONE,
532     GL_NONE,
533     GL_NONE,
534     GL_NONE,
535     GL_NONE,
536     GL_NONE,
537     GL_NONE,
538     GL_NONE,
539     GL_NONE,
540     GL_NONE,
541     GL_NONE,
542     GL_NONE,
543     GL_NONE,
544     GL_NONE,
545     GL_NONE,
546     GL_NONE,
547     GL_NONE,
548     GL_NONE,
549     GL_NONE,
550     GL_NONE,
551     GL_NONE,
552     GL_NONE,
553     GL_NONE,
554     GL_NONE,
555     GL_NONE,
556     GL_NONE,
557     GL_NONE,
558     GL_NONE,
559     GL_NONE,
560     GL_NONE,
561     GL_NONE,
562     GL_NONE,
563     /* GL_SRGB8_ALPHA8, */ GL_NONE,
564     GL_NONE,
565     GL_NONE,
566     GL_NONE,
567     GL_NONE,
568     GL_NONE,
569     GL_NONE,
570     GL_NONE,
571     GL_NONE,
572     GL_NONE,
573     GL_NONE,
574     GL_NONE,
575     GL_NONE,
576     GL_NONE,
577     GL_NONE,
578     GL_NONE,
579     GL_NONE,
580     GL_NONE,
581     GL_SRGB8,
582     GL_SRGB8_ALPHA8,
583     GL_NONE,
584     GL_NONE,
585     GL_NONE,
586     GL_NONE,
587     GL_NONE,
588     GL_NONE,
589     GL_NONE,
590     GL_NONE,
591     GL_NONE,
592     GL_NONE,
593     GL_NONE,
594     GL_NONE,
595     GL_NONE,
596     GL_NONE,
597     GL_NONE,
598     GL_NONE,
599     GL_NONE,
600     GL_NONE,
601     GL_NONE,
602     GL_NONE,
603     GL_NONE,
604     GL_NONE,
605     GL_NONE,
606     GL_NONE,
607     GL_NONE,
608     GL_NONE,
609     GL_NONE,
610     GL_NONE,
611     GL_NONE,
612     GL_NONE,
613     GL_NONE,
614     GL_NONE,
615     GL_NONE,
616     GL_NONE,
617     /* GL_R8I, */ GL_NONE,
618     GL_NONE,
619     GL_NONE,
620     GL_NONE,
621     GL_NONE,
622     GL_NONE,
623     GL_NONE,
624     GL_NONE,
625     GL_NONE,
626     GL_NONE,
627     GL_NONE,
628     GL_NONE,
629     GL_NONE,
630     GL_NONE,
631     GL_NONE,
632     GL_NONE,
633     GL_NONE,
634     GL_NONE,
635     GL_NONE,
636     GL_NONE,
637     GL_NONE,
638     GL_NONE,
639     GL_NONE,
640     GL_NONE,
641     GL_NONE,
642     GL_NONE,
643     GL_NONE,
644     GL_NONE,
645     GL_NONE,
646     GL_NONE,
647     GL_R8I,
648     GL_NONE,
649     GL_NONE,
650     GL_NONE,
651     GL_NONE,
652     GL_NONE,
653     GL_NONE,
654     GL_NONE,
655     GL_NONE,
656     GL_NONE,
657     GL_NONE,
658     GL_NONE,
659     GL_NONE,
660     GL_NONE,
661     GL_NONE,
662     GL_NONE,
663     GL_NONE,
664     GL_NONE,
665     GL_NONE,
666     GL_NONE,
667     GL_NONE,
668     GL_NONE,
669     GL_NONE,
670     GL_NONE,
671     /* GL_R8UI, */ GL_NONE,
672     GL_NONE,
673     GL_NONE,
674     GL_NONE,
675     GL_NONE,
676     GL_NONE,
677     GL_NONE,
678     GL_NONE,
679     GL_NONE,
680     GL_NONE,
681     GL_NONE,
682     GL_NONE,
683     GL_NONE,
684     GL_NONE,
685     GL_NONE,
686     GL_NONE,
687     GL_NONE,
688     GL_NONE,
689     GL_NONE,
690     GL_NONE,
691     GL_NONE,
692     GL_NONE,
693     GL_NONE,
694     GL_NONE,
695     GL_NONE,
696     GL_NONE,
697     GL_NONE,
698     GL_NONE,
699     GL_NONE,
700     GL_NONE,
701     GL_NONE,
702     GL_R8UI,
703     GL_NONE,
704     GL_NONE,
705     GL_NONE,
706     GL_NONE,
707     GL_NONE,
708     GL_NONE,
709     GL_NONE,
710     GL_NONE,
711     GL_NONE,
712     GL_NONE,
713     GL_NONE,
714     GL_NONE,
715     GL_NONE,
716     GL_NONE,
717     GL_NONE,
718     GL_NONE,
719     GL_NONE,
720     GL_NONE,
721     GL_NONE,
722     GL_NONE,
723     GL_NONE,
724     GL_NONE,
725     /* GL_R16I, */ GL_NONE,
726     GL_NONE,
727     GL_NONE,
728     GL_NONE,
729     GL_NONE,
730     GL_NONE,
731     GL_NONE,
732     GL_NONE,
733     GL_NONE,
734     GL_NONE,
735     GL_NONE,
736     GL_NONE,
737     GL_NONE,
738     GL_NONE,
739     GL_NONE,
740     GL_NONE,
741     GL_NONE,
742     GL_NONE,
743     GL_NONE,
744     GL_NONE,
745     GL_NONE,
746     GL_NONE,
747     GL_NONE,
748     GL_NONE,
749     GL_NONE,
750     GL_NONE,
751     GL_NONE,
752     GL_NONE,
753     GL_NONE,
754     GL_NONE,
755     GL_NONE,
756     GL_NONE,
757     GL_R16I,
758     GL_NONE,
759     GL_NONE,
760     GL_NONE,
761     GL_NONE,
762     GL_NONE,
763     GL_NONE,
764     GL_NONE,
765     GL_NONE,
766     GL_NONE,
767     GL_NONE,
768     GL_NONE,
769     GL_NONE,
770     GL_NONE,
771     GL_NONE,
772     GL_NONE,
773     GL_NONE,
774     GL_NONE,
775     GL_NONE,
776     GL_NONE,
777     GL_NONE,
778     GL_NONE,
779     /* GL_R16UI, */ GL_NONE,
780     GL_NONE,
781     GL_NONE,
782     GL_NONE,
783     GL_NONE,
784     GL_NONE,
785     GL_NONE,
786     GL_NONE,
787     GL_NONE,
788     GL_NONE,
789     GL_NONE,
790     GL_NONE,
791     GL_NONE,
792     GL_NONE,
793     GL_NONE,
794     GL_NONE,
795     GL_NONE,
796     GL_NONE,
797     GL_NONE,
798     GL_NONE,
799     GL_NONE,
800     GL_NONE,
801     GL_NONE,
802     GL_NONE,
803     GL_NONE,
804     GL_NONE,
805     GL_NONE,
806     GL_NONE,
807     GL_NONE,
808     GL_NONE,
809     GL_NONE,
810     GL_NONE,
811     GL_NONE,
812     GL_R16UI,
813     GL_NONE,
814     GL_NONE,
815     GL_NONE,
816     GL_NONE,
817     GL_NONE,
818     GL_NONE,
819     GL_NONE,
820     GL_NONE,
821     GL_NONE,
822     GL_NONE,
823     GL_NONE,
824     GL_NONE,
825     GL_NONE,
826     GL_NONE,
827     GL_NONE,
828     GL_NONE,
829     GL_NONE,
830     GL_NONE,
831     GL_NONE,
832     GL_NONE,
833     /* GL_R32I, */ GL_NONE,
834     GL_NONE,
835     GL_NONE,
836     GL_NONE,
837     GL_NONE,
838     GL_NONE,
839     GL_NONE,
840     GL_NONE,
841     GL_NONE,
842     GL_NONE,
843     GL_NONE,
844     GL_NONE,
845     GL_NONE,
846     GL_NONE,
847     GL_NONE,
848     GL_NONE,
849     GL_NONE,
850     GL_NONE,
851     GL_NONE,
852     GL_NONE,
853     GL_NONE,
854     GL_NONE,
855     GL_NONE,
856     GL_NONE,
857     GL_NONE,
858     GL_NONE,
859     GL_NONE,
860     GL_NONE,
861     GL_NONE,
862     GL_NONE,
863     GL_NONE,
864     GL_NONE,
865     GL_NONE,
866     GL_NONE,
867     GL_R32I,
868     GL_NONE,
869     GL_NONE,
870     GL_NONE,
871     GL_NONE,
872     GL_NONE,
873     GL_NONE,
874     GL_NONE,
875     GL_NONE,
876     GL_NONE,
877     GL_NONE,
878     GL_NONE,
879     GL_NONE,
880     GL_NONE,
881     GL_NONE,
882     GL_NONE,
883     GL_NONE,
884     GL_NONE,
885     GL_NONE,
886     GL_NONE,
887     /* GL_R32UI, */ GL_NONE,
888     GL_NONE,
889     GL_NONE,
890     GL_NONE,
891     GL_NONE,
892     GL_NONE,
893     GL_NONE,
894     GL_NONE,
895     GL_NONE,
896     GL_NONE,
897     GL_NONE,
898     GL_NONE,
899     GL_NONE,
900     GL_NONE,
901     GL_NONE,
902     GL_NONE,
903     GL_NONE,
904     GL_NONE,
905     GL_NONE,
906     GL_NONE,
907     GL_NONE,
908     GL_NONE,
909     GL_NONE,
910     GL_NONE,
911     GL_NONE,
912     GL_NONE,
913     GL_NONE,
914     GL_NONE,
915     GL_NONE,
916     GL_NONE,
917     GL_NONE,
918     GL_NONE,
919     GL_NONE,
920     GL_NONE,
921     GL_NONE,
922     GL_R32UI,
923     GL_NONE,
924     GL_NONE,
925     GL_NONE,
926     GL_NONE,
927     GL_NONE,
928     GL_NONE,
929     GL_NONE,
930     GL_NONE,
931     GL_NONE,
932     GL_NONE,
933     GL_NONE,
934     GL_NONE,
935     GL_NONE,
936     GL_NONE,
937     GL_NONE,
938     GL_NONE,
939     GL_NONE,
940     GL_NONE,
941     /* GL_RG8I, */ GL_NONE,
942     GL_NONE,
943     GL_NONE,
944     GL_NONE,
945     GL_NONE,
946     GL_NONE,
947     GL_NONE,
948     GL_NONE,
949     GL_NONE,
950     GL_NONE,
951     GL_NONE,
952     GL_NONE,
953     GL_NONE,
954     GL_NONE,
955     GL_NONE,
956     GL_NONE,
957     GL_NONE,
958     GL_NONE,
959     GL_NONE,
960     GL_NONE,
961     GL_NONE,
962     GL_NONE,
963     GL_NONE,
964     GL_NONE,
965     GL_NONE,
966     GL_NONE,
967     GL_NONE,
968     GL_NONE,
969     GL_NONE,
970     GL_NONE,
971     GL_R8I,
972     GL_NONE,
973     GL_NONE,
974     GL_NONE,
975     GL_NONE,
976     GL_NONE,
977     GL_RG8I,
978     GL_NONE,
979     GL_NONE,
980     GL_NONE,
981     GL_NONE,
982     GL_NONE,
983     GL_NONE,
984     GL_NONE,
985     GL_NONE,
986     GL_NONE,
987     GL_NONE,
988     GL_NONE,
989     GL_NONE,
990     GL_NONE,
991     GL_NONE,
992     GL_NONE,
993     GL_NONE,
994     GL_NONE,
995     /* GL_RG8UI, */ GL_NONE,
996     GL_NONE,
997     GL_NONE,
998     GL_NONE,
999     GL_NONE,
1000     GL_NONE,
1001     GL_NONE,
1002     GL_NONE,
1003     GL_NONE,
1004     GL_NONE,
1005     GL_NONE,
1006     GL_NONE,
1007     GL_NONE,
1008     GL_NONE,
1009     GL_NONE,
1010     GL_NONE,
1011     GL_NONE,
1012     GL_NONE,
1013     GL_NONE,
1014     GL_NONE,
1015     GL_NONE,
1016     GL_NONE,
1017     GL_NONE,
1018     GL_NONE,
1019     GL_NONE,
1020     GL_NONE,
1021     GL_NONE,
1022     GL_NONE,
1023     GL_NONE,
1024     GL_NONE,
1025     GL_NONE,
1026     GL_R8UI,
1027     GL_NONE,
1028     GL_NONE,
1029     GL_NONE,
1030     GL_NONE,
1031     GL_NONE,
1032     GL_RG8UI,
1033     GL_NONE,
1034     GL_NONE,
1035     GL_NONE,
1036     GL_NONE,
1037     GL_NONE,
1038     GL_NONE,
1039     GL_NONE,
1040     GL_NONE,
1041     GL_NONE,
1042     GL_NONE,
1043     GL_NONE,
1044     GL_NONE,
1045     GL_NONE,
1046     GL_NONE,
1047     GL_NONE,
1048     GL_NONE,
1049     /* GL_RG16I, */ GL_NONE,
1050     GL_NONE,
1051     GL_NONE,
1052     GL_NONE,
1053     GL_NONE,
1054     GL_NONE,
1055     GL_NONE,
1056     GL_NONE,
1057     GL_NONE,
1058     GL_NONE,
1059     GL_NONE,
1060     GL_NONE,
1061     GL_NONE,
1062     GL_NONE,
1063     GL_NONE,
1064     GL_NONE,
1065     GL_NONE,
1066     GL_NONE,
1067     GL_NONE,
1068     GL_NONE,
1069     GL_NONE,
1070     GL_NONE,
1071     GL_NONE,
1072     GL_NONE,
1073     GL_NONE,
1074     GL_NONE,
1075     GL_NONE,
1076     GL_NONE,
1077     GL_NONE,
1078     GL_NONE,
1079     GL_NONE,
1080     GL_NONE,
1081     GL_R16I,
1082     GL_NONE,
1083     GL_NONE,
1084     GL_NONE,
1085     GL_NONE,
1086     GL_NONE,
1087     GL_RG16I,
1088     GL_NONE,
1089     GL_NONE,
1090     GL_NONE,
1091     GL_NONE,
1092     GL_NONE,
1093     GL_NONE,
1094     GL_NONE,
1095     GL_NONE,
1096     GL_NONE,
1097     GL_NONE,
1098     GL_NONE,
1099     GL_NONE,
1100     GL_NONE,
1101     GL_NONE,
1102     GL_NONE,
1103     /* GL_RG16UI, */ GL_NONE,
1104     GL_NONE,
1105     GL_NONE,
1106     GL_NONE,
1107     GL_NONE,
1108     GL_NONE,
1109     GL_NONE,
1110     GL_NONE,
1111     GL_NONE,
1112     GL_NONE,
1113     GL_NONE,
1114     GL_NONE,
1115     GL_NONE,
1116     GL_NONE,
1117     GL_NONE,
1118     GL_NONE,
1119     GL_NONE,
1120     GL_NONE,
1121     GL_NONE,
1122     GL_NONE,
1123     GL_NONE,
1124     GL_NONE,
1125     GL_NONE,
1126     GL_NONE,
1127     GL_NONE,
1128     GL_NONE,
1129     GL_NONE,
1130     GL_NONE,
1131     GL_NONE,
1132     GL_NONE,
1133     GL_NONE,
1134     GL_NONE,
1135     GL_NONE,
1136     GL_R16UI,
1137     GL_NONE,
1138     GL_NONE,
1139     GL_NONE,
1140     GL_NONE,
1141     GL_NONE,
1142     GL_RG16UI,
1143     GL_NONE,
1144     GL_NONE,
1145     GL_NONE,
1146     GL_NONE,
1147     GL_NONE,
1148     GL_NONE,
1149     GL_NONE,
1150     GL_NONE,
1151     GL_NONE,
1152     GL_NONE,
1153     GL_NONE,
1154     GL_NONE,
1155     GL_NONE,
1156     GL_NONE,
1157     /* GL_RG32I, */ GL_NONE,
1158     GL_NONE,
1159     GL_NONE,
1160     GL_NONE,
1161     GL_NONE,
1162     GL_NONE,
1163     GL_NONE,
1164     GL_NONE,
1165     GL_NONE,
1166     GL_NONE,
1167     GL_NONE,
1168     GL_NONE,
1169     GL_NONE,
1170     GL_NONE,
1171     GL_NONE,
1172     GL_NONE,
1173     GL_NONE,
1174     GL_NONE,
1175     GL_NONE,
1176     GL_NONE,
1177     GL_NONE,
1178     GL_NONE,
1179     GL_NONE,
1180     GL_NONE,
1181     GL_NONE,
1182     GL_NONE,
1183     GL_NONE,
1184     GL_NONE,
1185     GL_NONE,
1186     GL_NONE,
1187     GL_NONE,
1188     GL_NONE,
1189     GL_NONE,
1190     GL_NONE,
1191     GL_R32I,
1192     GL_NONE,
1193     GL_NONE,
1194     GL_NONE,
1195     GL_NONE,
1196     GL_NONE,
1197     GL_RG32I,
1198     GL_NONE,
1199     GL_NONE,
1200     GL_NONE,
1201     GL_NONE,
1202     GL_NONE,
1203     GL_NONE,
1204     GL_NONE,
1205     GL_NONE,
1206     GL_NONE,
1207     GL_NONE,
1208     GL_NONE,
1209     GL_NONE,
1210     GL_NONE,
1211     /* GL_RG32UI, */ GL_NONE,
1212     GL_NONE,
1213     GL_NONE,
1214     GL_NONE,
1215     GL_NONE,
1216     GL_NONE,
1217     GL_NONE,
1218     GL_NONE,
1219     GL_NONE,
1220     GL_NONE,
1221     GL_NONE,
1222     GL_NONE,
1223     GL_NONE,
1224     GL_NONE,
1225     GL_NONE,
1226     GL_NONE,
1227     GL_NONE,
1228     GL_NONE,
1229     GL_NONE,
1230     GL_NONE,
1231     GL_NONE,
1232     GL_NONE,
1233     GL_NONE,
1234     GL_NONE,
1235     GL_NONE,
1236     GL_NONE,
1237     GL_NONE,
1238     GL_NONE,
1239     GL_NONE,
1240     GL_NONE,
1241     GL_NONE,
1242     GL_NONE,
1243     GL_NONE,
1244     GL_NONE,
1245     GL_NONE,
1246     GL_R32UI,
1247     GL_NONE,
1248     GL_NONE,
1249     GL_NONE,
1250     GL_NONE,
1251     GL_NONE,
1252     GL_RG32UI,
1253     GL_NONE,
1254     GL_NONE,
1255     GL_NONE,
1256     GL_NONE,
1257     GL_NONE,
1258     GL_NONE,
1259     GL_NONE,
1260     GL_NONE,
1261     GL_NONE,
1262     GL_NONE,
1263     GL_NONE,
1264     GL_NONE,
1265     /* GL_RGBA8I, */ GL_NONE,
1266     GL_NONE,
1267     GL_NONE,
1268     GL_NONE,
1269     GL_NONE,
1270     GL_NONE,
1271     GL_NONE,
1272     GL_NONE,
1273     GL_NONE,
1274     GL_NONE,
1275     GL_NONE,
1276     GL_NONE,
1277     GL_NONE,
1278     GL_NONE,
1279     GL_NONE,
1280     GL_NONE,
1281     GL_NONE,
1282     GL_NONE,
1283     GL_NONE,
1284     GL_NONE,
1285     GL_NONE,
1286     GL_NONE,
1287     GL_NONE,
1288     GL_NONE,
1289     GL_NONE,
1290     GL_NONE,
1291     GL_NONE,
1292     GL_NONE,
1293     GL_NONE,
1294     GL_NONE,
1295     GL_R8I,
1296     GL_NONE,
1297     GL_NONE,
1298     GL_NONE,
1299     GL_NONE,
1300     GL_NONE,
1301     GL_RG8I,
1302     GL_NONE,
1303     GL_NONE,
1304     GL_NONE,
1305     GL_NONE,
1306     GL_NONE,
1307     GL_RGB8I,
1308     GL_NONE,
1309     GL_NONE,
1310     GL_NONE,
1311     GL_NONE,
1312     GL_NONE,
1313     GL_RGBA8I,
1314     GL_NONE,
1315     GL_NONE,
1316     GL_NONE,
1317     GL_NONE,
1318     GL_NONE,
1319     /* GL_RGBA8UI, */ GL_NONE,
1320     GL_NONE,
1321     GL_NONE,
1322     GL_NONE,
1323     GL_NONE,
1324     GL_NONE,
1325     GL_NONE,
1326     GL_NONE,
1327     GL_NONE,
1328     GL_NONE,
1329     GL_NONE,
1330     GL_NONE,
1331     GL_NONE,
1332     GL_NONE,
1333     GL_NONE,
1334     GL_NONE,
1335     GL_NONE,
1336     GL_NONE,
1337     GL_NONE,
1338     GL_NONE,
1339     GL_NONE,
1340     GL_NONE,
1341     GL_NONE,
1342     GL_NONE,
1343     GL_NONE,
1344     GL_NONE,
1345     GL_NONE,
1346     GL_NONE,
1347     GL_NONE,
1348     GL_NONE,
1349     GL_NONE,
1350     GL_R8UI,
1351     GL_NONE,
1352     GL_NONE,
1353     GL_NONE,
1354     GL_NONE,
1355     GL_NONE,
1356     GL_RG8UI,
1357     GL_NONE,
1358     GL_NONE,
1359     GL_NONE,
1360     GL_NONE,
1361     GL_NONE,
1362     GL_RGB8UI,
1363     GL_NONE,
1364     GL_NONE,
1365     GL_NONE,
1366     GL_NONE,
1367     GL_NONE,
1368     GL_RGBA8UI,
1369     GL_NONE,
1370     GL_NONE,
1371     GL_NONE,
1372     GL_NONE,
1373     /* GL_RGBA16I, */ GL_NONE,
1374     GL_NONE,
1375     GL_NONE,
1376     GL_NONE,
1377     GL_NONE,
1378     GL_NONE,
1379     GL_NONE,
1380     GL_NONE,
1381     GL_NONE,
1382     GL_NONE,
1383     GL_NONE,
1384     GL_NONE,
1385     GL_NONE,
1386     GL_NONE,
1387     GL_NONE,
1388     GL_NONE,
1389     GL_NONE,
1390     GL_NONE,
1391     GL_NONE,
1392     GL_NONE,
1393     GL_NONE,
1394     GL_NONE,
1395     GL_NONE,
1396     GL_NONE,
1397     GL_NONE,
1398     GL_NONE,
1399     GL_NONE,
1400     GL_NONE,
1401     GL_NONE,
1402     GL_NONE,
1403     GL_NONE,
1404     GL_NONE,
1405     GL_R16I,
1406     GL_NONE,
1407     GL_NONE,
1408     GL_NONE,
1409     GL_NONE,
1410     GL_NONE,
1411     GL_RG16I,
1412     GL_NONE,
1413     GL_NONE,
1414     GL_NONE,
1415     GL_NONE,
1416     GL_NONE,
1417     GL_RGB16I,
1418     GL_NONE,
1419     GL_NONE,
1420     GL_NONE,
1421     GL_NONE,
1422     GL_NONE,
1423     GL_RGBA16I,
1424     GL_NONE,
1425     GL_NONE,
1426     GL_NONE,
1427     /* GL_RGBA16UI, */ GL_NONE,
1428     GL_NONE,
1429     GL_NONE,
1430     GL_NONE,
1431     GL_NONE,
1432     GL_NONE,
1433     GL_NONE,
1434     GL_NONE,
1435     GL_NONE,
1436     GL_NONE,
1437     GL_NONE,
1438     GL_NONE,
1439     GL_NONE,
1440     GL_NONE,
1441     GL_NONE,
1442     GL_NONE,
1443     GL_NONE,
1444     GL_NONE,
1445     GL_NONE,
1446     GL_NONE,
1447     GL_NONE,
1448     GL_NONE,
1449     GL_NONE,
1450     GL_NONE,
1451     GL_NONE,
1452     GL_NONE,
1453     GL_NONE,
1454     GL_NONE,
1455     GL_NONE,
1456     GL_NONE,
1457     GL_NONE,
1458     GL_NONE,
1459     GL_NONE,
1460     GL_R16UI,
1461     GL_NONE,
1462     GL_NONE,
1463     GL_NONE,
1464     GL_NONE,
1465     GL_NONE,
1466     GL_RG16UI,
1467     GL_NONE,
1468     GL_NONE,
1469     GL_NONE,
1470     GL_NONE,
1471     GL_NONE,
1472     GL_RGB16UI,
1473     GL_NONE,
1474     GL_NONE,
1475     GL_NONE,
1476     GL_NONE,
1477     GL_NONE,
1478     GL_RGBA16UI,
1479     GL_NONE,
1480     GL_NONE,
1481     /* GL_RGBA32I, */ GL_NONE,
1482     GL_NONE,
1483     GL_NONE,
1484     GL_NONE,
1485     GL_NONE,
1486     GL_NONE,
1487     GL_NONE,
1488     GL_NONE,
1489     GL_NONE,
1490     GL_NONE,
1491     GL_NONE,
1492     GL_NONE,
1493     GL_NONE,
1494     GL_NONE,
1495     GL_NONE,
1496     GL_NONE,
1497     GL_NONE,
1498     GL_NONE,
1499     GL_NONE,
1500     GL_NONE,
1501     GL_NONE,
1502     GL_NONE,
1503     GL_NONE,
1504     GL_NONE,
1505     GL_NONE,
1506     GL_NONE,
1507     GL_NONE,
1508     GL_NONE,
1509     GL_NONE,
1510     GL_NONE,
1511     GL_NONE,
1512     GL_NONE,
1513     GL_NONE,
1514     GL_NONE,
1515     GL_R32I,
1516     GL_NONE,
1517     GL_NONE,
1518     GL_NONE,
1519     GL_NONE,
1520     GL_NONE,
1521     GL_RG32I,
1522     GL_NONE,
1523     GL_NONE,
1524     GL_NONE,
1525     GL_NONE,
1526     GL_NONE,
1527     GL_RGB32I,
1528     GL_NONE,
1529     GL_NONE,
1530     GL_NONE,
1531     GL_NONE,
1532     GL_NONE,
1533     GL_RGBA32I,
1534     GL_NONE,
1535     /* GL_RGBA32UI, */ GL_NONE,
1536     GL_NONE,
1537     GL_NONE,
1538     GL_NONE,
1539     GL_NONE,
1540     GL_NONE,
1541     GL_NONE,
1542     GL_NONE,
1543     GL_NONE,
1544     GL_NONE,
1545     GL_NONE,
1546     GL_NONE,
1547     GL_NONE,
1548     GL_NONE,
1549     GL_NONE,
1550     GL_NONE,
1551     GL_NONE,
1552     GL_NONE,
1553     GL_NONE,
1554     GL_NONE,
1555     GL_NONE,
1556     GL_NONE,
1557     GL_NONE,
1558     GL_NONE,
1559     GL_NONE,
1560     GL_NONE,
1561     GL_NONE,
1562     GL_NONE,
1563     GL_NONE,
1564     GL_NONE,
1565     GL_NONE,
1566     GL_NONE,
1567     GL_NONE,
1568     GL_NONE,
1569     GL_NONE,
1570     GL_R32UI,
1571     GL_NONE,
1572     GL_NONE,
1573     GL_NONE,
1574     GL_NONE,
1575     GL_NONE,
1576     GL_RG32UI,
1577     GL_NONE,
1578     GL_NONE,
1579     GL_NONE,
1580     GL_NONE,
1581     GL_NONE,
1582     GL_RGB32UI,
1583     GL_NONE,
1584     GL_NONE,
1585     GL_NONE,
1586     GL_NONE,
1587     GL_NONE,
1588     GL_RGBA32UI,
1589     /* GL_R16F, */ GL_NONE,
1590     GL_NONE,
1591     GL_NONE,
1592     GL_NONE,
1593     GL_NONE,
1594     GL_NONE,
1595     GL_NONE,
1596     GL_NONE,
1597     GL_NONE,
1598     GL_NONE,
1599     GL_NONE,
1600     GL_NONE,
1601     GL_NONE,
1602     GL_NONE,
1603     GL_NONE,
1604     GL_NONE,
1605     GL_NONE,
1606     GL_NONE,
1607     GL_NONE,
1608     GL_NONE,
1609     GL_R16F,
1610     GL_NONE,
1611     GL_NONE,
1612     GL_NONE,
1613     GL_NONE,
1614     GL_NONE,
1615     GL_NONE,
1616     GL_NONE,
1617     GL_NONE,
1618     GL_NONE,
1619     GL_NONE,
1620     GL_NONE,
1621     GL_NONE,
1622     GL_NONE,
1623     GL_NONE,
1624     GL_NONE,
1625     GL_NONE,
1626     GL_NONE,
1627     GL_NONE,
1628     GL_NONE,
1629     GL_NONE,
1630     GL_NONE,
1631     GL_NONE,
1632     GL_NONE,
1633     GL_NONE,
1634     GL_NONE,
1635     GL_NONE,
1636     GL_NONE,
1637     GL_NONE,
1638     GL_NONE,
1639     GL_NONE,
1640     GL_NONE,
1641     GL_NONE,
1642     GL_NONE,
1643     /* GL_RG16F, */ GL_NONE,
1644     GL_NONE,
1645     GL_NONE,
1646     GL_NONE,
1647     GL_NONE,
1648     GL_NONE,
1649     GL_NONE,
1650     GL_NONE,
1651     GL_NONE,
1652     GL_NONE,
1653     GL_NONE,
1654     GL_NONE,
1655     GL_NONE,
1656     GL_NONE,
1657     GL_NONE,
1658     GL_NONE,
1659     GL_NONE,
1660     GL_NONE,
1661     GL_NONE,
1662     GL_NONE,
1663     GL_R16F,
1664     GL_RG16F,
1665     GL_NONE,
1666     GL_NONE,
1667     GL_NONE,
1668     GL_NONE,
1669     GL_NONE,
1670     GL_NONE,
1671     GL_NONE,
1672     GL_NONE,
1673     GL_NONE,
1674     GL_NONE,
1675     GL_NONE,
1676     GL_NONE,
1677     GL_NONE,
1678     GL_NONE,
1679     GL_NONE,
1680     GL_NONE,
1681     GL_NONE,
1682     GL_NONE,
1683     GL_NONE,
1684     GL_NONE,
1685     GL_NONE,
1686     GL_NONE,
1687     GL_NONE,
1688     GL_NONE,
1689     GL_NONE,
1690     GL_NONE,
1691     GL_NONE,
1692     GL_NONE,
1693     GL_NONE,
1694     GL_NONE,
1695     GL_NONE,
1696     GL_NONE,
1697     /* GL_R32F, */ GL_NONE,
1698     GL_NONE,
1699     GL_NONE,
1700     GL_NONE,
1701     GL_NONE,
1702     GL_NONE,
1703     GL_NONE,
1704     GL_NONE,
1705     GL_NONE,
1706     GL_NONE,
1707     GL_NONE,
1708     GL_NONE,
1709     GL_NONE,
1710     GL_NONE,
1711     GL_NONE,
1712     GL_NONE,
1713     GL_NONE,
1714     GL_NONE,
1715     GL_NONE,
1716     GL_NONE,
1717     GL_NONE,
1718     GL_NONE,
1719     GL_NONE,
1720     GL_NONE,
1721     GL_R32F,
1722     GL_NONE,
1723     GL_NONE,
1724     GL_NONE,
1725     GL_NONE,
1726     GL_NONE,
1727     GL_NONE,
1728     GL_NONE,
1729     GL_NONE,
1730     GL_NONE,
1731     GL_NONE,
1732     GL_NONE,
1733     GL_NONE,
1734     GL_NONE,
1735     GL_NONE,
1736     GL_NONE,
1737     GL_NONE,
1738     GL_NONE,
1739     GL_NONE,
1740     GL_NONE,
1741     GL_NONE,
1742     GL_NONE,
1743     GL_NONE,
1744     GL_NONE,
1745     GL_NONE,
1746     GL_NONE,
1747     GL_NONE,
1748     GL_NONE,
1749     GL_NONE,
1750     GL_NONE,
1751     /* GL_RG32F, */ GL_NONE,
1752     GL_NONE,
1753     GL_NONE,
1754     GL_NONE,
1755     GL_NONE,
1756     GL_NONE,
1757     GL_NONE,
1758     GL_NONE,
1759     GL_NONE,
1760     GL_NONE,
1761     GL_NONE,
1762     GL_NONE,
1763     GL_NONE,
1764     GL_NONE,
1765     GL_NONE,
1766     GL_NONE,
1767     GL_NONE,
1768     GL_NONE,
1769     GL_NONE,
1770     GL_NONE,
1771     GL_NONE,
1772     GL_NONE,
1773     GL_NONE,
1774     GL_NONE,
1775     GL_R32F,
1776     GL_RG32F,
1777     GL_NONE,
1778     GL_NONE,
1779     GL_NONE,
1780     GL_NONE,
1781     GL_NONE,
1782     GL_NONE,
1783     GL_NONE,
1784     GL_NONE,
1785     GL_NONE,
1786     GL_NONE,
1787     GL_NONE,
1788     GL_NONE,
1789     GL_NONE,
1790     GL_NONE,
1791     GL_NONE,
1792     GL_NONE,
1793     GL_NONE,
1794     GL_NONE,
1795     GL_NONE,
1796     GL_NONE,
1797     GL_NONE,
1798     GL_NONE,
1799     GL_NONE,
1800     GL_NONE,
1801     GL_NONE,
1802     GL_NONE,
1803     GL_NONE,
1804     GL_NONE,
1805     /* GL_RGB16F, */ GL_NONE,
1806     GL_NONE,
1807     GL_NONE,
1808     GL_NONE,
1809     GL_NONE,
1810     GL_NONE,
1811     GL_NONE,
1812     GL_NONE,
1813     GL_NONE,
1814     GL_NONE,
1815     GL_NONE,
1816     GL_NONE,
1817     GL_NONE,
1818     GL_NONE,
1819     GL_NONE,
1820     GL_NONE,
1821     GL_NONE,
1822     GL_NONE,
1823     GL_NONE,
1824     GL_NONE,
1825     GL_R16F,
1826     GL_RG16F,
1827     GL_RGB16F,
1828     GL_NONE,
1829     GL_NONE,
1830     GL_NONE,
1831     GL_NONE,
1832     GL_NONE,
1833     GL_NONE,
1834     GL_NONE,
1835     GL_NONE,
1836     GL_NONE,
1837     GL_NONE,
1838     GL_NONE,
1839     GL_NONE,
1840     GL_NONE,
1841     GL_NONE,
1842     GL_NONE,
1843     GL_NONE,
1844     GL_NONE,
1845     GL_NONE,
1846     GL_NONE,
1847     GL_NONE,
1848     GL_NONE,
1849     GL_NONE,
1850     GL_NONE,
1851     GL_NONE,
1852     GL_NONE,
1853     GL_NONE,
1854     GL_NONE,
1855     GL_NONE,
1856     GL_NONE,
1857     GL_NONE,
1858     GL_NONE,
1859     /* GL_RGBA16F, */ GL_NONE,
1860     GL_NONE,
1861     GL_NONE,
1862     GL_NONE,
1863     GL_NONE,
1864     GL_NONE,
1865     GL_NONE,
1866     GL_NONE,
1867     GL_NONE,
1868     GL_NONE,
1869     GL_NONE,
1870     GL_NONE,
1871     GL_NONE,
1872     GL_NONE,
1873     GL_NONE,
1874     GL_NONE,
1875     GL_NONE,
1876     GL_NONE,
1877     GL_NONE,
1878     GL_NONE,
1879     GL_R16F,
1880     GL_RG16F,
1881     GL_RGB16F,
1882     GL_RGBA16F,
1883     GL_NONE,
1884     GL_NONE,
1885     GL_NONE,
1886     GL_NONE,
1887     GL_NONE,
1888     GL_NONE,
1889     GL_NONE,
1890     GL_NONE,
1891     GL_NONE,
1892     GL_NONE,
1893     GL_NONE,
1894     GL_NONE,
1895     GL_NONE,
1896     GL_NONE,
1897     GL_NONE,
1898     GL_NONE,
1899     GL_NONE,
1900     GL_NONE,
1901     GL_NONE,
1902     GL_NONE,
1903     GL_NONE,
1904     GL_NONE,
1905     GL_NONE,
1906     GL_NONE,
1907     GL_NONE,
1908     GL_NONE,
1909     GL_NONE,
1910     GL_NONE,
1911     GL_NONE,
1912     GL_NONE,
1913     /* GL_RGB32F, */ GL_NONE,
1914     GL_NONE,
1915     GL_NONE,
1916     GL_NONE,
1917     GL_NONE,
1918     GL_NONE,
1919     GL_NONE,
1920     GL_NONE,
1921     GL_NONE,
1922     GL_NONE,
1923     GL_NONE,
1924     GL_NONE,
1925     GL_NONE,
1926     GL_NONE,
1927     GL_NONE,
1928     GL_NONE,
1929     GL_NONE,
1930     GL_NONE,
1931     GL_NONE,
1932     GL_NONE,
1933     GL_NONE,
1934     GL_NONE,
1935     GL_NONE,
1936     GL_NONE,
1937     GL_R32F,
1938     GL_RG32F,
1939     GL_RGB32F,
1940     GL_NONE,
1941     GL_NONE,
1942     GL_NONE,
1943     GL_NONE,
1944     GL_NONE,
1945     GL_NONE,
1946     GL_NONE,
1947     GL_NONE,
1948     GL_NONE,
1949     GL_NONE,
1950     GL_NONE,
1951     GL_NONE,
1952     GL_NONE,
1953     GL_NONE,
1954     GL_NONE,
1955     GL_NONE,
1956     GL_NONE,
1957     GL_NONE,
1958     GL_NONE,
1959     GL_NONE,
1960     GL_NONE,
1961     GL_NONE,
1962     GL_NONE,
1963     GL_NONE,
1964     GL_NONE,
1965     GL_NONE,
1966     GL_NONE,
1967     /* GL_RGBA32F, */ GL_NONE,
1968     GL_NONE,
1969     GL_NONE,
1970     GL_NONE,
1971     GL_NONE,
1972     GL_NONE,
1973     GL_NONE,
1974     GL_NONE,
1975     GL_NONE,
1976     GL_NONE,
1977     GL_NONE,
1978     GL_NONE,
1979     GL_NONE,
1980     GL_NONE,
1981     GL_NONE,
1982     GL_NONE,
1983     GL_NONE,
1984     GL_NONE,
1985     GL_NONE,
1986     GL_NONE,
1987     GL_NONE,
1988     GL_NONE,
1989     GL_NONE,
1990     GL_NONE,
1991     GL_R32F,
1992     GL_RG32F,
1993     GL_RGB32F,
1994     GL_RGBA32F,
1995     GL_NONE,
1996     GL_NONE,
1997     GL_NONE,
1998     GL_NONE,
1999     GL_NONE,
2000     GL_NONE,
2001     GL_NONE,
2002     GL_NONE,
2003     GL_NONE,
2004     GL_NONE,
2005     GL_NONE,
2006     GL_NONE,
2007     GL_NONE,
2008     GL_NONE,
2009     GL_NONE,
2010     GL_NONE,
2011     GL_NONE,
2012     GL_NONE,
2013     GL_NONE,
2014     GL_NONE,
2015     GL_NONE,
2016     GL_NONE,
2017     GL_NONE,
2018     GL_NONE,
2019     GL_NONE,
2020     GL_NONE,
2021 };
2022 
2023 // Tells:
2024 // 1) how many rows conversion_array uses.
2025 // 2) what destination internalformat (NOT effective internalformat!)
2026 //    corresponds to each entry.
2027 // NOTE: If you need to modify this array, make sure conversion-array
2028 //       is updated accordingly!
2029 const GLenum copyTexImage2DInternalFormatOrdering[] = {GL_RGBA,
2030                                                        GL_RGB,
2031                                                        GL_LUMINANCE_ALPHA,
2032                                                        GL_LUMINANCE,
2033                                                        GL_ALPHA,
2034                                                        GL_R8,
2035                                                        GL_R8_SNORM,
2036                                                        GL_RG8,
2037                                                        GL_RG8_SNORM,
2038                                                        GL_RGB8,
2039                                                        GL_RGB8_SNORM,
2040                                                        GL_RGB565,
2041                                                        GL_RGBA4,
2042                                                        GL_RGB5_A1,
2043                                                        GL_RGBA8,
2044                                                        GL_RGBA8_SNORM,
2045                                                        GL_RGB10_A2,
2046                                                        GL_RGB10_A2UI,
2047                                                        GL_SRGB8,
2048                                                        GL_SRGB8_ALPHA8,
2049                                                        GL_R16F,
2050                                                        GL_RG16F,
2051                                                        GL_RGB16F,
2052                                                        GL_RGBA16F,
2053                                                        GL_R32F,
2054                                                        GL_RG32F,
2055                                                        GL_RGB32F,
2056                                                        GL_RGBA32F,
2057                                                        GL_R11F_G11F_B10F,
2058                                                        GL_RGB9_E5,
2059                                                        GL_R8I,
2060                                                        GL_R8UI,
2061                                                        GL_R16I,
2062                                                        GL_R16UI,
2063                                                        GL_R32I,
2064                                                        GL_R32UI,
2065                                                        GL_RG8I,
2066                                                        GL_RG8UI,
2067                                                        GL_RG16I,
2068                                                        GL_RG16UI,
2069                                                        GL_RG32I,
2070                                                        GL_RG32UI,
2071                                                        GL_RGB8I,
2072                                                        GL_RGB8UI,
2073                                                        GL_RGB16I,
2074                                                        GL_RGB16UI,
2075                                                        GL_RGB32I,
2076                                                        GL_RGB32UI,
2077                                                        GL_RGBA8I,
2078                                                        GL_RGBA8UI,
2079                                                        GL_RGBA16I,
2080                                                        GL_RGBA16UI,
2081                                                        GL_RGBA32I,
2082                                                        GL_RGBA32UI};
2083 
2084 // Ordering as per Bug 9807 table for FBO effective internalformats
2085 const GLenum fboEffectiveInternalFormatOrdering[] = {
2086     GL_R8,           GL_RG8,    GL_RGB8,  GL_RGB565, GL_RGBA4,  GL_RGB5_A1, GL_RGBA8,   GL_RGB10_A2, GL_RGB10_A2UI,
2087     GL_SRGB8_ALPHA8, GL_R8I,    GL_R8UI,  GL_R16I,   GL_R16UI,  GL_R32I,    GL_R32UI,   GL_RG8I,     GL_RG8UI,
2088     GL_RG16I,        GL_RG16UI, GL_RG32I, GL_RG32UI, GL_RGBA8I, GL_RGBA8UI, GL_RGBA16I, GL_RGBA16UI, GL_RGBA32I,
2089     GL_RGBA32UI,     GL_R16F,   GL_RG16F, GL_R32F,   GL_RG32F,  GL_RGB16F,  GL_RGBA16F, GL_RGB32F,   GL_RGBA32F,
2090 };
2091 
2092 // Tells how channels are ordered for a particular pixel.
2093 enum ChannelOrder
2094 {
2095     CHANNEL_ORDER_ABGR,
2096     CHANNEL_ORDER_BGR,
2097     CHANNEL_ORDER_BGRA,
2098     CHANNEL_ORDER_R,
2099     CHANNEL_ORDER_RG,
2100     CHANNEL_ORDER_RGB,
2101     CHANNEL_ORDER_RGBA,
2102 
2103     CHANNEL_ORDER_UNKNOWN
2104 };
2105 
2106 // Tells how many bits and what type is used for data representation
2107 // for a single pixel channel.
2108 enum ChannelDataType
2109 {
2110     CHANNEL_DATA_TYPE_NONE = 0,
2111     CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS,
2112     CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS,
2113     CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS,
2114     CHANNEL_DATA_TYPE_UNSIGNED_BYTE_1BIT,
2115     CHANNEL_DATA_TYPE_UNSIGNED_BYTE_2BITS,
2116     CHANNEL_DATA_TYPE_UNSIGNED_BYTE_4BITS,
2117     CHANNEL_DATA_TYPE_UNSIGNED_BYTE_5BITS,
2118     CHANNEL_DATA_TYPE_UNSIGNED_BYTE_6BITS,
2119     CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS,
2120     CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS,
2121     CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS,
2122     CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS,
2123     CHANNEL_DATA_TYPE_FLOAT
2124 };
2125 
2126 // Structure holding uniform locations and object IDs.
2127 // Those values are used to support non-color-renderable texture internalformat checks.
2128 struct NonRenderableInternalformatSupportObjects
2129 {
2130     GLuint comparison_result_buffer_object_id;
2131     GLuint dst_texture_pixels_buffer_object_id;
2132     GLint dst_2D_texture_uniform_location;
2133     GLint dst_Cube_texture_uniform_location;
2134     GLuint fragment_shader_object_id;
2135     GLuint program_object_id;
2136     GLuint src_texture_pixels_buffer_object_id;
2137     GLint src_2D_texture_uniform_location;
2138     GLint src_2DArray_texture_uniform_location;
2139     GLint src_3D_texture_uniform_location;
2140     GLint src_Cube_texture_uniform_location;
2141     GLuint transform_feedback_object_id;
2142     GLuint vertex_shader_object_id;
2143     GLint channels_to_compare_uniform_location;
2144     GLint samplers_to_use_uniform_location;
2145     GLuint src_texture_coordinates_buffer_object_id;
2146     GLuint dst_texture_coordinates_buffer_object_id;
2147 };
2148 
2149 // Structure describing contents of a channel of a single pixel.
2150 struct ChannelData
2151 {
2152     // Union that allows to access the data representation
2153     // in a data_type-friendly manner
2154     union
2155     {
2156         signed char signed_byte_data;
2157         signed int signed_integer_data;
2158         signed short signed_short_data;
2159         unsigned char unsigned_byte_data;
2160         unsigned int unsigned_integer_data;
2161         unsigned short unsigned_short_data;
2162         float float_data;
2163     };
2164 
2165     // Data type used for channel representation
2166     ChannelDataType data_type;
2167 };
2168 
2169 // Structure describing a single pixel.
2170 struct PixelData
2171 {
2172     // Alpha channel data descriptor
2173     ChannelData alpha;
2174     // Blue channel data descriptor
2175     ChannelData blue;
2176     // Green channel data descriptor
2177     ChannelData green;
2178     // Red channel data descriptor
2179     ChannelData red;
2180 
2181     // For source pixels:   GL internal-format used by all channels.
2182     // For destination pixels: GL format to be used for gl.readPixels()
2183     //                         operation in order to retrieve result data
2184     //                         in a matching representation.
2185     GLenum data_internalformat;
2186     // For source pixels:   GL type used by all channels.
2187     // For destination pixels: GL type to be used for gl.readPixels()
2188     //                         operation in order to retrieve result data
2189     //                         in a matching representation.
2190     GLenum data_type;
2191 };
2192 
2193 // To confirm contents of data stored in non-renderable internalformat, a special shader
2194 // is used. This type definition tells which texture() function sampler should be used
2195 // for sampling the texture data.
2196 enum DataSamplerType
2197 {
2198     DATA_SAMPLER_FLOAT,
2199     DATA_SAMPLER_INTEGER,
2200     DATA_SAMPLER_UNSIGNED_INTEGER,
2201 };
2202 
2203 // When a special shader is used to check whether the copy succeeded we need to know which
2204 // channels will have to be compared
2205 enum PixelCompareChannel
2206 {
2207     PIXEL_COMPARE_CHANNEL_R    = 0x1,
2208     PIXEL_COMPARE_CHANNEL_G    = 0x2,
2209     PIXEL_COMPARE_CHANNEL_B    = 0x4,
2210     PIXEL_COMPARE_CHANNEL_A    = 0x8,
2211     PIXEL_COMPARE_CHANNEL_RG   = PIXEL_COMPARE_CHANNEL_R | PIXEL_COMPARE_CHANNEL_G,
2212     PIXEL_COMPARE_CHANNEL_RA   = PIXEL_COMPARE_CHANNEL_R | PIXEL_COMPARE_CHANNEL_A,
2213     PIXEL_COMPARE_CHANNEL_RGB  = PIXEL_COMPARE_CHANNEL_RG | PIXEL_COMPARE_CHANNEL_B,
2214     PIXEL_COMPARE_CHANNEL_RGBA = PIXEL_COMPARE_CHANNEL_RGB | PIXEL_COMPARE_CHANNEL_A,
2215 };
2216 
2217 // Structure describing a single conversion rule.
2218 //
2219 // For more details on meaning of these fields, please refer
2220 // to doxygen of AddEntryToConversionDatabase() and similar.
2221 struct ConversionDatabaseEntry
2222 {
2223     // Reference destination data expected for bottom-left corner
2224     PixelData dst_bottomleft_corner;
2225     // Reference destination data expected for bottom-right corner
2226     PixelData dst_bottomright_corner;
2227     // Reference destination data expected for top-left corner
2228     PixelData dst_topleft_corner;
2229     // Reference destination data expected for top-right corner
2230     PixelData dst_topright_corner;
2231 
2232     // Input bottom-left corner data to be used for conversion
2233     PixelData src_bottomleft_corner;
2234     // Input bottom-right corner data to be used for conversion
2235     PixelData src_bottomright_corner;
2236     // Input top-left corner data to be used for conversion
2237     PixelData src_topleft_corner;
2238     // Input top-right corner data to be used for conversion
2239     PixelData src_topright_corner;
2240 
2241     // What are the channels that we need to compare if gl.readPixels
2242     // can't be used to read back the data
2243     PixelCompareChannel channels_to_compare;
2244 };
2245 
2246 // Structure describing contents of an opaque conversion database handle.
2247 class ConversionDatabase
2248 {
2249 public:
2250     ConversionDatabase();
2251     ~ConversionDatabase();
2252 
2253     void initializeDatabase();
2254 
2255     bool isTypeSupportedByGLReadPixels(GLenum type);
2256     bool isInternalFormatCompatibleWithType(GLenum type, GLenum internalformat);
2257     bool convertNormalizedUnsignedFixedPoint(int *src_input_rgba_bits, int *src_attachment_rgba_bits,
2258                                              int *dst_attachment_rgba_bits, int *dst_output_rgba_bits, int *src_rgba,
2259                                              int *dst_rgba);
2260 
2261     PixelData getAlpha8OESPixelData(GLenum type, unsigned char alpha);
2262     PixelData getLuminance8OESPixelData(GLenum type, unsigned char luminance);
2263     PixelData getLuminance8Alpha8OESPixelData(GLenum type, unsigned char luminance, unsigned char alpha);
2264     PixelData getR16IPixelData(int is_source_pixel, GLenum type, int red);
2265     PixelData getR16UIPixelData(int is_source_pixel, GLenum type, unsigned int red);
2266     PixelData getR32IPixelData(int is_source_pixel, GLenum type, int red);
2267     PixelData getR32UIPixelData(int is_source_pixel, GLenum type, unsigned int red);
2268     PixelData getR8IPixelData(int is_source_pixel, GLenum type, int red);
2269     PixelData getR8UIPixelData(int is_source_pixel, GLenum type, unsigned int red);
2270     PixelData getR8PixelData(int is_source_pixel, GLenum type, unsigned char red);
2271     PixelData getRG16IPixelData(int is_source_pixel, GLenum type, int red, int green);
2272     PixelData getRG16UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green);
2273     PixelData getRG32IPixelData(int is_source_pixel, GLenum type, int red, int green);
2274     PixelData getRG32UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green);
2275     PixelData getRG8IPixelData(int is_source_pixel, GLenum type, int red, int green);
2276     PixelData getRG8UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green);
2277     PixelData getRG8PixelData(int is_source_pixel, GLenum type, unsigned char red, unsigned char green);
2278     PixelData getRGB10A2PixelData(GLenum type, unsigned short red, unsigned short green, unsigned short blue,
2279                                   unsigned char alpha);
2280     PixelData getRGB10A2UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
2281                                     unsigned int blue, unsigned int alpha);
2282     PixelData getRGB16IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue);
2283     PixelData getRGB16UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
2284                                   unsigned int blue);
2285     PixelData getRGB32IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue);
2286     PixelData getRGB32UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
2287                                   unsigned int blue);
2288     PixelData getRGB5A1PixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
2289                                  unsigned int blue, unsigned int alpha);
2290     PixelData getRGB565PixelData(int is_source_pixel, GLenum type, int red, int green, int blue);
2291     PixelData getRGB8PixelData(int is_source_pixel, GLenum type, unsigned char red, unsigned char green,
2292                                unsigned char blue);
2293     PixelData getRGB8IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue);
2294     PixelData getRGB8UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
2295                                  unsigned int blue);
2296     PixelData getRGBA16IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue, int alpha);
2297     PixelData getRGBA16UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
2298                                    unsigned int blue, unsigned int alpha);
2299     PixelData getRGBA32IPixelData(GLenum type, int red, int green, int blue, int alpha);
2300 
2301     PixelData getRGBA32UIPixelData(GLenum type, unsigned int red, unsigned int green, unsigned int blue,
2302                                    unsigned int alpha);
2303     PixelData getRGBA8IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue, int alpha);
2304     PixelData getRGBA8UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
2305                                   unsigned int blue, unsigned int alpha);
2306     PixelData getRGBA4PixelData(int is_source_pixel, GLenum type, unsigned char red, unsigned char green,
2307                                 unsigned char blue, unsigned char alpha);
2308     PixelData getRGBA8PixelData(GLenum type, unsigned char red, unsigned char green, unsigned char blue,
2309                                 unsigned char alpha);
2310     PixelData getSRGB8Alpha8PixelData(GLenum type, unsigned char red, unsigned char green, unsigned char blue,
2311                                       unsigned char alpha);
2312     PixelData getSRGB8PixelData(int is_source_pixel, GLenum type, unsigned char red, unsigned char green,
2313                                 unsigned char blue);
2314     PixelData getR16FPixelData(int is_source_pixel, GLenum type, float red);
2315     PixelData getR32FPixelData(int is_source_pixel, GLenum type, float red);
2316     PixelData getRG16FPixelData(int is_source_pixel, GLenum type, float red, float green);
2317     PixelData getRG32FPixelData(int is_source_pixel, GLenum type, float red, float green);
2318     PixelData getRGB16FPixelData(int is_source_pixel, GLenum type, float red, float green, float blue);
2319     PixelData getRGB32FPixelData(int is_source_pixel, GLenum type, float red, float green, float blue);
2320     PixelData getRGBA16FPixelData(GLenum type, float red, float green, float blue, float alpha);
2321     PixelData getRGBA32FPixelData(GLenum type, float red, float green, float blue, float alpha);
2322 
2323 protected:
2324     void addEntryToConversionDatabase(PixelData src_topleft, PixelData dst_topleft, PixelData src_topright,
2325                                       PixelData dst_topright, PixelData src_bottomleft, PixelData dst_bottomleft,
2326                                       PixelData src_bottomright, PixelData dst_bottomright,
2327                                       PixelCompareChannel channels_to_compare);
2328     void configureConversionDatabase();
2329 
2330 public:
2331     // An array of _conversion_database_entry instances,
2332     // storing all known conversion rules.
2333     std::vector<ConversionDatabaseEntry> entries;
2334 
2335     // Amount of entries allocated in the "entries" array so far.
2336     unsigned int n_entries_allocated;
2337 
2338     // Amount of entries added to the "entries" array so far.
2339     unsigned int n_entries_added;
2340 };
2341 
ConversionDatabase()2342 ConversionDatabase::ConversionDatabase() : n_entries_allocated(0), n_entries_added(0)
2343 {
2344 }
2345 
~ConversionDatabase()2346 ConversionDatabase::~ConversionDatabase()
2347 {
2348 }
2349 
2350 /** Initializes database instance. The database will be filled by the
2351  *  function with all available conversion rules, so it is a mistake to call
2352  *  ConfigureConversionDatabase() function for a handle reported by this function.
2353  *
2354  *  The handle should be released with ReleaseConversionDatabase() when no longer
2355  *  needed.
2356  *
2357  *  @return Handle to the newly created conversion database.
2358  **/
initializeDatabase()2359 void ConversionDatabase::initializeDatabase()
2360 {
2361     // Return when database was initialized earlier.
2362     if (!entries.empty())
2363         return;
2364 
2365     entries.resize(N_START_CONVERSION_DATABASE_ENTRIES);
2366     n_entries_allocated = N_START_CONVERSION_DATABASE_ENTRIES;
2367     n_entries_added     = 0;
2368 
2369     if (entries.empty())
2370         TCU_FAIL("Out of memory while pre-allocating space for conversion database entries");
2371 
2372     deMemset(&entries[0], DE_NULL, N_START_CONVERSION_DATABASE_ENTRIES * sizeof(ConversionDatabaseEntry));
2373 
2374     // Add all predefined entries that the test implementation is aware of
2375     configureConversionDatabase();
2376 }
2377 
2378 /** Tells whether @param type can be used for a gl.readPixels() call.
2379  *
2380  *  @param type GL type to consider.
2381  *
2382  *  @return true  if the type should be accepted by a gl.readPixels() call,
2383  *          false otherwise.
2384  */
isTypeSupportedByGLReadPixels(GLenum type)2385 bool ConversionDatabase::isTypeSupportedByGLReadPixels(GLenum type)
2386 {
2387     return (type == GL_INT) || (type == GL_UNSIGNED_BYTE) || (type == GL_UNSIGNED_INT) || (type == GL_FLOAT) ||
2388            (type == GL_HALF_FLOAT) || (type == GL_UNSIGNED_INT_2_10_10_10_REV);
2389 }
2390 
2391 /** Tells whether @param type can be used with @param internalformat internal format.
2392  *
2393  *  @param type           GLES type to consider.
2394  *  @param internalformat GLES internal format to consider.
2395  *
2396  *  @return true if the type is compatible with specific internal format, false otherwise.
2397  **/
isInternalFormatCompatibleWithType(GLenum type,GLenum internalformat)2398 bool ConversionDatabase::isInternalFormatCompatibleWithType(GLenum type, GLenum internalformat)
2399 {
2400     bool result = false;
2401 
2402     switch (type)
2403     {
2404     case GL_INT:
2405     {
2406         result = (internalformat == GL_R8I) || (internalformat == GL_R16I) || (internalformat == GL_R32I) ||
2407                  (internalformat == GL_RG8I) || (internalformat == GL_RG16I) || (internalformat == GL_RG32I) ||
2408                  (internalformat == GL_RGB8I) || (internalformat == GL_RGB16I) || (internalformat == GL_RGB32I) ||
2409                  (internalformat == GL_RGBA8I) || (internalformat == GL_RGBA16I) || (internalformat == GL_RGBA32I);
2410 
2411         break;
2412     }
2413 
2414     case GL_UNSIGNED_BYTE:
2415     {
2416         result = (internalformat == GL_RGB) || (internalformat == GL_RGBA) || (internalformat == GL_LUMINANCE_ALPHA) ||
2417                  (internalformat == GL_LUMINANCE) || (internalformat == GL_LUMINANCE8_OES) ||
2418                  (internalformat == GL_LUMINANCE8_ALPHA8_OES) || (internalformat == GL_ALPHA) ||
2419                  (internalformat == GL_ALPHA8_OES) || (internalformat == GL_R8) || (internalformat == GL_R8_SNORM) ||
2420                  (internalformat == GL_RG8) || (internalformat == GL_RG8_SNORM) || (internalformat == GL_RGB8) ||
2421                  (internalformat == GL_SRGB8) || (internalformat == GL_RGB565) || (internalformat == GL_RGB8_SNORM) ||
2422                  (internalformat == GL_RGBA8) || (internalformat == GL_SRGB8_ALPHA8) ||
2423                  (internalformat == GL_RGBA8_SNORM) || (internalformat == GL_RGB5_A1) || (internalformat == GL_RGBA4);
2424 
2425         break;
2426     }
2427 
2428     case GL_UNSIGNED_INT:
2429     {
2430         result = (internalformat == GL_R8UI) || (internalformat == GL_R16UI) || (internalformat == GL_R32UI) ||
2431                  (internalformat == GL_RG8UI) || (internalformat == GL_RG16UI) || (internalformat == GL_RG32UI) ||
2432                  (internalformat == GL_RGB8UI) || (internalformat == GL_RGB10_A2UI) || (internalformat == GL_RGB16UI) ||
2433                  (internalformat == GL_RGB32UI) || (internalformat == GL_RGBA8UI) || (internalformat == GL_RGBA16UI) ||
2434                  (internalformat == GL_RGBA32UI);
2435 
2436         break;
2437     }
2438 
2439     case GL_UNSIGNED_INT_2_10_10_10_REV:
2440     {
2441         result = (internalformat == GL_RGB10_A2) || (internalformat == GL_RGB10_A2UI);
2442 
2443         break;
2444     }
2445 
2446     case GL_FLOAT:
2447     {
2448         result = (internalformat == GL_RGB) || (internalformat == GL_RGBA) || (internalformat == GL_R32F) ||
2449                  (internalformat == GL_RG32F) || (internalformat == GL_RGB32F) || (internalformat == GL_RGBA32F);
2450 
2451         break;
2452     }
2453 
2454     case GL_HALF_FLOAT:
2455     {
2456         result = (internalformat == GL_RGB) || (internalformat == GL_RGBA) || (internalformat == GL_R16F) ||
2457                  (internalformat == GL_RG16F) || (internalformat == GL_RGB16F) || (internalformat == GL_RGBA16F);
2458 
2459         break;
2460     }
2461 
2462     default:
2463     {
2464         TCU_FAIL("Unsupported type");
2465     }
2466     }
2467 
2468     return result;
2469 }
2470 
2471 /** Converts normalized unsigned fixed-point RGBA pixel representations
2472  *  from one resolution to another, simulating the result that one would
2473  *  get if glCopyTexImage2D() call was used for a single pixel, read
2474  *  afterward with a gl.readPixels() call.
2475  *
2476  *  @param src_input_rgba_bits      Pointer to an array storing 4 integers, representing
2477  *                                  amount of bits per channel, as used by input data,
2478  *                                  that will be fed to a GL object using gl.texImage2D()
2479  *                                  call or similar. Cannot be NULL.
2480  *  @param src_attachment_rgba_bits Pointer to an array storing 4 integers, representing
2481  *                                  amount of bits per channel, as used by data storage
2482  *                                  of an object attached to read buffer. Cannot be NULL.
2483  *  @param dst_attachment_rgba_bits Pointer to an array storing 4 integers, representing
2484  *                                  amount of bits per channel, as used by data storage
2485  *                                  of a texture object that glCopyTexImage2D() call will
2486  *                                  initialize. Cannot be NULL.
2487  *  @param dst_output_rgba_bits     Pointer to an array storing 4 integers, representing
2488  *                                  amount of bits per channel, as requested by the user
2489  *                                  using the gl.readPixels() call. Cannot be NULL.
2490  *  @param src_rgba                 Pointer to an array storing 4 values representing
2491  *                                  RGBA channel. It is assumed the values do not exceed
2492  *                                  allowed precision, described by @param src_input_rgba_bits.
2493  *                                  Cannot be NULL.
2494  *  @param dst_rgba                 Deref will be used to store result of the conversion.
2495  *                                  Cannot be NULL.
2496  *
2497  *  @return 1 if successful, 0 otherwise.
2498  *  */
convertNormalizedUnsignedFixedPoint(int * src_input_rgba_bits,int * src_attachment_rgba_bits,int * dst_attachment_rgba_bits,int * dst_output_rgba_bits,int * src_rgba,int * dst_rgba)2499 bool ConversionDatabase::convertNormalizedUnsignedFixedPoint(int *src_input_rgba_bits, int *src_attachment_rgba_bits,
2500                                                              int *dst_attachment_rgba_bits, int *dst_output_rgba_bits,
2501                                                              int *src_rgba, int *dst_rgba)
2502 {
2503     float a_f32                  = 0.0f;
2504     float b_f32                  = 0.0f;
2505     float dst_rgba_f[4]          = {0.0f};
2506     float g_f32                  = 0.0f;
2507     float r_f32                  = 0.0f;
2508     int src_rgba_intermediate[4] = {src_rgba[0], src_rgba[1], src_rgba[2], src_rgba[3]};
2509 
2510     // Reduce or crank up precision before casting to floats
2511     int bit_diffs_src_intermediate[] = {abs(src_input_rgba_bits[0] - src_attachment_rgba_bits[0]),
2512                                         abs(src_input_rgba_bits[1] - src_attachment_rgba_bits[1]),
2513                                         abs(src_input_rgba_bits[2] - src_attachment_rgba_bits[2]),
2514                                         abs(src_input_rgba_bits[3] - src_attachment_rgba_bits[3])};
2515 
2516     for (unsigned int n = 0; n < sizeof(bit_diffs_src_intermediate) / sizeof(bit_diffs_src_intermediate[0]); ++n)
2517     {
2518         if (src_input_rgba_bits[n] != 0)
2519         {
2520             float tmp = ((float)src_rgba_intermediate[n]) / ((1 << src_input_rgba_bits[n]) - 1);
2521             if (tmp > 1.0f)
2522                 tmp = 1.0f;
2523             tmp *= (float)((1 << src_attachment_rgba_bits[n]) - 1);
2524             src_rgba_intermediate[n] = (int)(0.5 + tmp);
2525         }
2526     }
2527 
2528     // The following equations correspond to equation 2.1 from ES spec 3.0.2
2529     if (src_attachment_rgba_bits[0] != 0)
2530         r_f32 = ((float)src_rgba_intermediate[0]) / (float)((1 << src_attachment_rgba_bits[0]) - 1);
2531     if (src_attachment_rgba_bits[1] != 0)
2532         g_f32 = ((float)src_rgba_intermediate[1]) / (float)((1 << src_attachment_rgba_bits[1]) - 1);
2533     if (src_attachment_rgba_bits[2] != 0)
2534         b_f32 = ((float)src_rgba_intermediate[2]) / (float)((1 << src_attachment_rgba_bits[2]) - 1);
2535     if (src_attachment_rgba_bits[3] != 0)
2536         a_f32 = ((float)src_rgba_intermediate[3]) / (float)((1 << src_attachment_rgba_bits[3]) - 1);
2537 
2538     // Clamp to <0, 1>. Since we're dealing with unsigned ints on input, there's
2539     // no way we could be lower than 0.
2540     if (r_f32 > 1.0f)
2541         r_f32 = 1.0f;
2542     if (g_f32 > 1.0f)
2543         g_f32 = 1.0f;
2544     if (b_f32 > 1.0f)
2545         b_f32 = 1.0f;
2546     if (a_f32 > 1.0f)
2547         a_f32 = 1.0f;
2548 
2549     // The following equations are taken from table 4.5 & equation 2.3,
2550     // ES spec 3.0.2
2551     dst_rgba_f[0] = (r_f32 * (float)((1 << dst_attachment_rgba_bits[0]) - 1));
2552     dst_rgba_f[1] = (g_f32 * (float)((1 << dst_attachment_rgba_bits[1]) - 1));
2553     dst_rgba_f[2] = (b_f32 * (float)((1 << dst_attachment_rgba_bits[2]) - 1));
2554     dst_rgba_f[3] = (a_f32 * (float)((1 << dst_attachment_rgba_bits[3]) - 1));
2555 
2556     // As per spec:
2557     //
2558     // The conversion from a floating-point value f to the corresponding
2559     // unsigned normalized fixed-point value c is defined by first clamping
2560     // f to the range [0,1], then computing
2561     //
2562     // f' = convert_float_uint(f * (2^b-1), b) [2.3]
2563     //
2564     // where convert_float_uint(r,b) returns one of the two unsigned binary
2565     // integer values with exactly b bits which are closest to the floating-point
2566     // value r (where *rounding to nearest is preferred*)
2567     //
2568     // C casting truncates the remainder, so if dst_rgba_f[x] is larger than or
2569     // equal to 0.5, we need to take a ceiling of the value.
2570     for (unsigned int n = 0; n < 4 /* channels */; ++n)
2571     {
2572         if (deFloatMod(dst_rgba_f[n], 1.0f) >= 0.5f)
2573             dst_rgba_f[n] = deFloatCeil(dst_rgba_f[n]);
2574     }
2575 
2576     // Expand the data or reduce its precision, depending on the type requested by the caller.
2577     dst_rgba[0] = ((unsigned int)dst_rgba_f[0]);
2578     dst_rgba[1] = ((unsigned int)dst_rgba_f[1]);
2579     dst_rgba[2] = ((unsigned int)dst_rgba_f[2]);
2580     dst_rgba[3] = ((unsigned int)dst_rgba_f[3]);
2581 
2582     for (unsigned int n = 0; n < 4 /* channels */; ++n)
2583     {
2584         if (dst_attachment_rgba_bits[n] != 0)
2585         {
2586             float tmp = ((float)dst_rgba[n]) / ((1 << dst_attachment_rgba_bits[n]) - 1);
2587             if (tmp > 1.0f)
2588                 tmp = 1.0f;
2589             tmp *= (float)((1 << dst_output_rgba_bits[n]) - 1);
2590             dst_rgba[n] = (int)(0.5 + tmp);
2591         }
2592     }
2593 
2594     return true;
2595 }
2596 
2597 /** Retrieves a PixelData instance describing a single pixel stored in
2598  *  GL_ALPHA8 internal format.
2599  *
2600  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2601  *                         0 otherwise.
2602  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_BYTE.
2603  *  @param red             Value for red channel.
2604  *
2605  *  @return Filled PixelData instance.
2606  **/
getAlpha8OESPixelData(GLenum type,unsigned char alpha)2607 PixelData ConversionDatabase::getAlpha8OESPixelData(GLenum type, unsigned char alpha)
2608 {
2609     PixelData result;
2610 
2611     // Quick checks
2612     DE_ASSERT(type == GL_UNSIGNED_BYTE);
2613 
2614     // Carry on
2615     deMemset(&result, 0, sizeof(result));
2616 
2617     result.alpha.unsigned_byte_data = alpha;
2618     result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2619     result.blue.data_type           = CHANNEL_DATA_TYPE_NONE;
2620     result.green.data_type          = CHANNEL_DATA_TYPE_NONE;
2621     result.red.data_type            = CHANNEL_DATA_TYPE_NONE;
2622     result.data_internalformat      = GL_ALPHA8_OES;
2623     result.data_type                = type;
2624 
2625     return result;
2626 }
2627 
2628 /** Retrieves a PixelData instance describing a single pixel stored in
2629  *  GL_LUMINANCE8 internal format.
2630  *
2631  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2632  *                         0 otherwise.
2633  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_BYTE.
2634  *  @param luminance       Luminance value. Will get cloned to blue/green/red channels.
2635  *
2636  *  @return Filled PixelData instance.
2637  **/
getLuminance8OESPixelData(GLenum type,unsigned char luminance)2638 PixelData ConversionDatabase::getLuminance8OESPixelData(GLenum type, unsigned char luminance)
2639 {
2640     PixelData result;
2641 
2642     /* Quick checks */
2643     DE_ASSERT(type == GL_UNSIGNED_BYTE);
2644 
2645     /* Carry on */
2646     deMemset(&result, 0, sizeof(result));
2647 
2648     result.alpha.unsigned_byte_data = 255;
2649     result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2650     result.blue.unsigned_byte_data  = luminance;
2651     result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2652     result.green.unsigned_byte_data = luminance;
2653     result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2654     result.red.unsigned_byte_data   = luminance;
2655     result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2656     result.data_internalformat      = GL_LUMINANCE8_OES;
2657     result.data_type                = type;
2658 
2659     return result;
2660 }
2661 
2662 /** Retrieves a PixelData instance describing a single pixel stored in
2663  *  GL_LUMINANCE8_ALPHA8 internal format.
2664  *
2665  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2666  *                         0 otherwise.
2667  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_BYTE.
2668  *  @param luminance       Luminance value. Will be cloned to blue/green/red channels.
2669  *  @param alpha           Alpha channel value.
2670  *
2671  *  @return Filled PixelData instance.
2672  **/
getLuminance8Alpha8OESPixelData(GLenum type,unsigned char luminance,unsigned char alpha)2673 PixelData ConversionDatabase::getLuminance8Alpha8OESPixelData(GLenum type, unsigned char luminance, unsigned char alpha)
2674 {
2675     PixelData result;
2676 
2677     /* Quick checks */
2678     DE_ASSERT(type == GL_UNSIGNED_BYTE);
2679 
2680     /* Carry on */
2681     deMemset(&result, 0, sizeof(result));
2682 
2683     result.alpha.unsigned_byte_data = alpha;
2684     result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2685     result.blue.unsigned_byte_data  = luminance;
2686     result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2687     result.green.unsigned_byte_data = luminance;
2688     result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2689     result.red.unsigned_byte_data   = luminance;
2690     result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2691     result.data_internalformat      = GL_LUMINANCE8_ALPHA8_OES;
2692     result.data_type                = type;
2693 
2694     return result;
2695 }
2696 
2697 /** Retrieves a PixelData instance describing a single pixel stored in
2698  *  GL_R16I internal format.
2699  *
2700  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2701  *                         0 otherwise.
2702  *  @param type            GLES type the pixel uses. Must be:
2703  *                         1) GL_SHORT for source pixels.
2704  *                         2) GL_INT for destination pixels.
2705  *  @param red             Value for red channel.
2706  *
2707  *  @return Filled PixelData instance.
2708  **/
getR16IPixelData(int is_source_pixel,GLenum type,int red)2709 PixelData ConversionDatabase::getR16IPixelData(int is_source_pixel, GLenum type, int red)
2710 {
2711     PixelData result;
2712 
2713     /* Quick checks */
2714     if (is_source_pixel)
2715     {
2716         DE_ASSERT(type == GL_SHORT);
2717     } /* if (is_source_pixel) */
2718     else
2719     {
2720         DE_ASSERT(type == GL_INT);
2721     }
2722 
2723     /* Carry on */
2724     deMemset(&result, 0, sizeof(result));
2725 
2726     result.blue.data_type  = CHANNEL_DATA_TYPE_NONE;
2727     result.green.data_type = CHANNEL_DATA_TYPE_NONE;
2728 
2729     if (is_source_pixel)
2730     {
2731         result.red.signed_short_data = red;
2732         result.red.data_type         = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
2733     } /* if (is_source_pixel) */
2734     else
2735     {
2736         result.alpha.signed_integer_data = 1;
2737         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
2738         result.red.signed_integer_data   = red;
2739         result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
2740     }
2741 
2742     result.data_internalformat = GL_R16I;
2743     result.data_type           = type;
2744 
2745     return result;
2746 }
2747 
2748 /** Retrieves a PixelData instance describing a single pixel stored in
2749  *  GL_R16UI internal format.
2750  *
2751  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2752  *                         0 otherwise.
2753  *  @param type            GLES type the pixel uses. Must be:
2754  *                         1) GL_UNSIGNED_SHORT for source pixels.
2755  *                         2) GL_UNSIGNED_INT for destination pixels.
2756  *  @param red             Value for red channel.
2757  *
2758  *  @return Filled PixelData instance.
2759  **/
getR16UIPixelData(int is_source_pixel,GLenum type,unsigned int red)2760 PixelData ConversionDatabase::getR16UIPixelData(int is_source_pixel, GLenum type, unsigned int red)
2761 {
2762     PixelData result;
2763 
2764     /* Quick checks */
2765     if (is_source_pixel)
2766     {
2767         DE_ASSERT(type == GL_UNSIGNED_SHORT);
2768     } /* if (is_source_pixels) */
2769     else
2770     {
2771         DE_ASSERT(type == GL_UNSIGNED_INT);
2772     }
2773 
2774     deMemset(&result, 0, sizeof(result));
2775 
2776     result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
2777     result.blue.data_type  = CHANNEL_DATA_TYPE_NONE;
2778     result.green.data_type = CHANNEL_DATA_TYPE_NONE;
2779 
2780     if (is_source_pixel)
2781     {
2782         result.red.unsigned_short_data = red;
2783         result.red.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
2784     } /* if (is_source_pixel) */
2785     else
2786     {
2787         result.alpha.unsigned_integer_data = 1;
2788         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
2789         result.red.unsigned_integer_data   = red;
2790         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
2791     }
2792 
2793     result.data_internalformat = GL_R16UI;
2794     result.data_type           = type;
2795 
2796     return result;
2797 }
2798 
2799 /** Retrieves a PixelData instance describing a single pixel stored in
2800  *  GL_R32I internal format.
2801  *
2802  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2803  *                         0 otherwise.
2804  *  @param type            GLES type the pixel uses. Must be GL_INT.
2805  *  @param red             Value for red channel.
2806  *
2807  *  @return Filled PixelData instance.
2808  **/
getR32IPixelData(int is_source_pixel,GLenum type,int red)2809 PixelData ConversionDatabase::getR32IPixelData(int is_source_pixel, GLenum type, int red)
2810 {
2811     PixelData result;
2812 
2813     DE_ASSERT(type == GL_INT);
2814 
2815     deMemset(&result, 0, sizeof(result));
2816 
2817     if (!is_source_pixel)
2818     {
2819         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
2820         result.alpha.signed_integer_data = 1;
2821     }
2822     else
2823     {
2824         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
2825     }
2826 
2827     result.blue.data_type          = CHANNEL_DATA_TYPE_NONE;
2828     result.green.data_type         = CHANNEL_DATA_TYPE_NONE;
2829     result.red.signed_integer_data = red;
2830     result.red.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
2831     result.data_internalformat     = GL_R32I;
2832     result.data_type               = type;
2833 
2834     return result;
2835 }
2836 
2837 /** Retrieves a PixelData instance describing a single pixel stored in
2838  *  GL_R32UI internal format.
2839  *
2840  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2841  *                         0 otherwise.
2842  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_INT.
2843  *  @param red             Value for red channel.
2844  *
2845  *  @return Filled PixelData instance.
2846  **/
getR32UIPixelData(int is_source_pixel,GLenum type,unsigned int red)2847 PixelData ConversionDatabase::getR32UIPixelData(int is_source_pixel, GLenum type, unsigned int red)
2848 {
2849     PixelData result;
2850 
2851     DE_ASSERT(type == GL_UNSIGNED_INT);
2852 
2853     deMemset(&result, 0, sizeof(result));
2854 
2855     if (!is_source_pixel)
2856     {
2857         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
2858         result.alpha.unsigned_integer_data = 1;
2859     } /* if (!is_source_pixel) */
2860     else
2861     {
2862         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
2863     }
2864 
2865     result.blue.data_type            = CHANNEL_DATA_TYPE_NONE;
2866     result.green.data_type           = CHANNEL_DATA_TYPE_NONE;
2867     result.red.unsigned_integer_data = red;
2868     result.red.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
2869     result.data_internalformat       = GL_R32UI;
2870     result.data_type                 = type;
2871 
2872     return result;
2873 }
2874 
2875 /** Retrieves a PixelData instance describing a single pixel stored in
2876  *  GL_R8I internal format.
2877  *
2878  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2879  *                         0 otherwise.
2880  *  @param type            GLES type the pixel uses. Must be:
2881  *                         1) GL_BYTE for source pixels.
2882  *                         2) GL_INT for destination pixels.
2883  *  @param red             Value for red channel.
2884  *
2885  *  @return Filled PixelData instance.
2886  **/
getR8IPixelData(int is_source_pixel,GLenum type,int red)2887 PixelData ConversionDatabase::getR8IPixelData(int is_source_pixel, GLenum type, int red)
2888 {
2889     PixelData result;
2890 
2891     // Quick checks
2892     if (is_source_pixel)
2893         DE_ASSERT(type == GL_BYTE);
2894     else
2895         DE_ASSERT(type == GL_INT);
2896 
2897     // Carry on
2898     deMemset(&result, 0, sizeof(result));
2899 
2900     result.blue.data_type  = CHANNEL_DATA_TYPE_NONE;
2901     result.green.data_type = CHANNEL_DATA_TYPE_NONE;
2902 
2903     if (is_source_pixel)
2904     {
2905         result.alpha.data_type      = CHANNEL_DATA_TYPE_NONE;
2906         result.red.signed_byte_data = red;
2907         result.red.data_type        = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
2908     }
2909     else
2910     {
2911         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
2912         result.alpha.signed_integer_data = 1;
2913         result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
2914         result.red.signed_integer_data   = red;
2915     }
2916 
2917     result.data_internalformat = GL_R8I;
2918     result.data_type           = type;
2919 
2920     return result;
2921 }
2922 
2923 /** Retrieves a PixelData instance describing a single pixel stored in
2924  *  GL_R8UI internal format.
2925  *
2926  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2927  *                         0 otherwise.
2928  *  @param type            GLES type the pixel uses. Must be:
2929  *                         1) GL_UNSIGNED_BYTE for source pixels.
2930  *                         2) GL_UNSIGNED_INT for destination pixels.
2931  *  @param red             Value for red channel.
2932  *
2933  *  @return Filled PixelData instance.
2934  **/
getR8UIPixelData(int is_source_pixel,GLenum type,unsigned int red)2935 PixelData ConversionDatabase::getR8UIPixelData(int is_source_pixel, GLenum type, unsigned int red)
2936 {
2937     PixelData result;
2938 
2939     /* Quick checks */
2940     if (is_source_pixel)
2941         DE_ASSERT(type == GL_UNSIGNED_BYTE);
2942     else
2943         DE_ASSERT(type == GL_UNSIGNED_INT);
2944 
2945     deMemset(&result, 0, sizeof(result));
2946 
2947     result.blue.data_type  = CHANNEL_DATA_TYPE_NONE;
2948     result.green.data_type = CHANNEL_DATA_TYPE_NONE;
2949 
2950     if (is_source_pixel)
2951     {
2952         result.alpha.data_type        = CHANNEL_DATA_TYPE_NONE;
2953         result.red.unsigned_byte_data = red;
2954         result.red.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2955     }
2956     else
2957     {
2958         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
2959         result.alpha.unsigned_integer_data = 1;
2960         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
2961         result.red.unsigned_integer_data   = red;
2962     }
2963 
2964     result.data_internalformat = GL_R8UI;
2965     result.data_type           = type;
2966 
2967     return result;
2968 }
2969 
2970 /** Retrieves a PixelData instance describing a single pixel stored in
2971  *  GL_R8 internal format.
2972  *
2973  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
2974  *                         0 otherwise.
2975  *  @param type            GLES type the pixel uses. Must beGL_UNSIGNED_BYTE.
2976  *  @param red             Value for red channel.
2977  *
2978  *  @return Filled PixelData instance.
2979  **/
getR8PixelData(int is_source_pixel,GLenum type,unsigned char red)2980 PixelData ConversionDatabase::getR8PixelData(int is_source_pixel, GLenum type, unsigned char red)
2981 {
2982     PixelData result;
2983 
2984     DE_ASSERT(type == GL_UNSIGNED_BYTE);
2985     deMemset(&result, 0, sizeof(result));
2986 
2987     if (is_source_pixel)
2988     {
2989         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
2990     }
2991     else
2992     {
2993         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
2994         result.alpha.unsigned_byte_data = 255;
2995     }
2996 
2997     result.blue.data_type         = CHANNEL_DATA_TYPE_NONE;
2998     result.green.data_type        = CHANNEL_DATA_TYPE_NONE;
2999     result.red.unsigned_byte_data = red;
3000     result.red.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3001     result.data_internalformat    = GL_R8;
3002     result.data_type              = type;
3003 
3004     return result;
3005 }
3006 
3007 /** Retrieves a PixelData instance describing a single pixel stored in
3008  *  GL_RG16I internal format.
3009  *
3010  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3011  *                         0 otherwise.
3012  *  @param type            GLES type the pixel uses. Must be:
3013  *                         1) GL_SHORT for source pixels.
3014  *                         2) GL_INT for destination pixels.
3015  *  @param red             Value for red channel.
3016  *  @param green           Value for green channel.
3017  *
3018  *  @return Filled PixelData instance.
3019  **/
getRG16IPixelData(int is_source_pixel,GLenum type,int red,int green)3020 PixelData ConversionDatabase::getRG16IPixelData(int is_source_pixel, GLenum type, int red, int green)
3021 {
3022     PixelData result;
3023 
3024     if (is_source_pixel)
3025     {
3026         DE_ASSERT(type == GL_SHORT);
3027     }
3028     else
3029     {
3030         DE_ASSERT(type == GL_INT);
3031     }
3032 
3033     deMemset(&result, 0, sizeof(result));
3034 
3035     result.blue.data_type = CHANNEL_DATA_TYPE_NONE;
3036 
3037     if (is_source_pixel)
3038     {
3039         result.alpha.data_type         = CHANNEL_DATA_TYPE_NONE;
3040         result.green.signed_short_data = green;
3041         result.green.data_type         = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3042         result.red.signed_short_data   = red;
3043         result.red.data_type           = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3044     }
3045     else
3046     {
3047         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3048         result.alpha.signed_integer_data = 1;
3049         result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3050         result.green.signed_integer_data = green;
3051         result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3052         result.red.signed_integer_data   = red;
3053     }
3054 
3055     result.data_internalformat = GL_RG16I;
3056     result.data_type           = type;
3057 
3058     return result;
3059 }
3060 
3061 /** Retrieves a PixelData instance describing a single pixel stored in
3062  *  GL_RG16UI internal format.
3063  *
3064  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3065  *                         0 otherwise.
3066  *  @param type            GLES type the pixel uses. Must be:
3067  *                         1) GL_UNSIGNED_SHORT for source pixels.
3068  *                         2) GL_UNSIGNED_INT for destination pixels.
3069  *  @param red             Value for red channel.
3070  *  @param green           Value for green channel.
3071  *
3072  *  @return Filled PixelData instance.
3073  **/
getRG16UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green)3074 PixelData ConversionDatabase::getRG16UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green)
3075 {
3076     PixelData result;
3077 
3078     if (is_source_pixel)
3079         DE_ASSERT(type == GL_UNSIGNED_SHORT);
3080     else
3081         DE_ASSERT(type == GL_UNSIGNED_INT);
3082 
3083     deMemset(&result, 0, sizeof(result));
3084 
3085     result.blue.data_type = CHANNEL_DATA_TYPE_NONE;
3086 
3087     if (is_source_pixel)
3088     {
3089         result.alpha.data_type         = CHANNEL_DATA_TYPE_NONE;
3090         result.green.signed_short_data = green;
3091         result.green.data_type         = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
3092         result.red.signed_short_data   = red;
3093         result.red.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
3094     }
3095     else
3096     {
3097         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3098         result.alpha.unsigned_integer_data = 1;
3099         result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3100         result.green.unsigned_integer_data = green;
3101         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3102         result.red.unsigned_integer_data   = red;
3103     }
3104 
3105     result.data_internalformat = GL_RG16UI;
3106     result.data_type           = type;
3107 
3108     return result;
3109 }
3110 
3111 /** Retrieves a PixelData instance describing a single pixel stored in
3112  *  GL_RG32I internal format.
3113  *
3114  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3115  *                         0 otherwise.
3116  *  @param type            GLES type the pixel uses. Must be GL_INT.
3117  *  @param red             Value for red channel.
3118  *  @param green           Value for green channel.
3119  *
3120  *  @return Filled PixelData instance.
3121  **/
getRG32IPixelData(int is_source_pixel,GLenum type,int red,int green)3122 PixelData ConversionDatabase::getRG32IPixelData(int is_source_pixel, GLenum type, int red, int green)
3123 {
3124     PixelData result;
3125 
3126     DE_ASSERT(type == GL_INT);
3127 
3128     deMemset(&result, 0, sizeof(result));
3129 
3130     if (is_source_pixel)
3131         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
3132     else
3133     {
3134         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3135         result.alpha.signed_integer_data = 1;
3136     }
3137 
3138     result.blue.data_type            = CHANNEL_DATA_TYPE_NONE;
3139     result.green.signed_integer_data = green;
3140     result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3141     result.red.signed_integer_data   = red;
3142     result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3143     result.data_internalformat       = GL_RG32I;
3144     result.data_type                 = type;
3145 
3146     return result;
3147 }
3148 
3149 /** Retrieves a PixelData instance describing a single pixel stored in
3150  *  GL_RG32UI internal format.
3151  *
3152  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3153  *                         0 otherwise.
3154  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_INT.
3155  *  @param red             Value for red channel.
3156  *  @param green           Value for green channel.
3157  *
3158  *  @return Filled PixelData instance.
3159  **/
getRG32UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green)3160 PixelData ConversionDatabase::getRG32UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green)
3161 {
3162     PixelData result;
3163 
3164     DE_ASSERT(type == GL_UNSIGNED_INT);
3165 
3166     deMemset(&result, 0, sizeof(result));
3167 
3168     if (is_source_pixel)
3169     {
3170         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
3171     }
3172     else
3173     {
3174         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3175         result.alpha.unsigned_integer_data = 1;
3176     }
3177 
3178     result.blue.data_type              = CHANNEL_DATA_TYPE_NONE;
3179     result.green.unsigned_integer_data = green;
3180     result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3181     result.red.unsigned_integer_data   = red;
3182     result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3183     result.data_internalformat         = GL_RG32UI;
3184     result.data_type                   = type;
3185 
3186     return result;
3187 }
3188 
3189 /** Retrieves a PixelData instance describing a single pixel stored in
3190  *  GL_RG8I internal format.
3191  *
3192  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3193  *                         0 otherwise.
3194  *  @param type            GLES type the pixel uses. Must be:
3195  *                         1) GL_BYTE for source pixels.
3196  *                         2) GL_INT for destination pixels.
3197  *  @param red             Value for red channel.
3198  *  @param green           Value for green channel.
3199  *
3200  *  @return Filled PixelData instance.
3201  **/
getRG8IPixelData(int is_source_pixel,GLenum type,int red,int green)3202 PixelData ConversionDatabase::getRG8IPixelData(int is_source_pixel, GLenum type, int red, int green)
3203 {
3204     PixelData result;
3205 
3206     if (is_source_pixel)
3207         DE_ASSERT(type == GL_BYTE);
3208     else
3209         DE_ASSERT(type == GL_INT);
3210 
3211     deMemset(&result, 0, sizeof(result));
3212 
3213     result.blue.data_type = CHANNEL_DATA_TYPE_NONE;
3214 
3215     if (is_source_pixel)
3216     {
3217         result.alpha.data_type        = CHANNEL_DATA_TYPE_NONE;
3218         result.green.signed_byte_data = green;
3219         result.green.data_type        = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
3220         result.red.signed_byte_data   = red;
3221         result.red.data_type          = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
3222     } /* if (is_source_pixel) */
3223     else
3224     {
3225         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3226         result.alpha.signed_integer_data = 1;
3227         result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3228         result.green.signed_integer_data = green;
3229         result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3230         result.red.signed_integer_data   = red;
3231     }
3232 
3233     result.data_internalformat = GL_RG8I;
3234     result.data_type           = type;
3235 
3236     return result;
3237 }
3238 
3239 /** Retrieves a PixelData instance describing a single pixel stored in
3240  *  GL_RGB8UI internal format.
3241  *
3242  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3243  *                         0 otherwise.
3244  *  @param type            GLES type the pixel uses. Must be:
3245  *                         1) GL_UNSIGNED_BYTE for source pixels.
3246  *                         2) GL_UNSIGNED_INT for destination pixels.
3247  *  @param red             Value for red channel.
3248  *  @param green           Value for green channel.
3249  *
3250  *  @return Filled PixelData instance.
3251  **/
getRG8UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green)3252 PixelData ConversionDatabase::getRG8UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green)
3253 {
3254     PixelData result;
3255 
3256     if (is_source_pixel)
3257         DE_ASSERT(type == GL_UNSIGNED_BYTE);
3258     else
3259         DE_ASSERT(type == GL_UNSIGNED_INT);
3260 
3261     deMemset(&result, 0, sizeof(result));
3262 
3263     result.blue.data_type = CHANNEL_DATA_TYPE_NONE;
3264 
3265     if (is_source_pixel)
3266     {
3267         result.alpha.data_type          = CHANNEL_DATA_TYPE_NONE;
3268         result.green.unsigned_byte_data = green;
3269         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3270         result.red.unsigned_byte_data   = red;
3271         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3272     }
3273     else
3274     {
3275         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3276         result.alpha.unsigned_integer_data = 1;
3277         result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3278         result.green.unsigned_integer_data = green;
3279         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3280         result.red.unsigned_integer_data   = red;
3281     }
3282 
3283     result.data_internalformat = GL_RG8UI;
3284     result.data_type           = type;
3285 
3286     return result;
3287 }
3288 
3289 /** Retrieves a PixelData instance describing a single pixel stored in
3290  *  GL_RG8 internal format.
3291  *
3292  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3293  *                         0 otherwise.
3294  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_BYTE.
3295  *  @param red             Value for red channel.
3296  *  @param green           Value for green channel.
3297  *
3298  *  @return Filled PixelData instance.
3299  **/
getRG8PixelData(int is_source_pixel,GLenum type,unsigned char red,unsigned char green)3300 PixelData ConversionDatabase::getRG8PixelData(int is_source_pixel, GLenum type, unsigned char red, unsigned char green)
3301 {
3302     PixelData result;
3303 
3304     DE_ASSERT(type == GL_UNSIGNED_BYTE);
3305 
3306     deMemset(&result, 0, sizeof(result));
3307 
3308     if (is_source_pixel)
3309     {
3310         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
3311     }
3312     else
3313     {
3314         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3315         result.alpha.unsigned_byte_data = 255;
3316     }
3317 
3318     result.blue.data_type           = CHANNEL_DATA_TYPE_NONE;
3319     result.green.unsigned_byte_data = green;
3320     result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3321     result.red.unsigned_byte_data   = red;
3322     result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3323     result.data_internalformat      = GL_RG8;
3324     result.data_type                = type;
3325 
3326     return result;
3327 }
3328 
3329 /** Retrieves a PixelData instance describing a single pixel stored in
3330  *  GL_RGB10_A2 internal format.
3331  *
3332  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3333  *                         0 otherwise.
3334  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_INT_2_10_10_10_REV.
3335  *  @param red             Value for red channel.
3336  *  @param green           Value for green channel.
3337  *  @param blue            Value for blue channel.
3338  *  @param alpha           Value for alpha channel.
3339  *
3340  *  @return Filled PixelData instance.
3341  **/
getRGB10A2PixelData(GLenum type,unsigned short red,unsigned short green,unsigned short blue,unsigned char alpha)3342 PixelData ConversionDatabase::getRGB10A2PixelData(GLenum type, unsigned short red, unsigned short green,
3343                                                   unsigned short blue, unsigned char alpha)
3344 {
3345     PixelData result;
3346 
3347     DE_ASSERT(red <= 1023);
3348     DE_ASSERT(green <= 1023);
3349     DE_ASSERT(blue <= 1023);
3350     DE_ASSERT(alpha <= 3);
3351 
3352     DE_ASSERT(type == GL_UNSIGNED_INT_2_10_10_10_REV);
3353 
3354     deMemset(&result, 0, sizeof(result));
3355 
3356     result.alpha.unsigned_byte_data  = alpha;
3357     result.alpha.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_2BITS;
3358     result.blue.unsigned_short_data  = blue;
3359     result.blue.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3360     result.green.unsigned_short_data = green;
3361     result.green.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3362     result.red.unsigned_short_data   = red;
3363     result.red.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3364     result.data_internalformat       = GL_RGB10_A2;
3365     result.data_type                 = type;
3366 
3367     return result;
3368 }
3369 
3370 /** Retrieves a PixelData instance describing a single pixel stored in
3371  *  GL_RGB10A2UI internal format.
3372  *
3373  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3374  *                         0 otherwise.
3375  *  @param type            GLES type the pixel uses. Must be:
3376  *                         1) GL_UNSIGNED_INT_2_10_10_10_REV for source pixels.
3377  *                         2) GL_UNSIGNED_INT for destination pixels.
3378  *  @param red             Value for red channel.
3379  *  @param green           Value for green channel.
3380  *  @param blue            Value for blue channel.
3381  *  @param alpha           Value for alpha channel.
3382  *
3383  *  @return Filled PixelData instance.
3384  **/
getRGB10A2UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green,unsigned int blue,unsigned int alpha)3385 PixelData ConversionDatabase::getRGB10A2UIPixelData(int is_source_pixel, GLenum type, unsigned int red,
3386                                                     unsigned int green, unsigned int blue, unsigned int alpha)
3387 {
3388     PixelData result;
3389 
3390     if (is_source_pixel)
3391         DE_ASSERT(type == GL_UNSIGNED_INT_2_10_10_10_REV);
3392     else
3393         DE_ASSERT(type == GL_UNSIGNED_INT);
3394 
3395     deMemset(&result, 0, sizeof(result));
3396 
3397     if (is_source_pixel)
3398     {
3399         result.alpha.unsigned_byte_data  = alpha;
3400         result.alpha.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_2BITS;
3401         result.blue.unsigned_short_data  = blue;
3402         result.blue.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3403         result.green.unsigned_short_data = green;
3404         result.green.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3405         result.red.unsigned_short_data   = red;
3406         result.red.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3407     }
3408     else
3409     {
3410         result.alpha.unsigned_integer_data = alpha;
3411         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3412         result.blue.unsigned_integer_data  = blue;
3413         result.blue.data_type              = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3414         result.green.unsigned_integer_data = green;
3415         result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3416         result.red.unsigned_integer_data   = red;
3417         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3418     }
3419 
3420     result.data_internalformat = GL_RGB10_A2UI;
3421     result.data_type           = type;
3422 
3423     return result;
3424 }
3425 
3426 /** Retrieves a PixelData instance describing a single pixel stored in
3427  *  GL_RGB16I internal format.
3428  *
3429  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3430  *                         0 otherwise.
3431  *  @param type            GLES type the pixel uses. Must be:
3432  *                         1) GL_SHORT for source pixels.
3433  *                         2) GL_INT for destination pixels.
3434  *  @param red             Value for red channel.
3435  *  @param green           Value for green channel.
3436  *  @param blue            Value for blue channel.
3437  *
3438  *  @return Filled PixelData instance.
3439  **/
getRGB16IPixelData(int is_source_pixel,GLenum type,int red,int green,int blue)3440 PixelData ConversionDatabase::getRGB16IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue)
3441 {
3442     PixelData result;
3443 
3444     if (is_source_pixel)
3445         DE_ASSERT(type == GL_SHORT);
3446     else
3447         DE_ASSERT(type == GL_INT);
3448 
3449     deMemset(&result, 0, sizeof(result));
3450 
3451     if (is_source_pixel)
3452     {
3453         result.alpha.data_type         = CHANNEL_DATA_TYPE_NONE;
3454         result.blue.data_type          = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3455         result.blue.signed_short_data  = blue;
3456         result.green.data_type         = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3457         result.green.signed_short_data = green;
3458         result.red.data_type           = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3459         result.red.signed_short_data   = red;
3460     }
3461     else
3462     {
3463         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3464         result.alpha.signed_integer_data = 1;
3465         result.blue.data_type            = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3466         result.blue.signed_integer_data  = blue;
3467         result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3468         result.green.signed_integer_data = green;
3469         result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3470         result.red.signed_integer_data   = red;
3471     }
3472 
3473     result.data_internalformat = GL_RGB16I;
3474     result.data_type           = type;
3475 
3476     return result;
3477 }
3478 
3479 /** Retrieves a PixelData instance describing a single pixel stored in
3480  *  GL_RGB16UI internal format.
3481  *
3482  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3483  *                         0 otherwise.
3484  *  @param type            GLES type the pixel uses. Must be:
3485  *                         1) GL_UNSIGNED_SHORT for source pixels.
3486  *                         2) GL_UNSIGNED_INT for destination pixels.
3487  *  @param red             Value for red channel.
3488  *  @param green           Value for green channel.
3489  *  @param blue            Value for blue channel.
3490  *
3491  *  @return Filled PixelData instance.
3492  **/
getRGB16UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green,unsigned int blue)3493 PixelData ConversionDatabase::getRGB16UIPixelData(int is_source_pixel, GLenum type, unsigned int red,
3494                                                   unsigned int green, unsigned int blue)
3495 {
3496     PixelData result;
3497 
3498     if (is_source_pixel)
3499         DE_ASSERT(type == GL_UNSIGNED_SHORT);
3500     else
3501         DE_ASSERT(type == GL_UNSIGNED_INT);
3502 
3503     deMemset(&result, 0, sizeof(result));
3504 
3505     if (is_source_pixel)
3506     {
3507         result.alpha.data_type           = CHANNEL_DATA_TYPE_NONE;
3508         result.blue.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
3509         result.blue.unsigned_short_data  = blue;
3510         result.green.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
3511         result.green.unsigned_short_data = green;
3512         result.red.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
3513         result.red.unsigned_short_data   = red;
3514     }
3515     else
3516     {
3517         result.alpha.data_type             = CHANNEL_DATA_TYPE_NONE;
3518         result.alpha.unsigned_integer_data = 1;
3519         result.blue.data_type              = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3520         result.blue.unsigned_integer_data  = blue;
3521         result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3522         result.green.unsigned_integer_data = green;
3523         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3524         result.red.unsigned_integer_data   = red;
3525     }
3526 
3527     result.data_internalformat = GL_RGB16UI;
3528     result.data_type           = type;
3529 
3530     return result;
3531 }
3532 
3533 /** Retrieves a PixelData instance describing a single pixel stored in
3534  *  GL_RGB32I internal format.
3535  *
3536  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3537  *                         0 otherwise.
3538  *  @param type            GLES type the pixel uses. Must be GL_INT.
3539  *  @param red             Value for red channel.
3540  *  @param green           Value for green channel.
3541  *  @param blue            Value for blue channel.
3542  *
3543  *  @return Filled PixelData instance.
3544  **/
getRGB32IPixelData(int is_source_pixel,GLenum type,int red,int green,int blue)3545 PixelData ConversionDatabase::getRGB32IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue)
3546 {
3547     PixelData result;
3548 
3549     DE_ASSERT(type == GL_INT);
3550 
3551     deMemset(&result, 0, sizeof(result));
3552 
3553     if (is_source_pixel)
3554     {
3555         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
3556     }
3557     else
3558     {
3559         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3560         result.alpha.signed_integer_data = 1;
3561     }
3562 
3563     result.blue.data_type            = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3564     result.blue.signed_integer_data  = blue;
3565     result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3566     result.green.signed_integer_data = green;
3567     result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3568     result.red.signed_integer_data   = red;
3569     result.data_internalformat       = GL_RGB32I;
3570     result.data_type                 = type;
3571 
3572     return result;
3573 }
3574 
3575 /** Retrieves a PixelData instance describing a single pixel stored in
3576  *  GL_RGB32UI internal format.
3577  *
3578  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3579  *                         0 otherwise.
3580  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_INT.
3581  *  @param red             Value for red channel.
3582  *  @param green           Value for green channel.
3583  *  @param blue            Value for blue channel.
3584  *
3585  *  @return Filled PixelData instance.
3586  **/
getRGB32UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green,unsigned int blue)3587 PixelData ConversionDatabase::getRGB32UIPixelData(int is_source_pixel, GLenum type, unsigned int red,
3588                                                   unsigned int green, unsigned int blue)
3589 {
3590     PixelData result;
3591 
3592     DE_ASSERT(type == GL_UNSIGNED_INT);
3593 
3594     deMemset(&result, 0, sizeof(result));
3595 
3596     if (is_source_pixel)
3597     {
3598         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
3599     }
3600     else
3601     {
3602         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3603         result.alpha.unsigned_integer_data = 1;
3604     }
3605 
3606     result.blue.data_type              = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3607     result.blue.unsigned_integer_data  = blue;
3608     result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3609     result.green.unsigned_integer_data = green;
3610     result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3611     result.red.unsigned_integer_data   = red;
3612     result.data_internalformat         = GL_RGB32UI;
3613     result.data_type                   = type;
3614 
3615     return result;
3616 }
3617 
3618 /** Retrieves a PixelData instance describing a single pixel stored in
3619  *  GL_RGB5A1 internal format.
3620  *
3621  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3622  *                         0 otherwise.
3623  *  @param type            GLES type the pixel uses. Must be:
3624  *                         1) GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT_5_5_5_1 or
3625  *                            GL_UNSIGNED_INT_2_10_10_10_REV for source pixels.
3626  *                         2) GL_UNSIGNED_BYTE for destination pixels.
3627  *  @param red             Value for red channel.
3628  *  @param green           Value for green channel.
3629  *  @param blue            Value for blue channel.
3630  *  @param alpha           Value for alpha channel.
3631  *
3632  *  @return Filled PixelData instance.
3633  **/
getRGB5A1PixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green,unsigned int blue,unsigned int alpha)3634 PixelData ConversionDatabase::getRGB5A1PixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
3635                                                  unsigned int blue, unsigned int alpha)
3636 {
3637     PixelData result;
3638 
3639     if (is_source_pixel)
3640     {
3641         DE_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3642                   type == GL_UNSIGNED_INT_2_10_10_10_REV);
3643     }
3644     else
3645     {
3646         DE_ASSERT(type == GL_UNSIGNED_BYTE);
3647     }
3648 
3649     deMemset(&result, 0, sizeof(result));
3650 
3651     switch (type)
3652     {
3653     case GL_UNSIGNED_BYTE:
3654     {
3655         DE_ASSERT(red <= 255);
3656         DE_ASSERT(green <= 255);
3657         DE_ASSERT(blue <= 255);
3658         DE_ASSERT(alpha <= 255);
3659 
3660         // Fill the channel data structures
3661         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3662         result.alpha.unsigned_byte_data = alpha;
3663         result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3664         result.blue.unsigned_byte_data  = blue;
3665         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3666         result.green.unsigned_byte_data = green;
3667         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3668         result.red.unsigned_byte_data   = red;
3669 
3670         break;
3671     }
3672 
3673     case GL_UNSIGNED_SHORT_5_5_5_1:
3674     {
3675         DE_ASSERT(red <= 31);
3676         DE_ASSERT(green <= 31);
3677         DE_ASSERT(blue <= 31);
3678         DE_ASSERT(alpha == 0 || alpha == 1);
3679 
3680         // Fill the channel data structures
3681         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_1BIT;
3682         result.alpha.unsigned_byte_data = alpha;
3683         result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_5BITS;
3684         result.blue.unsigned_byte_data  = blue;
3685         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_5BITS;
3686         result.green.unsigned_byte_data = green;
3687         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_5BITS;
3688         result.red.unsigned_byte_data   = red;
3689 
3690         break;
3691     }
3692 
3693     case GL_UNSIGNED_INT_2_10_10_10_REV:
3694     {
3695         // Quick checks
3696         DE_ASSERT(red <= 1023);
3697         DE_ASSERT(green <= 1023);
3698         DE_ASSERT(blue <= 1023);
3699         DE_ASSERT(alpha <= 3);
3700 
3701         // Fill the channel data structures
3702         result.alpha.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_2BITS;
3703         result.alpha.unsigned_byte_data  = alpha;
3704         result.blue.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3705         result.blue.unsigned_short_data  = blue;
3706         result.green.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3707         result.green.unsigned_short_data = green;
3708         result.red.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
3709         result.red.unsigned_short_data   = red;
3710 
3711         break;
3712     }
3713     }
3714 
3715     result.data_internalformat = GL_RGB5_A1;
3716     result.data_type           = type;
3717 
3718     return result;
3719 }
3720 
3721 /** Retrieves a PixelData instance describing a single pixel stored in
3722  *  GL_RGB565 internal format.
3723  *
3724  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3725  *                         0 otherwise.
3726  *  @param type            GLES type the pixel uses. Must be:
3727  *                         1) GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT_5_6_5 for source pixels.
3728  *                         2) GL_UNSIGNED_BYTE for destination pixels.
3729  *  @param red             Value for red channel.
3730  *  @param green           Value for green channel.
3731  *  @param blue            Value for blue channel.
3732  *
3733  *  @return Filled PixelData instance.
3734  **/
getRGB565PixelData(int is_source_pixel,GLenum type,int red,int green,int blue)3735 PixelData ConversionDatabase::getRGB565PixelData(int is_source_pixel, GLenum type, int red, int green, int blue)
3736 {
3737     PixelData result;
3738 
3739     if (is_source_pixel)
3740         DE_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_5_6_5);
3741     else
3742         DE_ASSERT(type == GL_UNSIGNED_BYTE);
3743 
3744     deMemset(&result, 0, sizeof(result));
3745 
3746     switch (type)
3747     {
3748     case GL_UNSIGNED_BYTE:
3749     {
3750         // Fill the channel data structures
3751         result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3752         result.blue.unsigned_byte_data  = blue;
3753         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3754         result.green.unsigned_byte_data = green;
3755         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3756         result.red.unsigned_byte_data   = red;
3757 
3758         break;
3759     }
3760 
3761     case GL_UNSIGNED_SHORT_5_6_5:
3762     {
3763         DE_ASSERT(red >= 0 && red <= 31);
3764         DE_ASSERT(green >= 0 && green <= 63);
3765         DE_ASSERT(blue >= 0 && blue <= 31);
3766 
3767         // Fill the channel data structures
3768         result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_5BITS;
3769         result.blue.unsigned_byte_data  = blue;
3770         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_6BITS;
3771         result.green.unsigned_byte_data = green;
3772         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_5BITS;
3773         result.red.unsigned_byte_data   = red;
3774 
3775         break;
3776     }
3777     }
3778 
3779     if (is_source_pixel)
3780     {
3781         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
3782     }
3783     else
3784     {
3785         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3786         result.alpha.unsigned_byte_data = 255;
3787     }
3788 
3789     result.data_internalformat = GL_RGB565;
3790     result.data_type           = type;
3791 
3792     return result;
3793 }
3794 
3795 /** Retrieves a PixelData instance describing a single pixel stored in
3796  *  GL_RGB8 internal format.
3797  *
3798  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3799  *                         0 otherwise.
3800  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_BYTE.
3801  *  @param red             Value for red channel.
3802  *  @param green           Value for green channel.
3803  *  @param blue            Value for blue channel.
3804  *
3805  *  @return Filled PixelData instance.
3806  **/
getRGB8PixelData(int is_source_pixel,GLenum type,unsigned char red,unsigned char green,unsigned char blue)3807 PixelData ConversionDatabase::getRGB8PixelData(int is_source_pixel, GLenum type, unsigned char red, unsigned char green,
3808                                                unsigned char blue)
3809 {
3810     PixelData result;
3811 
3812     DE_ASSERT(type == GL_UNSIGNED_BYTE);
3813 
3814     deMemset(&result, 0, sizeof(result));
3815 
3816     if (is_source_pixel)
3817     {
3818         result.alpha.data_type = CHANNEL_DATA_TYPE_NONE;
3819     }
3820     else
3821     {
3822         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3823         result.alpha.unsigned_byte_data = 255;
3824     }
3825 
3826     result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3827     result.blue.unsigned_byte_data  = blue;
3828     result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3829     result.green.unsigned_byte_data = green;
3830     result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3831     result.red.unsigned_byte_data   = red;
3832     result.data_internalformat      = GL_RGB8;
3833     result.data_type                = type;
3834 
3835     return result;
3836 }
3837 
3838 /** Retrieves a PixelData instance describing a single pixel stored in
3839  *  GL_RGB8I internal format.
3840  *
3841  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3842  *                         0 otherwise.
3843  *  @param type            GLES type the pixel uses. Must be:
3844  *                         1) GL_BYTE for source pixels.
3845  *                         2) GL_INT for destination pixels.
3846  *  @param red             Value for red channel.
3847  *  @param green           Value for green channel.
3848  *  @param blue            Value for blue channel.
3849  *
3850  *  @return Filled PixelData instance.
3851  **/
getRGB8IPixelData(int is_source_pixel,GLenum type,int red,int green,int blue)3852 PixelData ConversionDatabase::getRGB8IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue)
3853 {
3854     PixelData result;
3855 
3856     if (is_source_pixel)
3857         DE_ASSERT(type == GL_BYTE);
3858     else
3859         DE_ASSERT(type == GL_INT);
3860 
3861     deMemset(&result, 0, sizeof(result));
3862 
3863     if (is_source_pixel)
3864     {
3865         result.alpha.data_type        = CHANNEL_DATA_TYPE_NONE;
3866         result.blue.data_type         = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
3867         result.blue.signed_byte_data  = blue;
3868         result.green.data_type        = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
3869         result.green.signed_byte_data = green;
3870         result.red.data_type          = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
3871         result.red.signed_byte_data   = red;
3872     }
3873     else
3874     {
3875         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3876         result.alpha.signed_integer_data = 1;
3877         result.blue.data_type            = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3878         result.blue.signed_integer_data  = blue;
3879         result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3880         result.green.signed_integer_data = green;
3881         result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3882         result.red.signed_integer_data   = red;
3883     }
3884 
3885     result.data_internalformat = GL_RGB8I;
3886     result.data_type           = type;
3887 
3888     return result;
3889 }
3890 
3891 /** Retrieves a PixelData instance describing a single pixel stored in
3892  *  GL_RGB8UI internal format.
3893  *
3894  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3895  *                         0 otherwise.
3896  *  @param type            GLES type the pixel uses. Must be:
3897  *                         1) GL_UNSIGNED_BYTE for source pixels.
3898  *                         2) GL_UNSIGNED_INT for destination pixels.
3899  *  @param red             Value for red channel.
3900  *  @param green           Value for green channel.
3901  *  @param blue            Value for blue channel.
3902  *  @param alpha           Value for alpha channel.
3903  *
3904  *  @return Filled PixelData instance.
3905  **/
getRGB8UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green,unsigned int blue)3906 PixelData ConversionDatabase::getRGB8UIPixelData(int is_source_pixel, GLenum type, unsigned int red, unsigned int green,
3907                                                  unsigned int blue)
3908 {
3909     PixelData result;
3910 
3911     if (is_source_pixel)
3912         DE_ASSERT(type == GL_UNSIGNED_BYTE);
3913     else
3914         DE_ASSERT(type == GL_UNSIGNED_INT);
3915 
3916     deMemset(&result, 0, sizeof(result));
3917 
3918     if (is_source_pixel)
3919     {
3920         result.alpha.data_type          = CHANNEL_DATA_TYPE_NONE;
3921         result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3922         result.blue.unsigned_byte_data  = blue;
3923         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3924         result.green.unsigned_byte_data = green;
3925         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
3926         result.red.unsigned_byte_data   = red;
3927     }
3928     else
3929     {
3930         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3931         result.alpha.unsigned_integer_data = 1;
3932         result.blue.data_type              = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3933         result.blue.unsigned_integer_data  = blue;
3934         result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3935         result.green.unsigned_integer_data = green;
3936         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
3937         result.red.unsigned_integer_data   = red;
3938     }
3939 
3940     result.data_internalformat = GL_RGB8UI;
3941     result.data_type           = type;
3942 
3943     return result;
3944 }
3945 
3946 /** Retrieves a PixelData instance describing a single pixel stored in
3947  *  GL_RGBA16I internal format.
3948  *
3949  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
3950  *                         0 otherwise.
3951  *  @param type            GLES type the pixel uses. Must be:
3952  *                         1) GL_SHORT for source pixels.
3953  *                         2) GL_INT for destination pixels.
3954  *  @param red             Value for red channel.
3955  *  @param green           Value for green channel.
3956  *  @param blue            Value for blue channel.
3957  *  @param alpha           Value for alpha channel.
3958  *
3959  *  @return Filled PixelData instance.
3960  **/
getRGBA16IPixelData(int is_source_pixel,GLenum type,int red,int green,int blue,int alpha)3961 PixelData ConversionDatabase::getRGBA16IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue,
3962                                                   int alpha)
3963 {
3964     PixelData result;
3965 
3966     if (is_source_pixel)
3967         DE_ASSERT(type == GL_SHORT);
3968     else
3969         DE_ASSERT(type == GL_INT);
3970 
3971     deMemset(&result, 0, sizeof(result));
3972 
3973     if (is_source_pixel)
3974     {
3975         result.alpha.data_type         = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3976         result.alpha.signed_short_data = alpha;
3977         result.blue.data_type          = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3978         result.blue.signed_short_data  = blue;
3979         result.green.data_type         = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3980         result.green.signed_short_data = green;
3981         result.red.data_type           = CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS;
3982         result.red.signed_short_data   = red;
3983     }
3984     else
3985     {
3986         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3987         result.alpha.signed_integer_data = alpha;
3988         result.blue.data_type            = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3989         result.blue.signed_integer_data  = blue;
3990         result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3991         result.green.signed_integer_data = green;
3992         result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
3993         result.red.signed_integer_data   = red;
3994     }
3995 
3996     result.data_internalformat = GL_RGBA16I;
3997     result.data_type           = type;
3998 
3999     return result;
4000 }
4001 
4002 /** Retrieves a PixelData instance describing a single pixel stored in
4003  *  GL_RGBA16UI internal format.
4004  *
4005  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4006  *                         0 otherwise.
4007  *  @param type            GLES type the pixel uses. Must be:
4008  *                         1) GL_UNSIGNED_SHORT for source pixels.
4009  *                         2) GL_UNSIGNED_INT for destination pixels.
4010  *  @param red             Value for red channel.
4011  *  @param green           Value for green channel.
4012  *  @param blue            Value for blue channel.
4013  *  @param alpha           Value for alpha channel.
4014  *
4015  *  @return Filled PixelData instance.
4016  **/
getRGBA16UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green,unsigned int blue,unsigned int alpha)4017 PixelData ConversionDatabase::getRGBA16UIPixelData(int is_source_pixel, GLenum type, unsigned int red,
4018                                                    unsigned int green, unsigned int blue, unsigned int alpha)
4019 {
4020     PixelData result;
4021 
4022     if (is_source_pixel)
4023         DE_ASSERT(type == GL_UNSIGNED_SHORT);
4024     else
4025         DE_ASSERT(type == GL_UNSIGNED_INT);
4026 
4027     deMemset(&result, 0, sizeof(result));
4028 
4029     if (is_source_pixel)
4030     {
4031         result.alpha.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
4032         result.alpha.unsigned_short_data = alpha;
4033         result.blue.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
4034         result.blue.unsigned_short_data  = blue;
4035         result.green.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
4036         result.green.unsigned_short_data = green;
4037         result.red.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS;
4038         result.red.unsigned_short_data   = red;
4039     }
4040     else
4041     {
4042         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4043         result.alpha.unsigned_integer_data = alpha;
4044         result.blue.data_type              = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4045         result.blue.unsigned_integer_data  = blue;
4046         result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4047         result.green.unsigned_integer_data = green;
4048         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4049         result.red.unsigned_integer_data   = red;
4050     }
4051 
4052     result.data_internalformat = GL_RGBA16UI;
4053     result.data_type           = type;
4054 
4055     return result;
4056 }
4057 
4058 /** Retrieves a PixelData instance describing a single pixel stored in
4059  *  GL_RGBA32I internal format.
4060  *
4061  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4062  *                         0 otherwise.
4063  *  @param type            GLES type the pixel uses. Must be GL_INT.
4064  *  @param red             Value for red channel.
4065  *  @param green           Value for green channel.
4066  *  @param blue            Value for blue channel.
4067  *  @param alpha           Value for alpha channel.
4068  *
4069  *  @return Filled PixelData instance.
4070  **/
getRGBA32IPixelData(GLenum type,int red,int green,int blue,int alpha)4071 PixelData ConversionDatabase::getRGBA32IPixelData(GLenum type, int red, int green, int blue, int alpha)
4072 {
4073     PixelData result;
4074 
4075     DE_ASSERT(type == GL_INT);
4076 
4077     deMemset(&result, 0, sizeof(result));
4078 
4079     result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
4080     result.alpha.signed_integer_data = alpha;
4081     result.blue.data_type            = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
4082     result.blue.signed_integer_data  = blue;
4083     result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
4084     result.green.signed_integer_data = green;
4085     result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
4086     result.red.signed_integer_data   = red;
4087     result.data_internalformat       = GL_RGBA32I;
4088     result.data_type                 = type;
4089 
4090     return result;
4091 }
4092 
4093 /** Retrieves a PixelData instance describing a single pixel stored in
4094  *  GL_RGBA32UI internal format.
4095  *
4096  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4097  *                         0 otherwise.
4098  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_INT.
4099  *  @param red             Value for red channel.
4100  *  @param green           Value for green channel.
4101  *  @param blue            Value for blue channel.
4102  *  @param alpha           Value for alpha channel.
4103  *
4104  *  @return Filled PixelData instance.
4105  **/
getRGBA32UIPixelData(GLenum type,unsigned int red,unsigned int green,unsigned int blue,unsigned int alpha)4106 PixelData ConversionDatabase::getRGBA32UIPixelData(GLenum type, unsigned int red, unsigned int green, unsigned int blue,
4107                                                    unsigned int alpha)
4108 {
4109     PixelData result;
4110 
4111     DE_ASSERT(type == GL_UNSIGNED_INT);
4112 
4113     deMemset(&result, 0, sizeof(result));
4114 
4115     result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4116     result.alpha.unsigned_integer_data = alpha;
4117     result.blue.data_type              = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4118     result.blue.unsigned_integer_data  = blue;
4119     result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4120     result.green.unsigned_integer_data = green;
4121     result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4122     result.red.unsigned_integer_data   = red;
4123     result.data_internalformat         = GL_RGBA32UI;
4124     result.data_type                   = type;
4125 
4126     return result;
4127 }
4128 
4129 /** Retrieves a PixelData instance describing a single pixel stored in
4130  *  GL_RGBA8I internal format.
4131  *
4132  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4133  *                         0 otherwise.
4134  *  @param type            GLES type the pixel uses. Must be:
4135  *                         1) GL_BYTE for source pixels.
4136  *                         2) GL_INT for destination pixels.
4137  *  @param red             Value for red channel.
4138  *  @param green           Value for green channel.
4139  *  @param blue            Value for blue channel.
4140  *  @param alpha           Value for alpha channel.
4141  *
4142  *  @return Filled PixelData instance.
4143  **/
getRGBA8IPixelData(int is_source_pixel,GLenum type,int red,int green,int blue,int alpha)4144 PixelData ConversionDatabase::getRGBA8IPixelData(int is_source_pixel, GLenum type, int red, int green, int blue,
4145                                                  int alpha)
4146 {
4147     PixelData result;
4148 
4149     if (is_source_pixel)
4150         DE_ASSERT(type == GL_BYTE);
4151     else
4152         DE_ASSERT(type == GL_INT);
4153 
4154     deMemset(&result, 0, sizeof(result));
4155 
4156     if (is_source_pixel)
4157     {
4158         result.alpha.data_type        = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
4159         result.alpha.signed_byte_data = alpha;
4160         result.blue.data_type         = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
4161         result.blue.signed_byte_data  = blue;
4162         result.green.data_type        = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
4163         result.green.signed_byte_data = green;
4164         result.red.data_type          = CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS;
4165         result.red.signed_byte_data   = red;
4166     }
4167     else
4168     {
4169         result.alpha.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
4170         result.alpha.signed_integer_data = alpha;
4171         result.blue.data_type            = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
4172         result.blue.signed_integer_data  = blue;
4173         result.green.data_type           = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
4174         result.green.signed_integer_data = green;
4175         result.red.data_type             = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
4176         result.red.signed_integer_data   = red;
4177     }
4178 
4179     result.data_internalformat = GL_RGBA8I;
4180     result.data_type           = type;
4181 
4182     return result;
4183 }
4184 
4185 /** Retrieves a PixelData instance describing a single pixel stored in
4186  *  GL_RGBA8UI internal format.
4187  *
4188  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4189  *                         0 otherwise.
4190  *  @param type            GLES type the pixel uses. Must be:
4191  *                         1) GL_UNSIGNED_BYTE for source pixels.
4192  *                         2) GL_UNSIGNED_INT for destination pixels.
4193  *  @param red             Value for red channel.
4194  *  @param green           Value for green channel.
4195  *  @param blue            Value for blue channel.
4196  *  @param alpha           Value for alpha channel.
4197  *
4198  *  @return Filled PixelData instance.
4199  **/
getRGBA8UIPixelData(int is_source_pixel,GLenum type,unsigned int red,unsigned int green,unsigned int blue,unsigned int alpha)4200 PixelData ConversionDatabase::getRGBA8UIPixelData(int is_source_pixel, GLenum type, unsigned int red,
4201                                                   unsigned int green, unsigned int blue, unsigned int alpha)
4202 {
4203     PixelData result;
4204 
4205     if (is_source_pixel)
4206         DE_ASSERT(type == GL_UNSIGNED_BYTE);
4207     else
4208         DE_ASSERT(type == GL_UNSIGNED_INT);
4209 
4210     deMemset(&result, 0, sizeof(result));
4211 
4212     if (is_source_pixel)
4213     {
4214         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4215         result.alpha.unsigned_byte_data = alpha;
4216         result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4217         result.blue.unsigned_byte_data  = blue;
4218         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4219         result.green.unsigned_byte_data = green;
4220         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4221         result.red.unsigned_byte_data   = red;
4222     }
4223     else
4224     {
4225         result.alpha.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4226         result.alpha.unsigned_integer_data = alpha;
4227         result.blue.data_type              = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4228         result.blue.unsigned_integer_data  = blue;
4229         result.green.data_type             = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4230         result.green.unsigned_integer_data = green;
4231         result.red.data_type               = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
4232         result.red.unsigned_integer_data   = red;
4233     }
4234 
4235     result.data_internalformat = GL_RGBA8UI;
4236     result.data_type           = type;
4237 
4238     return result;
4239 }
4240 
4241 /** Retrieves a PixelData instance describing a single pixel stored in
4242  *  GL_RGBA4 internal format.
4243  *
4244  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4245  *                         0 otherwise.
4246  *  @param type            GLES type the pixel uses. Must be:
4247  *                         1) GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT_4_4_4_4 for source pixels.
4248  *                         2) GL_UNSIGNED_BYTE for destination pixels.
4249  *  @param red             Value for red channel.
4250  *  @param green           Value for green channel.
4251  *  @param blue            Value for blue channel.
4252  *  @param alpha           Value for alpha channel.
4253  *
4254  *  @return Filled PixelData instance.
4255  **/
getRGBA4PixelData(int is_source_pixel,GLenum type,unsigned char red,unsigned char green,unsigned char blue,unsigned char alpha)4256 PixelData ConversionDatabase::getRGBA4PixelData(int is_source_pixel, GLenum type, unsigned char red,
4257                                                 unsigned char green, unsigned char blue, unsigned char alpha)
4258 {
4259     PixelData result;
4260 
4261     if (is_source_pixel)
4262         DE_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_4_4_4_4);
4263     else
4264         DE_ASSERT(type == GL_UNSIGNED_BYTE);
4265 
4266     deMemset(&result, 0, sizeof(result));
4267 
4268     switch (type)
4269     {
4270     case GL_UNSIGNED_BYTE:
4271     {
4272         // Fill the channel data structures
4273         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4274         result.alpha.unsigned_byte_data = alpha;
4275         result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4276         result.blue.unsigned_byte_data  = blue;
4277         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4278         result.green.unsigned_byte_data = green;
4279         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4280         result.red.unsigned_byte_data   = red;
4281 
4282         break;
4283     }
4284 
4285     case GL_UNSIGNED_SHORT_4_4_4_4:
4286     {
4287         DE_ASSERT(red <= 15);
4288         DE_ASSERT(green <= 15);
4289         DE_ASSERT(blue <= 15);
4290         DE_ASSERT(alpha <= 15);
4291 
4292         // Fill the channel data structures
4293         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_4BITS;
4294         result.alpha.unsigned_byte_data = alpha;
4295         result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_4BITS;
4296         result.blue.unsigned_byte_data  = blue;
4297         result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_4BITS;
4298         result.green.unsigned_byte_data = green;
4299         result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_4BITS;
4300         result.red.unsigned_byte_data   = red;
4301 
4302         break;
4303     }
4304     }
4305 
4306     result.data_internalformat = GL_RGBA4;
4307     result.data_type           = type;
4308 
4309     return result;
4310 }
4311 
4312 /** Retrieves a PixelData instance describing a single pixel stored in
4313  *  GL_RGBA8 internal format.
4314  *
4315  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4316  *                         0 otherwise.
4317  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_BYTE.
4318  *  @param red             Value for red channel.
4319  *  @param green           Value for green channel.
4320  *  @param blue            Value for blue channel.
4321  *  @param alpha           Value for alpha channel.
4322  *
4323  *  @return Filled PixelData instance.
4324  **/
getRGBA8PixelData(GLenum type,unsigned char red,unsigned char green,unsigned char blue,unsigned char alpha)4325 PixelData ConversionDatabase::getRGBA8PixelData(GLenum type, unsigned char red, unsigned char green, unsigned char blue,
4326                                                 unsigned char alpha)
4327 {
4328     PixelData result;
4329 
4330     DE_ASSERT(type == GL_UNSIGNED_BYTE);
4331 
4332     deMemset(&result, 0, sizeof(result));
4333 
4334     result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4335     result.alpha.unsigned_byte_data = alpha;
4336     result.blue.data_type           = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4337     result.blue.unsigned_byte_data  = blue;
4338     result.green.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4339     result.green.unsigned_byte_data = green;
4340     result.red.data_type            = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4341     result.red.unsigned_byte_data   = red;
4342     result.data_internalformat      = GL_RGBA8;
4343     result.data_type                = type;
4344 
4345     return result;
4346 }
4347 
4348 /** Retrieves a PixelData instance describing a single pixel stored in
4349  *  GL_SRGB8_ALPHA8 internal format.
4350  *
4351  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_BYTE.
4352  *  @param red             Value for red channel.
4353  *  @param green           Value for green channel.
4354  *  @param blue            Value for blue channel.
4355  *  @param alpha           Value for alpha channel.
4356  *
4357  *  @return Filled PixelData instance.
4358  **/
getSRGB8Alpha8PixelData(GLenum type,unsigned char red,unsigned char green,unsigned char blue,unsigned char alpha)4359 PixelData ConversionDatabase::getSRGB8Alpha8PixelData(GLenum type, unsigned char red, unsigned char green,
4360                                                       unsigned char blue, unsigned char alpha)
4361 {
4362     PixelData result = getRGBA8PixelData(type, red, green, blue, alpha);
4363 
4364     result.data_internalformat = GL_SRGB8_ALPHA8;
4365 
4366     return result;
4367 }
4368 
4369 /** Retrieves a PixelData instance describing a single pixel stored in
4370  *  GL_SRGB8 internal format.
4371  *
4372  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4373  *                         0 otherwise.
4374  *  @param type            GLES type the pixel uses. Must be GL_UNSIGNED_BYTE.
4375  *  @param red             Value for red channel.
4376  *  @param green           Value for green channel.
4377  *  @param blue            Value for blue channel.
4378  *
4379  *  @return Filled PixelData instance.
4380  **/
getSRGB8PixelData(int is_source_pixel,GLenum type,unsigned char red,unsigned char green,unsigned char blue)4381 PixelData ConversionDatabase::getSRGB8PixelData(int is_source_pixel, GLenum type, unsigned char red,
4382                                                 unsigned char green, unsigned char blue)
4383 {
4384     PixelData result = getSRGB8Alpha8PixelData(type, red, green, blue, 0);
4385 
4386     if (is_source_pixel)
4387     {
4388         result.alpha.data_type          = CHANNEL_DATA_TYPE_NONE;
4389         result.alpha.unsigned_byte_data = 0;
4390     }
4391     else
4392     {
4393         result.alpha.data_type          = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
4394         result.alpha.unsigned_byte_data = 255;
4395     }
4396 
4397     result.data_internalformat = GL_SRGB8;
4398     return result;
4399 }
4400 
4401 /** Retrieves a PixelData instance describing a single pixel stored in
4402  *  GL_R16F internal format.
4403  *
4404  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4405  *                         0 otherwise.
4406  *  @param type            GLES type the pixel uses. Must be GL_HALF_FLOAT
4407  *  @param red             Value for red channel.
4408  *
4409  *  @return Filled PixelData instance.
4410  **/
getR16FPixelData(int is_source_pixel,GLenum type,float red)4411 PixelData ConversionDatabase::getR16FPixelData(int is_source_pixel, GLenum type, float red)
4412 {
4413     PixelData result;
4414 
4415     DE_ASSERT(type == GL_HALF_FLOAT);
4416 
4417     deMemset(&result, 0, sizeof(result));
4418 
4419     if (is_source_pixel)
4420     {
4421         result.red.float_data = red;
4422         result.red.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4423     }
4424     else
4425     {
4426         result.alpha.float_data = 1;
4427         result.alpha.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4428         result.red.float_data   = red;
4429         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4430     }
4431 
4432     result.data_internalformat = GL_R16F;
4433     result.data_type           = type;
4434 
4435     return result;
4436 }
4437 
4438 /** Retrieves a PixelData instance describing a single pixel stored in
4439  *  GL_R32F internal format.
4440  *
4441  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4442  *                         0 otherwise.
4443  *  @param type            GLES type the pixel uses. Must be GL_FLOAT
4444  *  @param red             Value for red channel.
4445  *
4446  *  @return Filled PixelData instance.
4447  **/
getR32FPixelData(int is_source_pixel,GLenum type,float red)4448 PixelData ConversionDatabase::getR32FPixelData(int is_source_pixel, GLenum type, float red)
4449 {
4450     PixelData result;
4451 
4452     DE_ASSERT(type == GL_FLOAT);
4453 
4454     deMemset(&result, 0, sizeof(result));
4455 
4456     if (is_source_pixel)
4457     {
4458         result.red.float_data = red;
4459         result.red.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4460     }
4461     else
4462     {
4463         result.alpha.float_data = 1;
4464         result.alpha.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4465         result.red.float_data   = red;
4466         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4467     }
4468 
4469     result.data_internalformat = GL_R32F;
4470     result.data_type           = type;
4471 
4472     return result;
4473 }
4474 
4475 /** Retrieves a PixelData instance describing a single pixel stored in
4476  *  GL_RG16F internal format.
4477  *
4478  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4479  *                         0 otherwise.
4480  *  @param type            GLES type the pixel uses. Must be GL_HALF_FLOAT
4481  *  @param red             Value for red channel.
4482  *  @param green           Value for green channel.
4483  *
4484  *  @return Filled PixelData instance.
4485  **/
getRG16FPixelData(int is_source_pixel,GLenum type,float red,float green)4486 PixelData ConversionDatabase::getRG16FPixelData(int is_source_pixel, GLenum type, float red, float green)
4487 {
4488     PixelData result;
4489 
4490     DE_ASSERT(type == GL_HALF_FLOAT);
4491 
4492     deMemset(&result, 0, sizeof(result));
4493 
4494     if (is_source_pixel)
4495     {
4496         result.red.float_data   = red;
4497         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4498         result.green.float_data = green;
4499         result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4500     }
4501     else
4502     {
4503         result.alpha.float_data = 1;
4504         result.alpha.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4505         result.red.float_data   = red;
4506         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4507         result.green.float_data = green;
4508         result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4509     }
4510 
4511     result.data_internalformat = GL_RG16F;
4512     result.data_type           = type;
4513 
4514     return result;
4515 }
4516 
4517 /** Retrieves a PixelData instance describing a single pixel stored in
4518  *  GL_RG32F internal format.
4519  *
4520  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4521  *                         0 otherwise.
4522  *  @param type            GLES type the pixel uses. Must be GL_FLOAT
4523  *  @param red             Value for red channel.
4524  *  @param green           Value for green channel.
4525  *
4526  *  @return Filled PixelData instance.
4527  **/
getRG32FPixelData(int is_source_pixel,GLenum type,float red,float green)4528 PixelData ConversionDatabase::getRG32FPixelData(int is_source_pixel, GLenum type, float red, float green)
4529 {
4530     PixelData result;
4531 
4532     DE_ASSERT(type == GL_FLOAT);
4533 
4534     deMemset(&result, 0, sizeof(result));
4535 
4536     if (is_source_pixel)
4537     {
4538         result.red.float_data   = red;
4539         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4540         result.green.float_data = green;
4541         result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4542     }
4543     else
4544     {
4545         result.alpha.float_data = 1;
4546         result.alpha.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4547         result.red.float_data   = red;
4548         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4549         result.green.float_data = green;
4550         result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4551     }
4552 
4553     result.data_internalformat = GL_RG32F;
4554     result.data_type           = type;
4555 
4556     return result;
4557 }
4558 
4559 /** Retrieves a PixelData instance describing a single pixel stored in
4560  *  GL_RGB16F internal format.
4561  *
4562  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4563  *                         0 otherwise.
4564  *  @param type            GLES type the pixel uses. Must be GL_HALF_FLOAT
4565  *  @param red             Value for red channel.
4566  *  @param green           Value for green channel.
4567  *  @param blue            Value for green channel.
4568  *
4569  *  @return Filled PixelData instance.
4570  **/
getRGB16FPixelData(int is_source_pixel,GLenum type,float red,float green,float blue)4571 PixelData ConversionDatabase::getRGB16FPixelData(int is_source_pixel, GLenum type, float red, float green, float blue)
4572 {
4573     PixelData result;
4574 
4575     DE_ASSERT(type == GL_HALF_FLOAT);
4576 
4577     deMemset(&result, 0, sizeof(result));
4578 
4579     if (is_source_pixel)
4580     {
4581         result.red.float_data   = red;
4582         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4583         result.green.float_data = green;
4584         result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4585         result.blue.float_data  = blue;
4586         result.blue.data_type   = CHANNEL_DATA_TYPE_FLOAT;
4587     }
4588     else
4589     {
4590         result.alpha.float_data = 1;
4591         result.alpha.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4592         result.red.float_data   = red;
4593         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4594         result.green.float_data = green;
4595         result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4596         result.blue.float_data  = blue;
4597         result.blue.data_type   = CHANNEL_DATA_TYPE_FLOAT;
4598     }
4599 
4600     result.data_internalformat = GL_RGB16F;
4601     result.data_type           = type;
4602 
4603     return result;
4604 }
4605 
4606 /** Retrieves a PixelData instance describing a single pixel stored in
4607  *  GL_RGB32F internal format.
4608  *
4609  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4610  *                         0 otherwise.
4611  *  @param type            GLES type the pixel uses. Must be GL_FLOAT
4612  *  @param red             Value for red channel.
4613  *  @param green           Value for green channel.
4614  *  @param blue            Value for blue channel.
4615  *
4616  *  @return Filled PixelData instance.
4617  **/
getRGB32FPixelData(int is_source_pixel,GLenum type,float red,float green,float blue)4618 PixelData ConversionDatabase::getRGB32FPixelData(int is_source_pixel, GLenum type, float red, float green, float blue)
4619 {
4620     PixelData result;
4621 
4622     DE_ASSERT(type == GL_FLOAT);
4623 
4624     deMemset(&result, 0, sizeof(result));
4625 
4626     if (is_source_pixel)
4627     {
4628         result.red.float_data   = red;
4629         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4630         result.green.float_data = green;
4631         result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4632         result.blue.float_data  = blue;
4633         result.blue.data_type   = CHANNEL_DATA_TYPE_FLOAT;
4634     }
4635     else
4636     {
4637         result.alpha.float_data = 1;
4638         result.alpha.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4639         result.red.float_data   = red;
4640         result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4641         result.green.float_data = green;
4642         result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4643         result.blue.float_data  = blue;
4644         result.blue.data_type   = CHANNEL_DATA_TYPE_FLOAT;
4645     }
4646 
4647     result.data_internalformat = GL_RGB32F;
4648     result.data_type           = type;
4649 
4650     return result;
4651 }
4652 
4653 /** Retrieves a PixelData instance describing a single pixel stored in
4654  *  GL_RGBA16F internal format.
4655  *
4656  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4657  *                         0 otherwise.
4658  *  @param type            GLES type the pixel uses. Must be GL_HALF_FLOAT
4659  *  @param red             Value for red channel.
4660  *  @param green           Value for green channel.
4661  *  @param blue            Value for blue channel.
4662  *  @param alpha           Value for alpha channel.
4663  *
4664  *  @return Filled PixelData instance.
4665  **/
getRGBA16FPixelData(GLenum type,float red,float green,float blue,float alpha)4666 PixelData ConversionDatabase::getRGBA16FPixelData(GLenum type, float red, float green, float blue, float alpha)
4667 {
4668     PixelData result;
4669 
4670     DE_ASSERT(type == GL_HALF_FLOAT);
4671 
4672     deMemset(&result, 0, sizeof(result));
4673 
4674     result.alpha.float_data = alpha;
4675     result.alpha.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4676     result.red.float_data   = red;
4677     result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4678     result.green.float_data = green;
4679     result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4680     result.blue.float_data  = blue;
4681     result.blue.data_type   = CHANNEL_DATA_TYPE_FLOAT;
4682 
4683     result.data_internalformat = GL_RGBA16F;
4684     result.data_type           = type;
4685 
4686     return result;
4687 }
4688 
4689 /** Retrieves a PixelData instance describing a single pixel stored in
4690  *  GL_RGBA32F internal format.
4691  *
4692  *  @param is_source_pixel 1 if the pixel is going to be used as conversion source,
4693  *                         0 otherwise.
4694  *  @param type            GLES type the pixel uses. Must be GL_FLOAT
4695  *  @param red             Value for red channel.
4696  *  @param green           Value for green channel.
4697  *  @param blue            Value for blue channel.
4698  *  @param alpha           Value for alpha channel.
4699  *
4700  *  @return Filled PixelData instance.
4701  **/
getRGBA32FPixelData(GLenum type,float red,float green,float blue,float alpha)4702 PixelData ConversionDatabase::getRGBA32FPixelData(GLenum type, float red, float green, float blue, float alpha)
4703 {
4704     PixelData result;
4705 
4706     DE_ASSERT(type == GL_FLOAT);
4707 
4708     deMemset(&result, 0, sizeof(result));
4709 
4710     result.alpha.float_data = alpha;
4711     result.alpha.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4712     result.red.float_data   = red;
4713     result.red.data_type    = CHANNEL_DATA_TYPE_FLOAT;
4714     result.green.float_data = green;
4715     result.green.data_type  = CHANNEL_DATA_TYPE_FLOAT;
4716     result.blue.float_data  = blue;
4717     result.blue.data_type   = CHANNEL_DATA_TYPE_FLOAT;
4718 
4719     result.data_internalformat = GL_RGBA32F;
4720     result.data_type           = type;
4721 
4722     return result;
4723 }
4724 
4725 /** Adds a new conversion rule to a conversion database.
4726  *
4727  *  Destination pixel datasets can only use one of the following types:
4728  *
4729  *  GL_UNSIGNED_BYTE               (for fixed-point source types);
4730  *  GL_INT                         (for signed integer types);
4731  *  GL_UNSIGNED_INT                (for unsigned integer types);
4732  *  GL_UNSIGNED_INT_2_10_10_10_REV (for GL_RGB10_A2 type ONLY)
4733  *
4734  *  The type used for destination storage configures arguments that
4735  *  will be passed to a gl.readPixels() call in verification stage IF
4736  *  source internalformat is color-renderable. If not, destination type
4737  *  determines how result & reference data should be compared using
4738  *  a special program object.
4739  *
4740  *  It is illegal to:
4741  *
4742  *  1) add more than one conversion rule that uses the same source+destination
4743  *     internalformat+type combination.
4744  *  2) use source pixels of different internalformats or types;
4745  *  3) use destination pixels of different internalformats or types;
4746  *  4) use pixel data instances using invalid internalformat or types.
4747  *
4748  *  @param src_topleft     Pixel-data instance describing source top-left corner.
4749  *  @param dst_topleft     Pixel-data instance describing destination top-left corner.
4750  *  @param src_topright    Pixel-data instance describing source top-right corner.
4751  *  @param dst_topright    Pixel-data instance describing destination top-right corner.
4752  *  @param src_bottomleft  Pixel-data instance describing source bottom-left corner.
4753  *  @param dst_bottomleft  Pixel-data instance describing destination bottom-left corner.
4754  *  @param src_bottomright Pixel-data instance describing source bottom-right corner.
4755  *  @param dst_bottomright Pixel-data instance describing destination bottom-right corner.
4756  **/
addEntryToConversionDatabase(PixelData src_topleft,PixelData dst_topleft,PixelData src_topright,PixelData dst_topright,PixelData src_bottomleft,PixelData dst_bottomleft,PixelData src_bottomright,PixelData dst_bottomright,PixelCompareChannel channels_to_compare)4757 void ConversionDatabase::addEntryToConversionDatabase(PixelData src_topleft, PixelData dst_topleft,
4758                                                       PixelData src_topright, PixelData dst_topright,
4759                                                       PixelData src_bottomleft, PixelData dst_bottomleft,
4760                                                       PixelData src_bottomright, PixelData dst_bottomright,
4761                                                       PixelCompareChannel channels_to_compare)
4762 {
4763     GLenum dst_internalformat       = GL_NONE;
4764     GLenum dst_type                 = GL_NONE;
4765     int is_dst_internalformat_valid = 0;
4766     int is_dst_type_valid           = 0;
4767     GLenum src_internalformat       = GL_NONE;
4768     GLenum src_type                 = GL_NONE;
4769 
4770     // Quick checks: general
4771     DE_ASSERT(src_topleft.data_internalformat != GL_NONE);
4772     DE_ASSERT(dst_topleft.data_internalformat != GL_NONE);
4773 
4774     if (src_topleft.data_internalformat == GL_NONE || dst_topleft.data_internalformat == GL_NONE)
4775         return; // if (source / destination internalformats are GL_NONE)
4776 
4777     DE_ASSERT(src_topleft.data_internalformat == src_topright.data_internalformat);
4778     DE_ASSERT(src_topleft.data_internalformat == src_bottomleft.data_internalformat);
4779     DE_ASSERT(src_topleft.data_internalformat == src_bottomright.data_internalformat);
4780     DE_ASSERT(src_topleft.data_type == src_topright.data_type);
4781     DE_ASSERT(src_topleft.data_type == src_bottomleft.data_type);
4782     DE_ASSERT(src_topleft.data_type == src_bottomright.data_type);
4783 
4784     if (src_topleft.data_internalformat != src_topright.data_internalformat ||
4785         src_topleft.data_internalformat != src_bottomleft.data_internalformat ||
4786         src_topleft.data_internalformat != src_bottomright.data_internalformat ||
4787         src_topleft.data_type != src_topright.data_type || src_topleft.data_type != src_bottomleft.data_type ||
4788         src_topleft.data_type != src_bottomright.data_type)
4789     {
4790         return;
4791     } // if (source pixels' internalformats and/or types are not the same values)
4792 
4793     DE_ASSERT(dst_topleft.data_internalformat == dst_topright.data_internalformat);
4794     DE_ASSERT(dst_topleft.data_internalformat == dst_bottomleft.data_internalformat);
4795     DE_ASSERT(dst_topleft.data_internalformat == dst_bottomright.data_internalformat);
4796     DE_ASSERT(dst_topleft.data_type == dst_topright.data_type);
4797     DE_ASSERT(dst_topleft.data_type == dst_bottomleft.data_type);
4798     DE_ASSERT(dst_topleft.data_type == dst_bottomright.data_type);
4799 
4800     if (dst_topleft.data_internalformat != dst_topright.data_internalformat ||
4801         dst_topleft.data_internalformat != dst_bottomleft.data_internalformat ||
4802         dst_topleft.data_internalformat != dst_bottomright.data_internalformat ||
4803         dst_topleft.data_type != dst_topright.data_type || dst_topleft.data_type != dst_bottomleft.data_type ||
4804         dst_topleft.data_type != dst_bottomright.data_type)
4805     {
4806         return;
4807     } // if (destination pixels' internalformats and/or types are not the same values)
4808 
4809     src_internalformat = src_topleft.data_internalformat;
4810     src_type           = src_topleft.data_type;
4811     dst_internalformat = dst_topleft.data_internalformat;
4812     dst_type           = dst_topleft.data_type;
4813 
4814     // Quick checks: format used for destination storage
4815     is_dst_type_valid           = isTypeSupportedByGLReadPixels(dst_type);
4816     is_dst_internalformat_valid = isInternalFormatCompatibleWithType(dst_type, dst_internalformat);
4817 
4818     DE_ASSERT(is_dst_type_valid && is_dst_internalformat_valid);
4819     if (!is_dst_type_valid || !is_dst_internalformat_valid)
4820         TCU_FAIL("Requested destination type or internalformat is not compatible with validation requirements.");
4821 
4822     // Quick checks: make sure the conversion has not been already added
4823     for (unsigned int n = 0; n < n_entries_added; ++n)
4824     {
4825         ConversionDatabaseEntry &entry_ptr = entries[n];
4826 
4827         GLenum iterated_dst_internalformat = entry_ptr.dst_topleft_corner.data_internalformat;
4828         GLenum iterated_dst_type           = entry_ptr.dst_topleft_corner.data_type;
4829         GLenum iterated_src_internalformat = entry_ptr.src_topleft_corner.data_internalformat;
4830         GLenum iterated_src_type           = entry_ptr.src_topleft_corner.data_type;
4831         int is_new_rule                    = src_internalformat != iterated_src_internalformat ||
4832                           ((src_internalformat == iterated_src_internalformat) && (src_type != iterated_src_type)) ||
4833                           ((src_internalformat == iterated_src_internalformat) && (src_type == iterated_src_type) &&
4834                            (dst_internalformat != iterated_dst_internalformat)) ||
4835                           ((src_internalformat == iterated_src_internalformat) && (src_type == iterated_src_type) &&
4836                            (dst_internalformat == iterated_dst_internalformat) && (dst_type != iterated_dst_type));
4837 
4838         DE_ASSERT(is_new_rule);
4839         if (!is_new_rule)
4840             TCU_FAIL("This conversion rule already exists!");
4841     }
4842 
4843     // Make sure there's enough space to hold a new entry
4844     if ((n_entries_added + 1) >= n_entries_allocated)
4845     {
4846         // Realloc is needed
4847         n_entries_allocated <<= 1;
4848         entries.resize(n_entries_allocated);
4849         if (entries.empty())
4850             TCU_FAIL("Out of memory while reallocating conversion database");
4851     }
4852 
4853     // Add the new entry
4854     ConversionDatabaseEntry &entry_ptr = entries[n_entries_added];
4855     entry_ptr.dst_bottomleft_corner    = dst_bottomleft;
4856     entry_ptr.dst_bottomright_corner   = dst_bottomright;
4857     entry_ptr.dst_topleft_corner       = dst_topleft;
4858     entry_ptr.dst_topright_corner      = dst_topright;
4859     entry_ptr.src_bottomleft_corner    = src_bottomleft;
4860     entry_ptr.src_bottomright_corner   = src_bottomright;
4861     entry_ptr.src_topleft_corner       = src_topleft;
4862     entry_ptr.src_topright_corner      = src_topright;
4863     entry_ptr.channels_to_compare      = channels_to_compare;
4864 
4865     ++n_entries_added;
4866 }
4867 
4868 /** Adds all known conversion rules to a conversion database passed by argument.
4869  *
4870  *  A conversion database stores exactly one conversion rule for each valid combination
4871  *  of source+destination internal-formats (with an exception that for each internalformat
4872  *  data may be represented with many different types!).
4873  *  These rules are then used by copy_tex_image_conversions_required conformance test to
4874  *  validate successfully executed conversions.
4875  *
4876  *  A quick reminder:
4877  *
4878  *      Source dataset corresponds to 2x2 image (using up to 4 channels) that the attachment bound to
4879  *  read buffer will use prior to glCopyTexImage2D() call. This image is defined by 4 Get*PixelData()
4880  *  calls with the first argument set to 1.
4881  *      Destination dataset corresponds to 2x2 image (using up to 4 channels) that the result texture
4882  *  object should match (within acceptable epsilon). This image is defined by 4 Get*PixelData() calls
4883  *  with the first argument set to 0.
4884  *
4885  *  Source datasets are allowed to use any internalformat+type combination that is considered supported
4886  *  by GLES implementation.
4887  *  Destination datasets are only allowed to use specific types - please see AddEntryToConversionDatabase()
4888  *  doxygen for more details.
4889  *
4890  *  @param database Conversion database handle.
4891  **/
configureConversionDatabase()4892 void ConversionDatabase::configureConversionDatabase()
4893 {
4894     int bits_1010102[4] = {10, 10, 10, 2};
4895     int bits_4444[4]    = {4, 4, 4, 4};
4896     int bits_5551[4]    = {5, 5, 5, 1};
4897     int bits_565[4]     = {5, 6, 5, 0};
4898     int bits_888[4]     = {8, 8, 8, 0};
4899     int bits_8888[4]    = {8, 8, 8, 8};
4900 
4901     /* GL_R8 */
4902     {
4903         const unsigned char texel1[1] = {255};
4904         const unsigned char texel2[1] = {127};
4905         const unsigned char texel3[1] = {63};
4906         const unsigned char texel4[1] = {0};
4907 
4908         /* GL_R8 => GL_LUMINANCE8_OES */
4909         addEntryToConversionDatabase(
4910             getR8PixelData(1, GL_UNSIGNED_BYTE, texel1[0]), getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel1[0]),
4911             getR8PixelData(1, GL_UNSIGNED_BYTE, texel2[0]), getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel2[0]),
4912             getR8PixelData(1, GL_UNSIGNED_BYTE, texel3[0]), getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel3[0]),
4913             getR8PixelData(1, GL_UNSIGNED_BYTE, texel4[0]), getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel4[0]),
4914             PIXEL_COMPARE_CHANNEL_R);
4915 
4916         /* GL_R8 => GL_R8 */
4917         addEntryToConversionDatabase(
4918             getR8PixelData(1, GL_UNSIGNED_BYTE, texel1[0]), getR8PixelData(0, GL_UNSIGNED_BYTE, texel1[0]),
4919             getR8PixelData(1, GL_UNSIGNED_BYTE, texel2[0]), getR8PixelData(0, GL_UNSIGNED_BYTE, texel2[0]),
4920             getR8PixelData(1, GL_UNSIGNED_BYTE, texel3[0]), getR8PixelData(0, GL_UNSIGNED_BYTE, texel3[0]),
4921             getR8PixelData(1, GL_UNSIGNED_BYTE, texel4[0]), getR8PixelData(0, GL_UNSIGNED_BYTE, texel4[0]),
4922             PIXEL_COMPARE_CHANNEL_R);
4923     }
4924 
4925     /* GL_RG8 */
4926     {
4927         const unsigned char texel1[2] = {255, 127};
4928         const unsigned char texel2[2] = {127, 63};
4929         const unsigned char texel3[2] = {63, 0};
4930         const unsigned char texel4[2] = {0, 255};
4931 
4932         /* GL_RG8 => GL_LUMINANCE8_OES */
4933         addEntryToConversionDatabase(getRG8PixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1]),
4934                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel1[0]),
4935                                      getRG8PixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1]),
4936                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel2[0]),
4937                                      getRG8PixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1]),
4938                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel3[0]),
4939                                      getRG8PixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1]),
4940                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
4941 
4942         /* GL_RG8 => GL_R8 */
4943         addEntryToConversionDatabase(
4944             getRG8PixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1]), getR8PixelData(0, GL_UNSIGNED_BYTE, texel1[0]),
4945             getRG8PixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1]), getR8PixelData(0, GL_UNSIGNED_BYTE, texel2[0]),
4946             getRG8PixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1]), getR8PixelData(0, GL_UNSIGNED_BYTE, texel3[0]),
4947             getRG8PixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1]), getR8PixelData(0, GL_UNSIGNED_BYTE, texel4[0]),
4948             PIXEL_COMPARE_CHANNEL_R);
4949 
4950         /* GL_RG8 => GL_RG8 */
4951         addEntryToConversionDatabase(getRG8PixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1]),
4952                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel1[0], texel1[1]),
4953                                      getRG8PixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1]),
4954                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel2[0], texel2[1]),
4955                                      getRG8PixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1]),
4956                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel3[0], texel3[1]),
4957                                      getRG8PixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1]),
4958                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel4[0], texel4[1]),
4959                                      PIXEL_COMPARE_CHANNEL_RG);
4960     }
4961 
4962     /* GL_RGB8 */
4963     {
4964         const unsigned char texel1[3] = {255, 127, 63};
4965         const unsigned char texel2[3] = {127, 63, 0};
4966         const unsigned char texel3[3] = {63, 0, 255};
4967         const unsigned char texel4[3] = {0, 255, 127};
4968 
4969         /* GL_RGB8 => GL_RGB8 */
4970         addEntryToConversionDatabase(getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2]),
4971                                      getRGB8PixelData(0, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2]),
4972                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2]),
4973                                      getRGB8PixelData(0, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2]),
4974                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2]),
4975                                      getRGB8PixelData(0, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2]),
4976                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2]),
4977                                      getRGB8PixelData(0, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2]),
4978                                      PIXEL_COMPARE_CHANNEL_RGB);
4979 
4980         /* GL_RGB8 => GL_LUMINANCE8_OES */
4981         addEntryToConversionDatabase(getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2]),
4982                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel1[0]),
4983                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2]),
4984                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel2[0]),
4985                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2]),
4986                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel3[0]),
4987                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2]),
4988                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
4989 
4990         /* GL_RGB8 => GL_R8 */
4991         addEntryToConversionDatabase(getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2]),
4992                                      getR8PixelData(0, GL_UNSIGNED_BYTE, texel1[0]),
4993                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2]),
4994                                      getR8PixelData(0, GL_UNSIGNED_BYTE, texel2[0]),
4995                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2]),
4996                                      getR8PixelData(0, GL_UNSIGNED_BYTE, texel3[0]),
4997                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2]),
4998                                      getR8PixelData(0, GL_UNSIGNED_BYTE, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
4999 
5000         /* GL_RGB8 => GL_RG8 */
5001         addEntryToConversionDatabase(getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2]),
5002                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel1[0], texel1[1]),
5003                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2]),
5004                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel2[0], texel2[1]),
5005                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2]),
5006                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel3[0], texel3[1]),
5007                                      getRGB8PixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2]),
5008                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel4[0], texel4[1]),
5009                                      PIXEL_COMPARE_CHANNEL_RG);
5010     }
5011 
5012     { /* GL_RGB565 */
5013         int texel565_1[4] = {31, 63, 21, 0};
5014         int texel565_2[4] = {21, 43, 11, 0};
5015         int texel565_3[4] = {11, 23, 1, 0};
5016         int texel888_1[4] = {255, 155, 55, 0};
5017         int texel888_2[4] = {176, 76, 36, 0};
5018         int texel888_3[4] = {88, 66, 44, 0};
5019         int texel888_4[4] = {20, 10, 0, 0};
5020 
5021         int temp_565_to_888_bl[4]             = {0};
5022         int temp_565_to_888_tl[4]             = {0};
5023         int temp_565_to_888_tr[4]             = {0};
5024         int temp_888_through_565_to_888_bl[4] = {0};
5025         int temp_888_through_565_to_888_br[4] = {0};
5026         int temp_888_through_565_to_888_tl[4] = {0};
5027         int temp_888_through_565_to_888_tr[4] = {0};
5028 
5029         convertNormalizedUnsignedFixedPoint(bits_565, bits_888, bits_888, bits_888, texel565_1, temp_565_to_888_tl);
5030         convertNormalizedUnsignedFixedPoint(bits_565, bits_888, bits_888, bits_888, texel565_2, temp_565_to_888_tr);
5031         convertNormalizedUnsignedFixedPoint(bits_565, bits_888, bits_888, bits_888, texel565_3, temp_565_to_888_bl);
5032 
5033         convertNormalizedUnsignedFixedPoint(bits_888, bits_565, bits_888, bits_888, texel888_1,
5034                                             temp_888_through_565_to_888_tl);
5035         convertNormalizedUnsignedFixedPoint(bits_888, bits_565, bits_888, bits_888, texel888_2,
5036                                             temp_888_through_565_to_888_tr);
5037         convertNormalizedUnsignedFixedPoint(bits_888, bits_565, bits_888, bits_888, texel888_3,
5038                                             temp_888_through_565_to_888_bl);
5039         convertNormalizedUnsignedFixedPoint(bits_888, bits_565, bits_888, bits_888, texel888_4,
5040                                             temp_888_through_565_to_888_br);
5041 
5042         /* GL_RGB565 => GL_RGB565 */
5043         addEntryToConversionDatabase(
5044             getRGB565PixelData(1, GL_UNSIGNED_SHORT_5_6_5, texel565_1[0], texel565_1[1], texel565_1[2]),
5045             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_565_to_888_tl[0], temp_565_to_888_tl[1],
5046                                temp_565_to_888_tl[2]),
5047             getRGB565PixelData(1, GL_UNSIGNED_SHORT_5_6_5, texel565_2[0], texel565_2[1], texel565_2[2]),
5048             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_565_to_888_tr[0], temp_565_to_888_tr[1],
5049                                temp_565_to_888_tr[2]),
5050             getRGB565PixelData(1, GL_UNSIGNED_SHORT_5_6_5, texel565_3[0], texel565_3[1], texel565_3[2]),
5051             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_565_to_888_bl[0], temp_565_to_888_bl[1],
5052                                temp_565_to_888_bl[2]),
5053             getRGB565PixelData(1, GL_UNSIGNED_SHORT_5_6_5, 0, 0, 0), getRGB565PixelData(0, GL_UNSIGNED_BYTE, 0, 0, 0),
5054             PIXEL_COMPARE_CHANNEL_RGB);
5055 
5056         addEntryToConversionDatabase(
5057             getRGB565PixelData(1, GL_UNSIGNED_BYTE, texel888_1[0], texel888_1[1], texel888_1[2]),
5058             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_888_through_565_to_888_tl[0],
5059                                temp_888_through_565_to_888_tl[1], temp_888_through_565_to_888_tl[2]),
5060             getRGB565PixelData(1, GL_UNSIGNED_BYTE, texel888_2[0], texel888_2[1], texel888_2[2]),
5061             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_888_through_565_to_888_tr[0],
5062                                temp_888_through_565_to_888_tr[1], temp_888_through_565_to_888_tr[2]),
5063             getRGB565PixelData(1, GL_UNSIGNED_BYTE, texel888_3[0], texel888_3[1], texel888_3[2]),
5064             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_888_through_565_to_888_bl[0],
5065                                temp_888_through_565_to_888_bl[1], temp_888_through_565_to_888_bl[2]),
5066             getRGB565PixelData(1, GL_UNSIGNED_BYTE, texel888_4[0], texel888_4[1], texel888_4[2]),
5067             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_888_through_565_to_888_br[0],
5068                                temp_888_through_565_to_888_br[1], temp_888_through_565_to_888_br[2]),
5069             PIXEL_COMPARE_CHANNEL_RGB);
5070 
5071         /* GL_RGB565 => GL_LUMINANCE8_OES */
5072         addEntryToConversionDatabase(
5073             getRGB565PixelData(1, GL_UNSIGNED_SHORT_5_6_5, texel565_1[0], texel565_1[1], texel565_1[2]),
5074             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_565_to_888_tl[0]),
5075             getRGB565PixelData(1, GL_UNSIGNED_SHORT_5_6_5, texel565_2[0], texel565_2[1], texel565_2[2]),
5076             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_565_to_888_tr[0]),
5077             getRGB565PixelData(1, GL_UNSIGNED_SHORT_5_6_5, texel565_3[0], texel565_3[1], texel565_3[2]),
5078             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_565_to_888_bl[0]),
5079             getRGB565PixelData(1, GL_UNSIGNED_SHORT_5_6_5, 0, 0, 0), getLuminance8OESPixelData(GL_UNSIGNED_BYTE, 0),
5080             PIXEL_COMPARE_CHANNEL_R);
5081 
5082         addEntryToConversionDatabase(
5083             getRGB565PixelData(1, GL_UNSIGNED_BYTE, texel888_1[0], texel888_1[1], texel888_1[2]),
5084             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_888_through_565_to_888_tl[0]),
5085             getRGB565PixelData(1, GL_UNSIGNED_BYTE, texel888_2[0], texel888_2[1], texel888_2[2]),
5086             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_888_through_565_to_888_tr[0]),
5087             getRGB565PixelData(1, GL_UNSIGNED_BYTE, texel888_3[0], texel888_3[1], texel888_3[2]),
5088             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_888_through_565_to_888_bl[0]),
5089             getRGB565PixelData(1, GL_UNSIGNED_BYTE, texel888_4[0], texel888_4[1], texel888_4[2]),
5090             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_888_through_565_to_888_br[0]), PIXEL_COMPARE_CHANNEL_R);
5091     }
5092 
5093     /* GL_RGBA4 */
5094     {
5095         int texel4444_1[4] = {15, 9, 4, 0};
5096         int texel4444_2[4] = {9, 4, 0, 15};
5097         int texel4444_3[4] = {4, 0, 15, 9};
5098         int texel4444_4[4] = {0, 15, 9, 4};
5099         int texel8888_1[4] = {255, 159, 79, 0};
5100         int texel8888_2[4] = {159, 79, 0, 255};
5101         int texel8888_3[4] = {79, 0, 255, 159};
5102         int texel8888_4[4] = {0, 255, 159, 79};
5103 
5104         int temp_4444_to_565_8888_tl[4]              = {0};
5105         int temp_4444_to_565_8888_tr[4]              = {0};
5106         int temp_4444_to_565_8888_bl[4]              = {0};
5107         int temp_4444_to_565_8888_br[4]              = {0};
5108         int temp_4444_to_8888_tl[4]                  = {0};
5109         int temp_4444_to_8888_tr[4]                  = {0};
5110         int temp_4444_to_8888_bl[4]                  = {0};
5111         int temp_4444_to_8888_br[4]                  = {0};
5112         int temp_8888_through_4444_to_565_tl[4]      = {0};
5113         int temp_8888_through_4444_to_565_tr[4]      = {0};
5114         int temp_8888_through_4444_to_565_bl[4]      = {0};
5115         int temp_8888_through_4444_to_565_br[4]      = {0};
5116         int temp_8888_through_4444_to_8888_tl[4]     = {0};
5117         int temp_8888_through_4444_to_8888_tr[4]     = {0};
5118         int temp_8888_through_4444_to_8888_bl[4]     = {0};
5119         int temp_8888_through_4444_to_8888_br[4]     = {0};
5120         int temp_8888_through_4444_565_to_8888_tl[4] = {0};
5121         int temp_8888_through_4444_565_to_8888_tr[4] = {0};
5122         int temp_8888_through_4444_565_to_8888_bl[4] = {0};
5123         int temp_8888_through_4444_565_to_8888_br[4] = {0};
5124 
5125         convertNormalizedUnsignedFixedPoint(bits_4444, bits_565, bits_8888, bits_8888, texel4444_1,
5126                                             temp_4444_to_565_8888_tl);
5127         convertNormalizedUnsignedFixedPoint(bits_4444, bits_565, bits_8888, bits_8888, texel4444_2,
5128                                             temp_4444_to_565_8888_tr);
5129         convertNormalizedUnsignedFixedPoint(bits_4444, bits_565, bits_8888, bits_8888, texel4444_3,
5130                                             temp_4444_to_565_8888_bl);
5131         convertNormalizedUnsignedFixedPoint(bits_4444, bits_565, bits_8888, bits_8888, texel4444_4,
5132                                             temp_4444_to_565_8888_br);
5133 
5134         convertNormalizedUnsignedFixedPoint(bits_4444, bits_8888, bits_8888, bits_8888, texel4444_1,
5135                                             temp_4444_to_8888_tl);
5136         convertNormalizedUnsignedFixedPoint(bits_4444, bits_8888, bits_8888, bits_8888, texel4444_2,
5137                                             temp_4444_to_8888_tr);
5138         convertNormalizedUnsignedFixedPoint(bits_4444, bits_8888, bits_8888, bits_8888, texel4444_3,
5139                                             temp_4444_to_8888_bl);
5140         convertNormalizedUnsignedFixedPoint(bits_4444, bits_8888, bits_8888, bits_8888, texel4444_4,
5141                                             temp_4444_to_8888_br);
5142 
5143         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_565, bits_565, texel8888_1,
5144                                             temp_8888_through_4444_to_565_tl);
5145         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_565, bits_565, texel8888_2,
5146                                             temp_8888_through_4444_to_565_tr);
5147         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_565, bits_565, texel8888_3,
5148                                             temp_8888_through_4444_to_565_bl);
5149         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_565, bits_565, texel8888_4,
5150                                             temp_8888_through_4444_to_565_br);
5151 
5152         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_8888, bits_8888, texel8888_1,
5153                                             temp_8888_through_4444_to_8888_tl);
5154         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_8888, bits_8888, texel8888_2,
5155                                             temp_8888_through_4444_to_8888_tr);
5156         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_8888, bits_8888, texel8888_3,
5157                                             temp_8888_through_4444_to_8888_bl);
5158         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_8888, bits_8888, texel8888_4,
5159                                             temp_8888_through_4444_to_8888_br);
5160 
5161         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_565, bits_8888, texel8888_1,
5162                                             temp_8888_through_4444_565_to_8888_tl);
5163         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_565, bits_8888, texel8888_2,
5164                                             temp_8888_through_4444_565_to_8888_tr);
5165         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_565, bits_8888, texel8888_3,
5166                                             temp_8888_through_4444_565_to_8888_bl);
5167         convertNormalizedUnsignedFixedPoint(bits_8888, bits_4444, bits_565, bits_8888, texel8888_4,
5168                                             temp_8888_through_4444_565_to_8888_br);
5169 
5170         /* GL_RGBA4 => GL_RGBA4 */
5171         addEntryToConversionDatabase(
5172             getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_1[0], texel4444_1[1], texel4444_1[2],
5173                               texel4444_1[3]),
5174             getRGBA4PixelData(0, GL_UNSIGNED_BYTE, temp_4444_to_8888_tl[0], temp_4444_to_8888_tl[1],
5175                               temp_4444_to_8888_tl[2], temp_4444_to_8888_tl[3]),
5176             getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_2[0], texel4444_2[1], texel4444_2[2],
5177                               texel4444_2[3]),
5178             getRGBA4PixelData(0, GL_UNSIGNED_BYTE, temp_4444_to_8888_tr[0], temp_4444_to_8888_tr[1],
5179                               temp_4444_to_8888_tr[2], temp_4444_to_8888_tr[3]),
5180             getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_3[0], texel4444_3[1], texel4444_3[2],
5181                               texel4444_3[3]),
5182             getRGBA4PixelData(0, GL_UNSIGNED_BYTE, temp_4444_to_8888_bl[0], temp_4444_to_8888_bl[1],
5183                               temp_4444_to_8888_bl[2], temp_4444_to_8888_bl[3]),
5184             getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_4[0], texel4444_4[1], texel4444_4[2],
5185                               texel4444_4[3]),
5186             getRGBA4PixelData(0, GL_UNSIGNED_BYTE, temp_4444_to_8888_br[0], temp_4444_to_8888_br[1],
5187                               temp_4444_to_8888_br[2], temp_4444_to_8888_br[3]),
5188             PIXEL_COMPARE_CHANNEL_RGBA);
5189 
5190         addEntryToConversionDatabase(
5191             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel8888_1[0], texel8888_1[1], texel8888_1[2], texel8888_1[3]),
5192             getRGBA4PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_tl[0],
5193                               temp_8888_through_4444_to_8888_tl[1], temp_8888_through_4444_to_8888_tl[2],
5194                               temp_8888_through_4444_to_8888_tl[3]),
5195             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel8888_2[0], texel8888_2[1], texel8888_2[2], texel8888_2[3]),
5196             getRGBA4PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_tr[0],
5197                               temp_8888_through_4444_to_8888_tr[1], temp_8888_through_4444_to_8888_tr[2],
5198                               temp_8888_through_4444_to_8888_tr[3]),
5199             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel8888_3[0], texel8888_3[1], texel8888_3[2], texel8888_3[3]),
5200             getRGBA4PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_bl[0],
5201                               temp_8888_through_4444_to_8888_bl[1], temp_8888_through_4444_to_8888_bl[2],
5202                               temp_8888_through_4444_to_8888_bl[3]),
5203             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel8888_4[0], texel8888_4[1], texel8888_4[2], texel8888_4[3]),
5204             getRGBA4PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_br[0],
5205                               temp_8888_through_4444_to_8888_br[1], temp_8888_through_4444_to_8888_br[2],
5206                               temp_8888_through_4444_to_8888_br[3]),
5207             PIXEL_COMPARE_CHANNEL_RGBA);
5208 
5209         /* GL_RGBA4 => GL_RGB565 */
5210         addEntryToConversionDatabase(getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_1[0], texel4444_1[1],
5211                                                        texel4444_1[2], texel4444_1[3]),
5212                                      getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_4444_to_565_8888_tl[0],
5213                                                         temp_4444_to_565_8888_tl[1], temp_4444_to_565_8888_tl[2]),
5214                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_2[0], texel4444_2[1],
5215                                                        texel4444_2[2], texel4444_2[3]),
5216                                      getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_4444_to_565_8888_tr[0],
5217                                                         temp_4444_to_565_8888_tr[1], temp_4444_to_565_8888_tr[2]),
5218                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_3[0], texel4444_3[1],
5219                                                        texel4444_3[2], texel4444_3[3]),
5220                                      getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_4444_to_565_8888_bl[0],
5221                                                         temp_4444_to_565_8888_bl[1], temp_4444_to_565_8888_bl[2]),
5222                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_4[0], texel4444_4[1],
5223                                                        texel4444_4[2], texel4444_4[3]),
5224                                      getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_4444_to_565_8888_br[0],
5225                                                         temp_4444_to_565_8888_br[1], temp_4444_to_565_8888_br[2]),
5226                                      PIXEL_COMPARE_CHANNEL_RGB);
5227 
5228         addEntryToConversionDatabase(
5229             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel8888_1[0], texel8888_1[1], texel8888_1[2], texel8888_1[3]),
5230             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_4444_565_to_8888_tl[0],
5231                                temp_8888_through_4444_565_to_8888_tl[1], temp_8888_through_4444_565_to_8888_tl[2]),
5232             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel8888_2[0], texel8888_2[1], texel8888_2[2], texel8888_2[3]),
5233             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_4444_565_to_8888_tr[0],
5234                                temp_8888_through_4444_565_to_8888_tr[1], temp_8888_through_4444_565_to_8888_tr[2]),
5235             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel8888_3[0], texel8888_3[1], texel8888_3[2], texel8888_3[3]),
5236             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_4444_565_to_8888_bl[0],
5237                                temp_8888_through_4444_565_to_8888_bl[1], temp_8888_through_4444_565_to_8888_bl[2]),
5238             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel8888_4[0], texel8888_4[1], texel8888_4[2], texel8888_4[3]),
5239             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_4444_565_to_8888_br[0],
5240                                temp_8888_through_4444_565_to_8888_br[1], temp_8888_through_4444_565_to_8888_br[2]),
5241             PIXEL_COMPARE_CHANNEL_RGB);
5242 
5243         /* GL_RGBA4 => GL_LUMINANCE8_ALPHA8_OES */
5244         addEntryToConversionDatabase(
5245             getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_1[0], texel4444_1[1], texel4444_1[2],
5246                               texel4444_1[3]),
5247             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_tl[0], temp_4444_to_8888_tl[3]),
5248             getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_2[0], texel4444_2[1], texel4444_2[2],
5249                               texel4444_2[3]),
5250             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_tr[0], temp_4444_to_8888_tr[3]),
5251             getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_3[0], texel4444_3[1], texel4444_3[2],
5252                               texel4444_3[3]),
5253             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_bl[0], temp_4444_to_8888_bl[3]),
5254             getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_4[0], texel4444_4[1], texel4444_4[2],
5255                               texel4444_4[3]),
5256             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_br[0], temp_4444_to_8888_br[3]),
5257             PIXEL_COMPARE_CHANNEL_RA);
5258 
5259         addEntryToConversionDatabase(
5260             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_1[0], texel4444_1[1], texel4444_1[2], texel4444_1[3]),
5261             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_tl[0],
5262                                             temp_8888_through_4444_to_8888_tl[3]),
5263             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_2[0], texel4444_2[1], texel4444_2[2], texel4444_2[3]),
5264             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_tr[0],
5265                                             temp_8888_through_4444_to_8888_tr[3]),
5266             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_3[0], texel4444_3[1], texel4444_3[2], texel4444_3[3]),
5267             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_bl[0],
5268                                             temp_8888_through_4444_to_8888_bl[3]),
5269             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_4[0], texel4444_4[1], texel4444_4[2], texel4444_4[3]),
5270             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_br[0],
5271                                             temp_8888_through_4444_to_8888_br[3]),
5272             PIXEL_COMPARE_CHANNEL_RA);
5273 
5274         /* GL_RGBA4 => GL_LUMINANCE8_OES */
5275         addEntryToConversionDatabase(getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_1[0], texel4444_1[1],
5276                                                        texel4444_1[2], texel4444_1[3]),
5277                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_tl[0]),
5278                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_2[0], texel4444_2[1],
5279                                                        texel4444_2[2], texel4444_2[3]),
5280                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_tr[0]),
5281                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_3[0], texel4444_3[1],
5282                                                        texel4444_3[2], texel4444_3[3]),
5283                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_bl[0]),
5284                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_4[0], texel4444_4[1],
5285                                                        texel4444_4[2], texel4444_4[3]),
5286                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_br[0]),
5287                                      PIXEL_COMPARE_CHANNEL_R);
5288 
5289         addEntryToConversionDatabase(
5290             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_1[0], texel4444_1[1], texel4444_1[2], texel4444_1[3]),
5291             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_tl[0]),
5292             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_2[0], texel4444_2[1], texel4444_2[2], texel4444_2[3]),
5293             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_tr[0]),
5294             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_3[0], texel4444_3[1], texel4444_3[2], texel4444_3[3]),
5295             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_bl[0]),
5296             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_4[0], texel4444_4[1], texel4444_4[2], texel4444_4[3]),
5297             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_br[0]), PIXEL_COMPARE_CHANNEL_R);
5298 
5299         /* GL_RGBA4 => GL_ALPHA8_OES */
5300         addEntryToConversionDatabase(getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_1[0], texel4444_1[1],
5301                                                        texel4444_1[2], texel4444_1[3]),
5302                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_tl[3]),
5303                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_2[0], texel4444_2[1],
5304                                                        texel4444_2[2], texel4444_2[3]),
5305                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_tr[3]),
5306                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_3[0], texel4444_3[1],
5307                                                        texel4444_3[2], texel4444_3[3]),
5308                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_bl[3]),
5309                                      getRGBA4PixelData(1, GL_UNSIGNED_SHORT_4_4_4_4, texel4444_4[0], texel4444_4[1],
5310                                                        texel4444_4[2], texel4444_4[3]),
5311                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_4444_to_8888_br[3]),
5312                                      PIXEL_COMPARE_CHANNEL_A);
5313 
5314         addEntryToConversionDatabase(
5315             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_1[0], texel4444_1[1], texel4444_1[2], texel4444_1[3]),
5316             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_tl[3]),
5317             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_2[0], texel4444_2[1], texel4444_2[2], texel4444_2[3]),
5318             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_tr[3]),
5319             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_3[0], texel4444_3[1], texel4444_3[2], texel4444_3[3]),
5320             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_bl[3]),
5321             getRGBA4PixelData(1, GL_UNSIGNED_BYTE, texel4444_4[0], texel4444_4[1], texel4444_4[2], texel4444_4[3]),
5322             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_4444_to_8888_br[3]), PIXEL_COMPARE_CHANNEL_A);
5323     }
5324 
5325     /* GL_RGB5_A1 */
5326     {
5327         int texel2101010_1[4] = {1023, 703, 383, 2};
5328         int texel2101010_2[4] = {703, 383, 0, 0};
5329         int texel2101010_3[4] = {383, 0, 1023, 2};
5330         int texel2101010_4[4] = {0, 1023, 703, 0};
5331         int texel5551_1[4]    = {31, 21, 11, 1};
5332         int texel5551_2[4]    = {21, 11, 0, 0};
5333         int texel5551_3[4]    = {11, 0, 31, 1};
5334         int texel5551_4[4]    = {0, 31, 21, 0};
5335         int texel8888_1[4]    = {255, 207, 95, 255};
5336         int texel8888_2[4]    = {207, 95, 0, 0};
5337         int texel8888_3[4]    = {95, 0, 255, 255};
5338         int texel8888_4[4]    = {0, 255, 207, 0};
5339 
5340         int temp_2101010rev_through_5551_to_8888_tl[4]     = {0};
5341         int temp_2101010rev_through_5551_to_8888_tr[4]     = {0};
5342         int temp_2101010rev_through_5551_to_8888_bl[4]     = {0};
5343         int temp_2101010rev_through_5551_to_8888_br[4]     = {0};
5344         int temp_2101010rev_through_5551_565_to_8888_tl[4] = {0};
5345         int temp_2101010rev_through_5551_565_to_8888_tr[4] = {0};
5346         int temp_2101010rev_through_5551_565_to_8888_bl[4] = {0};
5347         int temp_2101010rev_through_5551_565_to_8888_br[4] = {0};
5348         int temp_5551_to_8888_tl[4]                        = {0};
5349         int temp_5551_to_8888_tr[4]                        = {0};
5350         int temp_5551_to_8888_bl[4]                        = {0};
5351         int temp_5551_to_8888_br[4]                        = {0};
5352         int temp_5551_through_565_to_8888_tl[4]            = {0};
5353         int temp_5551_through_565_to_8888_tr[4]            = {0};
5354         int temp_5551_through_565_to_8888_bl[4]            = {0};
5355         int temp_5551_through_565_to_8888_br[4]            = {0};
5356         int temp_8888_through_5551_to_8888_tl[4]           = {0};
5357         int temp_8888_through_5551_to_8888_tr[4]           = {0};
5358         int temp_8888_through_5551_to_8888_bl[4]           = {0};
5359         int temp_8888_through_5551_to_8888_br[4]           = {0};
5360         int temp_8888_through_5551_565_to_8888_tl[4]       = {0};
5361         int temp_8888_through_5551_565_to_8888_tr[4]       = {0};
5362         int temp_8888_through_5551_565_to_8888_bl[4]       = {0};
5363         int temp_8888_through_5551_565_to_8888_br[4]       = {0};
5364 
5365         convertNormalizedUnsignedFixedPoint(bits_1010102, bits_5551, bits_8888, bits_8888, texel2101010_1,
5366                                             temp_2101010rev_through_5551_to_8888_tl);
5367         convertNormalizedUnsignedFixedPoint(bits_1010102, bits_5551, bits_8888, bits_8888, texel2101010_2,
5368                                             temp_2101010rev_through_5551_to_8888_tr);
5369         convertNormalizedUnsignedFixedPoint(bits_1010102, bits_5551, bits_8888, bits_8888, texel2101010_3,
5370                                             temp_2101010rev_through_5551_to_8888_bl);
5371         convertNormalizedUnsignedFixedPoint(bits_1010102, bits_5551, bits_8888, bits_8888, texel2101010_4,
5372                                             temp_2101010rev_through_5551_to_8888_br);
5373 
5374         convertNormalizedUnsignedFixedPoint(bits_1010102, bits_5551, bits_565, bits_8888, texel2101010_1,
5375                                             temp_2101010rev_through_5551_565_to_8888_tl);
5376         convertNormalizedUnsignedFixedPoint(bits_1010102, bits_5551, bits_565, bits_8888, texel2101010_2,
5377                                             temp_2101010rev_through_5551_565_to_8888_tr);
5378         convertNormalizedUnsignedFixedPoint(bits_1010102, bits_5551, bits_565, bits_8888, texel2101010_3,
5379                                             temp_2101010rev_through_5551_565_to_8888_bl);
5380         convertNormalizedUnsignedFixedPoint(bits_1010102, bits_5551, bits_565, bits_8888, texel2101010_4,
5381                                             temp_2101010rev_through_5551_565_to_8888_br);
5382 
5383         convertNormalizedUnsignedFixedPoint(bits_5551, bits_8888, bits_8888, bits_8888, texel5551_1,
5384                                             temp_5551_to_8888_tl);
5385         convertNormalizedUnsignedFixedPoint(bits_5551, bits_8888, bits_8888, bits_8888, texel5551_2,
5386                                             temp_5551_to_8888_tr);
5387         convertNormalizedUnsignedFixedPoint(bits_5551, bits_8888, bits_8888, bits_8888, texel5551_3,
5388                                             temp_5551_to_8888_bl);
5389         convertNormalizedUnsignedFixedPoint(bits_5551, bits_8888, bits_8888, bits_8888, texel5551_4,
5390                                             temp_5551_to_8888_br);
5391 
5392         convertNormalizedUnsignedFixedPoint(bits_8888, bits_5551, bits_8888, bits_8888, texel8888_1,
5393                                             temp_8888_through_5551_to_8888_tl);
5394         convertNormalizedUnsignedFixedPoint(bits_8888, bits_5551, bits_8888, bits_8888, texel8888_2,
5395                                             temp_8888_through_5551_to_8888_tr);
5396         convertNormalizedUnsignedFixedPoint(bits_8888, bits_5551, bits_8888, bits_8888, texel8888_3,
5397                                             temp_8888_through_5551_to_8888_bl);
5398         convertNormalizedUnsignedFixedPoint(bits_8888, bits_5551, bits_8888, bits_8888, texel8888_4,
5399                                             temp_8888_through_5551_to_8888_br);
5400 
5401         convertNormalizedUnsignedFixedPoint(bits_8888, bits_5551, bits_565, bits_8888, texel8888_1,
5402                                             temp_8888_through_5551_565_to_8888_tl);
5403         convertNormalizedUnsignedFixedPoint(bits_8888, bits_5551, bits_565, bits_8888, texel8888_2,
5404                                             temp_8888_through_5551_565_to_8888_tr);
5405         convertNormalizedUnsignedFixedPoint(bits_8888, bits_5551, bits_565, bits_8888, texel8888_3,
5406                                             temp_8888_through_5551_565_to_8888_bl);
5407         convertNormalizedUnsignedFixedPoint(bits_8888, bits_5551, bits_565, bits_8888, texel8888_4,
5408                                             temp_8888_through_5551_565_to_8888_br);
5409 
5410         convertNormalizedUnsignedFixedPoint(bits_5551, bits_565, bits_8888, bits_8888, texel5551_1,
5411                                             temp_5551_through_565_to_8888_tl);
5412         convertNormalizedUnsignedFixedPoint(bits_5551, bits_565, bits_8888, bits_8888, texel5551_2,
5413                                             temp_5551_through_565_to_8888_tr);
5414         convertNormalizedUnsignedFixedPoint(bits_5551, bits_565, bits_8888, bits_8888, texel5551_3,
5415                                             temp_5551_through_565_to_8888_bl);
5416         convertNormalizedUnsignedFixedPoint(bits_5551, bits_565, bits_8888, bits_8888, texel5551_4,
5417                                             temp_5551_through_565_to_8888_br);
5418 
5419         /* GL_RGB5_A1 => GL_RGB5_A1 */
5420         addEntryToConversionDatabase(
5421             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_1[0], texel8888_1[1], texel8888_1[2], texel8888_1[3]),
5422             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_tl[0],
5423                                temp_8888_through_5551_to_8888_tl[1], temp_8888_through_5551_to_8888_tl[2],
5424                                temp_8888_through_5551_to_8888_tl[3]),
5425             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_2[0], texel8888_2[1], texel8888_2[2], texel8888_2[3]),
5426             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_tr[0],
5427                                temp_8888_through_5551_to_8888_tr[1], temp_8888_through_5551_to_8888_tr[2],
5428                                temp_8888_through_5551_to_8888_tr[3]),
5429             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_3[0], texel8888_3[1], texel8888_3[2], texel8888_3[3]),
5430             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_bl[0],
5431                                temp_8888_through_5551_to_8888_bl[1], temp_8888_through_5551_to_8888_bl[2],
5432                                temp_8888_through_5551_to_8888_bl[3]),
5433             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_4[0], texel8888_4[1], texel8888_4[2], texel8888_4[3]),
5434             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_br[0],
5435                                temp_8888_through_5551_to_8888_br[1], temp_8888_through_5551_to_8888_br[2],
5436                                temp_8888_through_5551_to_8888_br[3]),
5437             PIXEL_COMPARE_CHANNEL_RGBA);
5438 
5439         addEntryToConversionDatabase(
5440             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_1[0], texel5551_1[1], texel5551_1[2],
5441                                texel5551_1[3]),
5442             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_5551_to_8888_tl[0], temp_5551_to_8888_tl[1],
5443                                temp_5551_to_8888_tl[2], temp_5551_to_8888_tl[3]),
5444             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_2[0], texel5551_2[1], texel5551_2[2],
5445                                texel5551_2[3]),
5446             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_5551_to_8888_tr[0], temp_5551_to_8888_tr[1],
5447                                temp_5551_to_8888_tr[2], temp_5551_to_8888_tr[3]),
5448             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_3[0], texel5551_3[1], texel5551_3[2],
5449                                texel5551_3[3]),
5450             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_5551_to_8888_bl[0], temp_5551_to_8888_bl[1],
5451                                temp_5551_to_8888_bl[2], temp_5551_to_8888_bl[3]),
5452             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_4[0], texel5551_4[1], texel5551_4[2],
5453                                texel5551_4[3]),
5454             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_5551_to_8888_br[0], temp_5551_to_8888_br[1],
5455                                temp_5551_to_8888_br[2], temp_5551_to_8888_br[3]),
5456             PIXEL_COMPARE_CHANNEL_RGBA);
5457 
5458         addEntryToConversionDatabase(
5459             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_1[0], texel2101010_1[1],
5460                                texel2101010_1[2], texel2101010_1[3]),
5461             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_tl[0],
5462                                temp_2101010rev_through_5551_to_8888_tl[1], temp_2101010rev_through_5551_to_8888_tl[2],
5463                                temp_2101010rev_through_5551_to_8888_tl[3]),
5464             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_2[0], texel2101010_2[1],
5465                                texel2101010_2[2], texel2101010_2[3]),
5466             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_tr[0],
5467                                temp_2101010rev_through_5551_to_8888_tr[1], temp_2101010rev_through_5551_to_8888_tr[2],
5468                                temp_2101010rev_through_5551_to_8888_tr[3]),
5469             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_3[0], texel2101010_3[1],
5470                                texel2101010_3[2], texel2101010_3[3]),
5471             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_bl[0],
5472                                temp_2101010rev_through_5551_to_8888_bl[1], temp_2101010rev_through_5551_to_8888_bl[2],
5473                                temp_2101010rev_through_5551_to_8888_bl[3]),
5474             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_4[0], texel2101010_4[1],
5475                                texel2101010_4[2], texel2101010_4[3]),
5476             getRGB5A1PixelData(0, GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_br[0],
5477                                temp_2101010rev_through_5551_to_8888_br[1], temp_2101010rev_through_5551_to_8888_br[2],
5478                                temp_2101010rev_through_5551_to_8888_br[3]),
5479             PIXEL_COMPARE_CHANNEL_RGBA);
5480 
5481         /* GL_RGB5_A1 => GL_RGB565 */
5482         addEntryToConversionDatabase(
5483             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_1[0], texel8888_1[1], texel8888_1[2], texel8888_1[3]),
5484             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_5551_565_to_8888_tl[0],
5485                                temp_8888_through_5551_565_to_8888_tl[1], temp_8888_through_5551_565_to_8888_tl[2]),
5486             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_2[0], texel8888_2[1], texel8888_2[2], texel8888_2[3]),
5487             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_5551_565_to_8888_tr[0],
5488                                temp_8888_through_5551_565_to_8888_tr[1], temp_8888_through_5551_565_to_8888_tr[2]),
5489             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_3[0], texel8888_3[1], texel8888_3[2], texel8888_3[3]),
5490             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_5551_565_to_8888_bl[0],
5491                                temp_8888_through_5551_565_to_8888_bl[1], temp_8888_through_5551_565_to_8888_bl[2]),
5492             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_4[0], texel8888_4[1], texel8888_4[2], texel8888_4[3]),
5493             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_8888_through_5551_565_to_8888_br[0],
5494                                temp_8888_through_5551_565_to_8888_br[1], temp_8888_through_5551_565_to_8888_br[2]),
5495             PIXEL_COMPARE_CHANNEL_RGB);
5496 
5497         addEntryToConversionDatabase(
5498             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_1[0], texel5551_1[1], texel5551_1[2],
5499                                texel5551_1[3]),
5500             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_5551_through_565_to_8888_tl[0],
5501                                temp_5551_through_565_to_8888_tl[1], temp_5551_through_565_to_8888_tl[2]),
5502             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_2[0], texel5551_2[1], texel5551_2[2],
5503                                texel5551_2[3]),
5504             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_5551_through_565_to_8888_tr[0],
5505                                temp_5551_through_565_to_8888_tr[1], temp_5551_through_565_to_8888_tr[2]),
5506             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_3[0], texel5551_3[1], texel5551_3[2],
5507                                texel5551_3[3]),
5508             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_5551_through_565_to_8888_bl[0],
5509                                temp_5551_through_565_to_8888_bl[1], temp_5551_through_565_to_8888_bl[2]),
5510             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_4[0], texel5551_4[1], texel5551_4[2],
5511                                texel5551_4[3]),
5512             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_5551_through_565_to_8888_br[0],
5513                                temp_5551_through_565_to_8888_br[1], temp_5551_through_565_to_8888_br[2]),
5514             PIXEL_COMPARE_CHANNEL_RGB);
5515 
5516         addEntryToConversionDatabase(
5517             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_1[0], texel2101010_1[1],
5518                                texel2101010_1[2], texel2101010_1[3]),
5519             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_565_to_8888_tl[0],
5520                                temp_2101010rev_through_5551_565_to_8888_tl[1],
5521                                temp_2101010rev_through_5551_565_to_8888_tl[2]),
5522             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_2[0], texel2101010_2[1],
5523                                texel2101010_2[2], texel2101010_2[3]),
5524             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_565_to_8888_tr[0],
5525                                temp_2101010rev_through_5551_565_to_8888_tr[1],
5526                                temp_2101010rev_through_5551_565_to_8888_tr[2]),
5527             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_3[0], texel2101010_3[1],
5528                                texel2101010_3[2], texel2101010_3[3]),
5529             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_565_to_8888_bl[0],
5530                                temp_2101010rev_through_5551_565_to_8888_bl[1],
5531                                temp_2101010rev_through_5551_565_to_8888_bl[2]),
5532             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_4[0], texel2101010_4[1],
5533                                texel2101010_4[2], texel2101010_4[3]),
5534             getRGB565PixelData(0, GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_565_to_8888_br[0],
5535                                temp_2101010rev_through_5551_565_to_8888_br[1],
5536                                temp_2101010rev_through_5551_565_to_8888_br[2]),
5537             PIXEL_COMPARE_CHANNEL_RGB);
5538 
5539         /* GL_RGB5_A1 => GL_LUMINANCE8_ALPHA8_OES */
5540         addEntryToConversionDatabase(
5541             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_1[0], texel8888_1[1], texel8888_1[2], texel8888_1[3]),
5542             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_tl[0],
5543                                             temp_8888_through_5551_to_8888_tl[3]),
5544             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_2[0], texel8888_2[1], texel8888_2[2], texel8888_2[3]),
5545             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_tr[0],
5546                                             temp_8888_through_5551_to_8888_tr[3]),
5547             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_3[0], texel8888_3[1], texel8888_3[2], texel8888_3[3]),
5548             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_bl[0],
5549                                             temp_8888_through_5551_to_8888_bl[3]),
5550             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_4[0], texel8888_4[1], texel8888_4[2], texel8888_4[3]),
5551             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_br[0],
5552                                             temp_8888_through_5551_to_8888_br[3]),
5553             PIXEL_COMPARE_CHANNEL_RA);
5554 
5555         addEntryToConversionDatabase(
5556             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_1[0], texel5551_1[1], texel5551_1[2],
5557                                texel5551_1[3]),
5558             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_tl[0], temp_5551_to_8888_tl[3]),
5559             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_2[0], texel5551_2[1], texel5551_2[2],
5560                                texel5551_2[3]),
5561             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_tr[0], temp_5551_to_8888_tr[3]),
5562             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_3[0], texel5551_3[1], texel5551_3[2],
5563                                texel5551_3[3]),
5564             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_bl[0], temp_5551_to_8888_bl[3]),
5565             getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_4[0], texel5551_4[1], texel5551_4[2],
5566                                texel5551_4[3]),
5567             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_br[0], temp_5551_to_8888_br[3]),
5568             PIXEL_COMPARE_CHANNEL_RA);
5569 
5570         addEntryToConversionDatabase(
5571             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_1[0], texel2101010_1[1],
5572                                texel2101010_1[2], texel2101010_1[3]),
5573             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_tl[0],
5574                                             temp_2101010rev_through_5551_to_8888_tl[3]),
5575             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_2[0], texel2101010_2[1],
5576                                texel2101010_2[2], texel2101010_2[3]),
5577             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_tr[0],
5578                                             temp_2101010rev_through_5551_to_8888_tr[3]),
5579             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_3[0], texel2101010_3[1],
5580                                texel2101010_3[2], texel2101010_3[3]),
5581             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_bl[0],
5582                                             temp_2101010rev_through_5551_to_8888_bl[3]),
5583             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_4[0], texel2101010_4[1],
5584                                texel2101010_4[2], texel2101010_4[3]),
5585             getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_br[0],
5586                                             temp_2101010rev_through_5551_to_8888_br[3]),
5587             PIXEL_COMPARE_CHANNEL_RA);
5588 
5589         /* GL_RGB5_A1 => GL_LUMINANCE8_OES */
5590         addEntryToConversionDatabase(
5591             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_1[0], texel8888_1[1], texel8888_1[2], texel8888_1[3]),
5592             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_tl[0]),
5593             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_2[0], texel8888_2[1], texel8888_2[2], texel8888_2[3]),
5594             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_tr[0]),
5595             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_3[0], texel8888_3[1], texel8888_3[2], texel8888_3[3]),
5596             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_bl[0]),
5597             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_4[0], texel8888_4[1], texel8888_4[2], texel8888_4[3]),
5598             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_br[0]), PIXEL_COMPARE_CHANNEL_R);
5599 
5600         addEntryToConversionDatabase(getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_1[0], texel5551_1[1],
5601                                                         texel5551_1[2], texel5551_1[3]),
5602                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_tl[0]),
5603                                      getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_2[0], texel5551_2[1],
5604                                                         texel5551_2[2], texel5551_2[3]),
5605                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_tr[0]),
5606                                      getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_3[0], texel5551_3[1],
5607                                                         texel5551_3[2], texel5551_3[3]),
5608                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_bl[0]),
5609                                      getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_4[0], texel5551_4[1],
5610                                                         texel5551_4[2], texel5551_4[3]),
5611                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_br[0]),
5612                                      PIXEL_COMPARE_CHANNEL_R);
5613 
5614         addEntryToConversionDatabase(
5615             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_1[0], texel2101010_1[1],
5616                                texel2101010_1[2], texel2101010_1[3]),
5617             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_tl[0]),
5618             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_2[0], texel2101010_2[1],
5619                                texel2101010_2[2], texel2101010_2[3]),
5620             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_tr[0]),
5621             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_3[0], texel2101010_3[1],
5622                                texel2101010_3[2], texel2101010_3[3]),
5623             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_bl[0]),
5624             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_4[0], texel2101010_4[1],
5625                                texel2101010_4[2], texel2101010_4[3]),
5626             getLuminance8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_br[0]),
5627             PIXEL_COMPARE_CHANNEL_R);
5628 
5629         /* GL_RGB5_A1 => GL_ALPHA8_OES */
5630         addEntryToConversionDatabase(
5631             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_1[0], texel8888_1[1], texel8888_1[2], texel8888_1[3]),
5632             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_tl[3]),
5633             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_2[0], texel8888_2[1], texel8888_2[2], texel8888_2[3]),
5634             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_tr[3]),
5635             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_3[0], texel8888_3[1], texel8888_3[2], texel8888_3[3]),
5636             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_bl[3]),
5637             getRGB5A1PixelData(1, GL_UNSIGNED_BYTE, texel8888_4[0], texel8888_4[1], texel8888_4[2], texel8888_4[3]),
5638             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_8888_through_5551_to_8888_br[3]), PIXEL_COMPARE_CHANNEL_A);
5639 
5640         addEntryToConversionDatabase(getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_1[0], texel5551_1[1],
5641                                                         texel5551_1[2], texel5551_1[3]),
5642                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_tl[3]),
5643                                      getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_2[0], texel5551_2[1],
5644                                                         texel5551_2[2], texel5551_2[3]),
5645                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_tr[3]),
5646                                      getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_3[0], texel5551_3[1],
5647                                                         texel5551_3[2], texel5551_3[3]),
5648                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_bl[3]),
5649                                      getRGB5A1PixelData(1, GL_UNSIGNED_SHORT_5_5_5_1, texel5551_4[0], texel5551_4[1],
5650                                                         texel5551_4[2], texel5551_4[3]),
5651                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_5551_to_8888_br[3]),
5652                                      PIXEL_COMPARE_CHANNEL_A);
5653 
5654         addEntryToConversionDatabase(
5655             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_1[0], texel2101010_1[1],
5656                                texel2101010_1[2], texel2101010_1[3]),
5657             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_tl[3]),
5658             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_2[0], texel2101010_2[1],
5659                                texel2101010_2[2], texel2101010_2[3]),
5660             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_tr[3]),
5661             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_3[0], texel2101010_3[1],
5662                                texel2101010_3[2], texel2101010_3[3]),
5663             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_bl[3]),
5664             getRGB5A1PixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2101010_4[0], texel2101010_4[1],
5665                                texel2101010_4[2], texel2101010_4[3]),
5666             getAlpha8OESPixelData(GL_UNSIGNED_BYTE, temp_2101010rev_through_5551_to_8888_br[3]),
5667             PIXEL_COMPARE_CHANNEL_A);
5668     }
5669 
5670     /* GL_RGBA8 */
5671     {
5672         const unsigned char texel1[4] = {255, 127, 63, 0};
5673         const unsigned char texel2[4] = {127, 63, 0, 255};
5674         const unsigned char texel3[4] = {63, 0, 255, 127};
5675         const unsigned char texel4[4] = {0, 255, 127, 63};
5676 
5677         /* GL_RGBA8 => GL_RGBA8 */
5678         addEntryToConversionDatabase(getRGBA8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5679                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5680                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5681                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5682                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5683                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5684                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5685                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5686                                      PIXEL_COMPARE_CHANNEL_RGBA);
5687 
5688         /* GL_RGBA8 => GL_RGB8 */
5689         addEntryToConversionDatabase(getRGBA8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5690                                      getRGB8PixelData(0, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2]),
5691                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5692                                      getRGB8PixelData(0, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2]),
5693                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5694                                      getRGB8PixelData(0, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2]),
5695                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5696                                      getRGB8PixelData(0, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2]),
5697                                      PIXEL_COMPARE_CHANNEL_RGB);
5698 
5699         /* GL_RGBA8 => GL_LUMINANCE8_ALPHA8_OES */
5700         addEntryToConversionDatabase(getRGBA8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5701                                      getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[3]),
5702                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5703                                      getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[3]),
5704                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5705                                      getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[3]),
5706                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5707                                      getLuminance8Alpha8OESPixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[3]),
5708                                      PIXEL_COMPARE_CHANNEL_RA);
5709 
5710         /* GL_RGBA8 => GL_LUMINANCE8_OES */
5711         addEntryToConversionDatabase(getRGBA8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5712                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel1[0]),
5713                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5714                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel2[0]),
5715                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5716                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel3[0]),
5717                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5718                                      getLuminance8OESPixelData(GL_UNSIGNED_BYTE, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
5719 
5720         /* GL_RGBA8 => GL_ALPHA8_OES */
5721         addEntryToConversionDatabase(getRGBA8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5722                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, texel1[3]),
5723                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5724                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, texel2[3]),
5725                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5726                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, texel3[3]),
5727                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5728                                      getAlpha8OESPixelData(GL_UNSIGNED_BYTE, texel4[3]), PIXEL_COMPARE_CHANNEL_A);
5729 
5730         /* GL_RGBA8 => GL_R8 */
5731         addEntryToConversionDatabase(getRGBA8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5732                                      getR8PixelData(0, GL_UNSIGNED_BYTE, texel1[0]),
5733                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5734                                      getR8PixelData(0, GL_UNSIGNED_BYTE, texel2[0]),
5735                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5736                                      getR8PixelData(0, GL_UNSIGNED_BYTE, texel3[0]),
5737                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5738                                      getR8PixelData(0, GL_UNSIGNED_BYTE, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
5739 
5740         /* GL_RGBA8 => GL_RG8 */
5741         addEntryToConversionDatabase(getRGBA8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5742                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel1[0], texel1[1]),
5743                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5744                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel2[0], texel2[1]),
5745                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5746                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel3[0], texel3[1]),
5747                                      getRGBA8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5748                                      getRG8PixelData(0, GL_UNSIGNED_BYTE, texel4[0], texel4[1]),
5749                                      PIXEL_COMPARE_CHANNEL_RG);
5750     }
5751 
5752     /* GL_RGB10_A2 */
5753     {
5754         const unsigned short texel1[4] = {1023, 682, 341, 3};
5755         const unsigned short texel2[4] = {682, 341, 0, 2};
5756         const unsigned short texel3[4] = {341, 0, 1023, 1};
5757         const unsigned short texel4[4] = {0, 1023, 682, 0};
5758 
5759         /* GL_RGB10_A2 => GL_RGB10_A2 */
5760         addEntryToConversionDatabase(getRGB10A2PixelData(GL_UNSIGNED_INT_2_10_10_10_REV, texel1[0], texel1[1],
5761                                                          texel1[2], (unsigned char)texel1[3]),
5762                                      getRGB10A2PixelData(GL_UNSIGNED_INT_2_10_10_10_REV, texel1[0], texel1[1],
5763                                                          texel1[2], (unsigned char)texel1[3]),
5764                                      getRGB10A2PixelData(GL_UNSIGNED_INT_2_10_10_10_REV, texel2[0], texel2[1],
5765                                                          texel2[2], (unsigned char)texel2[3]),
5766                                      getRGB10A2PixelData(GL_UNSIGNED_INT_2_10_10_10_REV, texel2[0], texel2[1],
5767                                                          texel2[2], (unsigned char)texel2[3]),
5768                                      getRGB10A2PixelData(GL_UNSIGNED_INT_2_10_10_10_REV, texel3[0], texel3[1],
5769                                                          texel3[2], (unsigned char)texel3[3]),
5770                                      getRGB10A2PixelData(GL_UNSIGNED_INT_2_10_10_10_REV, texel3[0], texel3[1],
5771                                                          texel3[2], (unsigned char)texel3[3]),
5772                                      getRGB10A2PixelData(GL_UNSIGNED_INT_2_10_10_10_REV, texel4[0], texel4[1],
5773                                                          texel4[2], (unsigned char)texel4[3]),
5774                                      getRGB10A2PixelData(GL_UNSIGNED_INT_2_10_10_10_REV, texel4[0], texel4[1],
5775                                                          texel4[2], (unsigned char)texel4[3]),
5776                                      PIXEL_COMPARE_CHANNEL_RGBA);
5777     }
5778 
5779     /* GL_RGB10_A2UI */
5780     {
5781         const unsigned short texel1[4] = {1023, 682, 341, 3};
5782         const unsigned short texel2[4] = {682, 341, 0, 2};
5783         const unsigned short texel3[4] = {341, 0, 1023, 1};
5784         const unsigned short texel4[4] = {0, 1023, 682, 0};
5785 
5786         /* GL_RGB10_A2UI => GL_RGB10_A2UI */
5787         addEntryToConversionDatabase(
5788             getRGB10A2UIPixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel1[0], texel1[1], texel1[2], texel1[3]),
5789             getRGB10A2UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
5790             getRGB10A2UIPixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel2[0], texel2[1], texel2[2], texel2[3]),
5791             getRGB10A2UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
5792             getRGB10A2UIPixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel3[0], texel3[1], texel3[2], texel3[3]),
5793             getRGB10A2UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
5794             getRGB10A2UIPixelData(1, GL_UNSIGNED_INT_2_10_10_10_REV, texel4[0], texel4[1], texel4[2], texel4[3]),
5795             getRGB10A2UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
5796             PIXEL_COMPARE_CHANNEL_RGBA);
5797     }
5798 
5799     /* GL_SRGB8_ALPHA8 */
5800     {
5801         const unsigned char texel1[4] = {255, 127, 63, 0};
5802         const unsigned char texel2[4] = {127, 63, 0, 255};
5803         const unsigned char texel3[4] = {63, 0, 255, 127};
5804         const unsigned char texel4[4] = {0, 255, 127, 63};
5805 
5806         /* GL_SRGB8_ALPHA8 => GL_SRGB8 */
5807         addEntryToConversionDatabase(
5808             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5809             getSRGB8PixelData(0, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2]),
5810             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5811             getSRGB8PixelData(0, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2]),
5812             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5813             getSRGB8PixelData(0, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2]),
5814             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5815             getSRGB8PixelData(0, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2]), PIXEL_COMPARE_CHANNEL_RGB);
5816 
5817         /* GL_SRGB8_ALPHA8 => GL_SRGB8_ALPHA8 */
5818         addEntryToConversionDatabase(
5819             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5820             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
5821             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5822             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
5823             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5824             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
5825             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5826             getSRGB8Alpha8PixelData(GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
5827             PIXEL_COMPARE_CHANNEL_RGBA);
5828     }
5829 
5830     /* GL_R8I */
5831     {
5832         const signed char texel1[1] = {127};
5833         const signed char texel2[1] = {42};
5834         const signed char texel3[1] = {-43};
5835         const signed char texel4[1] = {-127};
5836 
5837         /* GL_R8I => GL_R8I */
5838         addEntryToConversionDatabase(getR8IPixelData(1, GL_BYTE, texel1[0]), getR8IPixelData(0, GL_INT, texel1[0]),
5839                                      getR8IPixelData(1, GL_BYTE, texel2[0]), getR8IPixelData(0, GL_INT, texel2[0]),
5840                                      getR8IPixelData(1, GL_BYTE, texel3[0]), getR8IPixelData(0, GL_INT, texel3[0]),
5841                                      getR8IPixelData(1, GL_BYTE, texel4[0]), getR8IPixelData(0, GL_INT, texel4[0]),
5842                                      PIXEL_COMPARE_CHANNEL_R);
5843     }
5844 
5845     /* GL_R8UI */
5846     {
5847         const unsigned char texel1[1] = {255};
5848         const unsigned char texel2[1] = {127};
5849         const unsigned char texel3[1] = {63};
5850         const unsigned char texel4[1] = {0};
5851 
5852         /* GL_R8UI => GL_R8UI */
5853         addEntryToConversionDatabase(
5854             getR8UIPixelData(1, GL_UNSIGNED_BYTE, texel1[0]), getR8UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
5855             getR8UIPixelData(1, GL_UNSIGNED_BYTE, texel2[0]), getR8UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
5856             getR8UIPixelData(1, GL_UNSIGNED_BYTE, texel3[0]), getR8UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
5857             getR8UIPixelData(1, GL_UNSIGNED_BYTE, texel4[0]), getR8UIPixelData(0, GL_UNSIGNED_INT, texel4[0]),
5858             PIXEL_COMPARE_CHANNEL_R);
5859     }
5860 
5861     /* GL_R16I */
5862     {
5863         const signed short texel1[1] = {32767};
5864         const signed short texel2[1] = {10922};
5865         const signed short texel3[1] = {-10923};
5866         const signed short texel4[1] = {-32767};
5867 
5868         /* GL_R16I => GL_R16I */
5869         addEntryToConversionDatabase(getR16IPixelData(1, GL_SHORT, texel1[0]), getR16IPixelData(0, GL_INT, texel1[0]),
5870                                      getR16IPixelData(1, GL_SHORT, texel2[0]), getR16IPixelData(0, GL_INT, texel2[0]),
5871                                      getR16IPixelData(1, GL_SHORT, texel3[0]), getR16IPixelData(0, GL_INT, texel3[0]),
5872                                      getR16IPixelData(1, GL_SHORT, texel4[0]), getR16IPixelData(0, GL_INT, texel4[0]),
5873                                      PIXEL_COMPARE_CHANNEL_R);
5874     }
5875 
5876     /* GL_R16UI */
5877     {
5878         const unsigned short texel1[1] = {65535};
5879         const unsigned short texel2[1] = {43690};
5880         const unsigned short texel3[1] = {21845};
5881         const unsigned short texel4[1] = {0};
5882 
5883         /* GL_R16UI => GL_R16UI */
5884         addEntryToConversionDatabase(
5885             getR16UIPixelData(1, GL_UNSIGNED_SHORT, texel1[0]), getR16UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
5886             getR16UIPixelData(1, GL_UNSIGNED_SHORT, texel2[0]), getR16UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
5887             getR16UIPixelData(1, GL_UNSIGNED_SHORT, texel3[0]), getR16UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
5888             getR16UIPixelData(1, GL_UNSIGNED_SHORT, texel4[0]), getR16UIPixelData(0, GL_UNSIGNED_INT, texel4[0]),
5889             PIXEL_COMPARE_CHANNEL_R);
5890     }
5891 
5892     /* GL_R32I */
5893     {
5894         const int texel1[1] = {2147483647l};
5895         const int texel2[1] = {715827883l};
5896         const int texel3[1] = {-715827881l};
5897         const int texel4[1] = {-2147483647l};
5898 
5899         /* GL_R32I => GL_R32I */
5900         addEntryToConversionDatabase(getR32IPixelData(1, GL_INT, texel1[0]), getR32IPixelData(0, GL_INT, texel1[0]),
5901                                      getR32IPixelData(1, GL_INT, texel2[0]), getR32IPixelData(0, GL_INT, texel2[0]),
5902                                      getR32IPixelData(1, GL_INT, texel3[0]), getR32IPixelData(0, GL_INT, texel3[0]),
5903                                      getR32IPixelData(1, GL_INT, texel4[0]), getR32IPixelData(0, GL_INT, texel4[0]),
5904                                      PIXEL_COMPARE_CHANNEL_R);
5905     }
5906 
5907     /* GL_R32UI */
5908     {
5909         const unsigned int texel1[1] = {4294967295u};
5910         const unsigned int texel2[1] = {2863311530u};
5911         const unsigned int texel3[1] = {1431655765u};
5912         const unsigned int texel4[1] = {0};
5913 
5914         /* GL_R32UI => GL_R32UI */
5915         addEntryToConversionDatabase(
5916             getR32UIPixelData(1, GL_UNSIGNED_INT, texel1[0]), getR32UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
5917             getR32UIPixelData(1, GL_UNSIGNED_INT, texel2[0]), getR32UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
5918             getR32UIPixelData(1, GL_UNSIGNED_INT, texel3[0]), getR32UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
5919             getR32UIPixelData(1, GL_UNSIGNED_INT, texel4[0]), getR32UIPixelData(0, GL_UNSIGNED_INT, texel4[0]),
5920             PIXEL_COMPARE_CHANNEL_R);
5921     }
5922 
5923     /* GL_RG8I */
5924     {
5925         const signed char texel1[2] = {127, 42};
5926         const signed char texel2[2] = {42, -43};
5927         const signed char texel3[2] = {-43, -127};
5928         const signed char texel4[2] = {-127, 127};
5929 
5930         /* GL_RG8I => GL_R8I */
5931         addEntryToConversionDatabase(
5932             getRG8IPixelData(1, GL_BYTE, texel1[0], texel1[1]), getR8IPixelData(0, GL_INT, texel1[0]),
5933             getRG8IPixelData(1, GL_BYTE, texel2[0], texel2[1]), getR8IPixelData(0, GL_INT, texel2[0]),
5934             getRG8IPixelData(1, GL_BYTE, texel3[0], texel3[1]), getR8IPixelData(0, GL_INT, texel3[0]),
5935             getRG8IPixelData(1, GL_BYTE, texel4[0], texel4[1]), getR8IPixelData(0, GL_INT, texel4[0]),
5936             PIXEL_COMPARE_CHANNEL_R);
5937         /* GL_RG8I => GL_RG8I */
5938         addEntryToConversionDatabase(
5939             getRG8IPixelData(1, GL_BYTE, texel1[0], texel1[1]), getRG8IPixelData(0, GL_INT, texel1[0], texel1[1]),
5940             getRG8IPixelData(1, GL_BYTE, texel2[0], texel2[1]), getRG8IPixelData(0, GL_INT, texel2[0], texel2[1]),
5941             getRG8IPixelData(1, GL_BYTE, texel3[0], texel3[1]), getRG8IPixelData(0, GL_INT, texel3[0], texel3[1]),
5942             getRG8IPixelData(1, GL_BYTE, texel4[0], texel4[1]), getRG8IPixelData(0, GL_INT, texel4[0], texel4[1]),
5943             PIXEL_COMPARE_CHANNEL_RG);
5944     }
5945 
5946     /* GL_RG8UI */
5947     {
5948         const unsigned char texel1[2] = {255, 127};
5949         const unsigned char texel2[2] = {127, 63};
5950         const unsigned char texel3[2] = {63, 0};
5951         const unsigned char texel4[2] = {0, 255};
5952 
5953         /* GL_RG8UI => GL_R8UI */
5954         addEntryToConversionDatabase(getRG8UIPixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1]),
5955                                      getR8UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
5956                                      getRG8UIPixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1]),
5957                                      getR8UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
5958                                      getRG8UIPixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1]),
5959                                      getR8UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
5960                                      getRG8UIPixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1]),
5961                                      getR8UIPixelData(0, GL_UNSIGNED_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
5962 
5963         /* GL_RG8UI => GL_RG8UI */
5964         addEntryToConversionDatabase(getRG8UIPixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1]),
5965                                      getRG8UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1]),
5966                                      getRG8UIPixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1]),
5967                                      getRG8UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1]),
5968                                      getRG8UIPixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1]),
5969                                      getRG8UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1]),
5970                                      getRG8UIPixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1]),
5971                                      getRG8UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1]),
5972                                      PIXEL_COMPARE_CHANNEL_RG);
5973     }
5974 
5975     /* GL_RG16I */
5976     {
5977         const short texel1[2] = {32767, 10922};
5978         const short texel2[2] = {10922, -10923};
5979         const short texel3[2] = {-10923, -32767};
5980         const short texel4[2] = {-32767, 32767};
5981 
5982         /* GL_RG16I => GL_R16I */
5983         addEntryToConversionDatabase(
5984             getRG16IPixelData(1, GL_SHORT, texel1[0], texel1[1]), getR16IPixelData(0, GL_INT, texel1[0]),
5985             getRG16IPixelData(1, GL_SHORT, texel2[0], texel2[1]), getR16IPixelData(0, GL_INT, texel2[0]),
5986             getRG16IPixelData(1, GL_SHORT, texel3[0], texel3[1]), getR16IPixelData(0, GL_INT, texel3[0]),
5987             getRG16IPixelData(1, GL_SHORT, texel4[0], texel4[1]), getR16IPixelData(0, GL_INT, texel4[0]),
5988             PIXEL_COMPARE_CHANNEL_R);
5989 
5990         /* GL_RG16I => GL_RG16I */
5991         addEntryToConversionDatabase(
5992             getRG16IPixelData(1, GL_SHORT, texel1[0], texel1[1]), getRG16IPixelData(0, GL_INT, texel1[0], texel1[1]),
5993             getRG16IPixelData(1, GL_SHORT, texel2[0], texel2[1]), getRG16IPixelData(0, GL_INT, texel2[0], texel2[1]),
5994             getRG16IPixelData(1, GL_SHORT, texel3[0], texel3[1]), getRG16IPixelData(0, GL_INT, texel3[0], texel3[1]),
5995             getRG16IPixelData(1, GL_SHORT, texel4[0], texel4[1]), getRG16IPixelData(0, GL_INT, texel4[0], texel4[1]),
5996             PIXEL_COMPARE_CHANNEL_RG);
5997     }
5998 
5999     /* GL_RG16UI */
6000     {
6001         const unsigned short texel1[2] = {65535, 43690};
6002         const unsigned short texel2[2] = {43690, 21845};
6003         const unsigned short texel3[2] = {21845, 0};
6004         const unsigned short texel4[2] = {0, 65535};
6005 
6006         /* GL_RG16UI => GL_R16UI */
6007         addEntryToConversionDatabase(getRG16UIPixelData(1, GL_UNSIGNED_SHORT, texel1[0], texel1[1]),
6008                                      getR16UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
6009                                      getRG16UIPixelData(1, GL_UNSIGNED_SHORT, texel2[0], texel2[1]),
6010                                      getR16UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
6011                                      getRG16UIPixelData(1, GL_UNSIGNED_SHORT, texel3[0], texel3[1]),
6012                                      getR16UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
6013                                      getRG16UIPixelData(1, GL_UNSIGNED_SHORT, texel4[0], texel4[1]),
6014                                      getR16UIPixelData(0, GL_UNSIGNED_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6015 
6016         /* GL_RG16UI => GL_RG16UI */
6017         addEntryToConversionDatabase(getRG16UIPixelData(1, GL_UNSIGNED_SHORT, texel1[0], texel1[1]),
6018                                      getRG16UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1]),
6019                                      getRG16UIPixelData(1, GL_UNSIGNED_SHORT, texel2[0], texel2[1]),
6020                                      getRG16UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1]),
6021                                      getRG16UIPixelData(1, GL_UNSIGNED_SHORT, texel3[0], texel3[1]),
6022                                      getRG16UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1]),
6023                                      getRG16UIPixelData(1, GL_UNSIGNED_SHORT, texel4[0], texel4[1]),
6024                                      getRG16UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1]),
6025                                      PIXEL_COMPARE_CHANNEL_RG);
6026     }
6027 
6028     /* GL_RG32I */
6029     {
6030         const int texel1[2] = {2147483647, 715827883l};
6031         const int texel2[2] = {715827883, -715827881l};
6032         const int texel3[2] = {-715827881, -2147483647l};
6033         const int texel4[2] = {-2147483647, 2147483647l};
6034 
6035         /* GL_RG32I => GL_R32I */
6036         addEntryToConversionDatabase(
6037             getRG32IPixelData(1, GL_INT, texel1[0], texel1[1]), getR32IPixelData(0, GL_INT, texel1[0]),
6038             getRG32IPixelData(1, GL_INT, texel2[0], texel2[1]), getR32IPixelData(0, GL_INT, texel2[0]),
6039             getRG32IPixelData(1, GL_INT, texel3[0], texel3[1]), getR32IPixelData(0, GL_INT, texel3[0]),
6040             getRG32IPixelData(1, GL_INT, texel4[0], texel4[1]), getR32IPixelData(0, GL_INT, texel4[0]),
6041             PIXEL_COMPARE_CHANNEL_R);
6042 
6043         /* GL_RG32I => GL_RG32I */
6044         addEntryToConversionDatabase(
6045             getRG32IPixelData(1, GL_INT, texel1[0], texel1[1]), getRG32IPixelData(0, GL_INT, texel1[0], texel1[1]),
6046             getRG32IPixelData(1, GL_INT, texel2[0], texel2[1]), getRG32IPixelData(0, GL_INT, texel2[0], texel2[1]),
6047             getRG32IPixelData(1, GL_INT, texel3[0], texel3[1]), getRG32IPixelData(0, GL_INT, texel3[0], texel3[1]),
6048             getRG32IPixelData(1, GL_INT, texel4[0], texel4[1]), getRG32IPixelData(0, GL_INT, texel4[0], texel4[1]),
6049             PIXEL_COMPARE_CHANNEL_RG);
6050     }
6051 
6052     /* GL_RG32UI */
6053     {
6054         const unsigned int texel1[2] = {4294967295u, 2863311530u};
6055         const unsigned int texel2[2] = {2863311530u, 1431655765u};
6056         const unsigned int texel3[2] = {1431655765u, 0};
6057         const unsigned int texel4[2] = {0, 4294967295u};
6058 
6059         /* GL_RG32UI => GL_R32UI */
6060         addEntryToConversionDatabase(getRG32UIPixelData(1, GL_UNSIGNED_INT, texel1[0], texel1[1]),
6061                                      getR32UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
6062                                      getRG32UIPixelData(1, GL_UNSIGNED_INT, texel2[0], texel2[1]),
6063                                      getR32UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
6064                                      getRG32UIPixelData(1, GL_UNSIGNED_INT, texel3[0], texel3[1]),
6065                                      getR32UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
6066                                      getRG32UIPixelData(1, GL_UNSIGNED_INT, texel4[0], texel4[1]),
6067                                      getR32UIPixelData(0, GL_UNSIGNED_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6068 
6069         /* GL_RG32UI => GL_RG32UI */
6070         addEntryToConversionDatabase(getRG32UIPixelData(1, GL_UNSIGNED_INT, texel1[0], texel1[1]),
6071                                      getRG32UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1]),
6072                                      getRG32UIPixelData(1, GL_UNSIGNED_INT, texel2[0], texel2[1]),
6073                                      getRG32UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1]),
6074                                      getRG32UIPixelData(1, GL_UNSIGNED_INT, texel3[0], texel3[1]),
6075                                      getRG32UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1]),
6076                                      getRG32UIPixelData(1, GL_UNSIGNED_INT, texel4[0], texel4[1]),
6077                                      getRG32UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1]),
6078                                      PIXEL_COMPARE_CHANNEL_RG);
6079     }
6080 
6081     /* GL_RGBA8I */
6082     {
6083         const signed char texel1[4] = {127, 42, -43, -127};
6084         const signed char texel2[4] = {42, -43, -127, 127};
6085         const signed char texel3[4] = {-43, -127, 127, 42};
6086         const signed char texel4[4] = {-127, 127, 42, -43};
6087 
6088         /* GL_RGBA8I => GL_R8I */
6089         addEntryToConversionDatabase(getRGBA8IPixelData(1, GL_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
6090                                      getR8IPixelData(0, GL_INT, texel1[0]),
6091                                      getRGBA8IPixelData(1, GL_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
6092                                      getR8IPixelData(0, GL_INT, texel2[0]),
6093                                      getRGBA8IPixelData(1, GL_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
6094                                      getR8IPixelData(0, GL_INT, texel3[0]),
6095                                      getRGBA8IPixelData(1, GL_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
6096                                      getR8IPixelData(0, GL_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6097 
6098         /* GL_RGBA8I => GL_RG8I */
6099         addEntryToConversionDatabase(getRGBA8IPixelData(1, GL_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
6100                                      getRG8IPixelData(0, GL_INT, texel1[0], texel1[1]),
6101                                      getRGBA8IPixelData(1, GL_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
6102                                      getRG8IPixelData(0, GL_INT, texel2[0], texel2[1]),
6103                                      getRGBA8IPixelData(1, GL_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
6104                                      getRG8IPixelData(0, GL_INT, texel3[0], texel3[1]),
6105                                      getRGBA8IPixelData(1, GL_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
6106                                      getRG8IPixelData(0, GL_INT, texel4[0], texel4[1]), PIXEL_COMPARE_CHANNEL_RG);
6107 
6108         /* GL_RGBA8I => GL_RGB8I */
6109         addEntryToConversionDatabase(getRGBA8IPixelData(1, GL_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
6110                                      getRGB8IPixelData(0, GL_INT, texel1[0], texel1[1], texel1[2]),
6111                                      getRGBA8IPixelData(1, GL_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
6112                                      getRGB8IPixelData(0, GL_INT, texel2[0], texel2[1], texel2[2]),
6113                                      getRGBA8IPixelData(1, GL_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
6114                                      getRGB8IPixelData(0, GL_INT, texel3[0], texel3[1], texel3[2]),
6115                                      getRGBA8IPixelData(1, GL_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
6116                                      getRGB8IPixelData(0, GL_INT, texel4[0], texel4[1], texel4[2]),
6117                                      PIXEL_COMPARE_CHANNEL_RGB);
6118 
6119         /* GL_RGBA8I => GL_RGBA8I */
6120         addEntryToConversionDatabase(getRGBA8IPixelData(1, GL_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
6121                                      getRGBA8IPixelData(0, GL_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6122                                      getRGBA8IPixelData(1, GL_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
6123                                      getRGBA8IPixelData(0, GL_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6124                                      getRGBA8IPixelData(1, GL_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
6125                                      getRGBA8IPixelData(0, GL_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6126                                      getRGBA8IPixelData(1, GL_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
6127                                      getRGBA8IPixelData(0, GL_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6128                                      PIXEL_COMPARE_CHANNEL_RGBA);
6129     }
6130 
6131     /* GL_RGBA8UI */
6132     {
6133         const unsigned char texel1[4] = {255, 127, 63, 0};
6134         const unsigned char texel2[4] = {127, 63, 0, 255};
6135         const unsigned char texel3[4] = {63, 0, 255, 127};
6136         const unsigned char texel4[4] = {0, 255, 127, 63};
6137 
6138         /* GL_RGBA8UI => GL_R8UI */
6139         addEntryToConversionDatabase(
6140             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
6141             getR8UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
6142             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
6143             getR8UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
6144             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
6145             getR8UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
6146             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
6147             getR8UIPixelData(0, GL_UNSIGNED_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6148 
6149         /* GL_RGBA8UI => GL_RG8UI */
6150         addEntryToConversionDatabase(
6151             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
6152             getRG8UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1]),
6153             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
6154             getRG8UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1]),
6155             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
6156             getRG8UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1]),
6157             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
6158             getRG8UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1]), PIXEL_COMPARE_CHANNEL_RG);
6159 
6160         /* GL_RGBA8UI => GL_RGB8UI */
6161         addEntryToConversionDatabase(
6162             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
6163             getRGB8UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2]),
6164             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
6165             getRGB8UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2]),
6166             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
6167             getRGB8UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2]),
6168             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
6169             getRGB8UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2]), PIXEL_COMPARE_CHANNEL_RGB);
6170 
6171         /* GL_RGBA8UI => GL_RGBA8UI */
6172         addEntryToConversionDatabase(
6173             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel1[0], texel1[1], texel1[2], texel1[3]),
6174             getRGBA8UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6175             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel2[0], texel2[1], texel2[2], texel2[3]),
6176             getRGBA8UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6177             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel3[0], texel3[1], texel3[2], texel3[3]),
6178             getRGBA8UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6179             getRGBA8UIPixelData(1, GL_UNSIGNED_BYTE, texel4[0], texel4[1], texel4[2], texel4[3]),
6180             getRGBA8UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6181             PIXEL_COMPARE_CHANNEL_RGBA);
6182     }
6183 
6184     /* GL_RGBA16I */
6185     {
6186         const short texel1[4] = {32767, 10922, -10923, -32767};
6187         const short texel2[4] = {10922, -10923, -32767, 32767};
6188         const short texel3[4] = {-10923, -32767, 32767, 10922};
6189         const short texel4[4] = {-32767, 32767, 10922, -10923};
6190 
6191         /* GL_RGBA16I => GL_R16I */
6192         addEntryToConversionDatabase(getRGBA16IPixelData(1, GL_SHORT, texel1[0], texel1[1], texel1[2], texel1[3]),
6193                                      getR16IPixelData(0, GL_INT, texel1[0]),
6194                                      getRGBA16IPixelData(1, GL_SHORT, texel2[0], texel2[1], texel2[2], texel2[3]),
6195                                      getR16IPixelData(0, GL_INT, texel2[0]),
6196                                      getRGBA16IPixelData(1, GL_SHORT, texel3[0], texel3[1], texel3[2], texel3[3]),
6197                                      getR16IPixelData(0, GL_INT, texel3[0]),
6198                                      getRGBA16IPixelData(1, GL_SHORT, texel4[0], texel4[1], texel4[2], texel4[3]),
6199                                      getR16IPixelData(0, GL_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6200 
6201         /* GL_RGBA16I => GL_RG16I */
6202         addEntryToConversionDatabase(getRGBA16IPixelData(1, GL_SHORT, texel1[0], texel1[1], texel1[2], texel1[3]),
6203                                      getRG16IPixelData(0, GL_INT, texel1[0], texel1[1]),
6204                                      getRGBA16IPixelData(1, GL_SHORT, texel2[0], texel2[1], texel2[2], texel2[3]),
6205                                      getRG16IPixelData(0, GL_INT, texel2[0], texel2[1]),
6206                                      getRGBA16IPixelData(1, GL_SHORT, texel3[0], texel3[1], texel3[2], texel3[3]),
6207                                      getRG16IPixelData(0, GL_INT, texel3[0], texel3[1]),
6208                                      getRGBA16IPixelData(1, GL_SHORT, texel4[0], texel4[1], texel4[2], texel4[3]),
6209                                      getRG16IPixelData(0, GL_INT, texel4[0], texel4[1]), PIXEL_COMPARE_CHANNEL_RG);
6210 
6211         /* GL_RGBA16I => GL_RGB16I */
6212         addEntryToConversionDatabase(getRGBA16IPixelData(1, GL_SHORT, texel1[0], texel1[1], texel1[2], texel1[3]),
6213                                      getRGB16IPixelData(0, GL_INT, texel1[0], texel1[1], texel1[2]),
6214                                      getRGBA16IPixelData(1, GL_SHORT, texel2[0], texel2[1], texel2[2], texel2[3]),
6215                                      getRGB16IPixelData(0, GL_INT, texel2[0], texel2[1], texel2[2]),
6216                                      getRGBA16IPixelData(1, GL_SHORT, texel3[0], texel3[1], texel3[2], texel3[3]),
6217                                      getRGB16IPixelData(0, GL_INT, texel3[0], texel3[1], texel3[2]),
6218                                      getRGBA16IPixelData(1, GL_SHORT, texel4[0], texel4[1], texel4[2], texel4[3]),
6219                                      getRGB16IPixelData(0, GL_INT, texel4[0], texel4[1], texel4[2]),
6220                                      PIXEL_COMPARE_CHANNEL_RGB);
6221 
6222         /* GL_RGBA16I => GL_RGBA16I */
6223         addEntryToConversionDatabase(getRGBA16IPixelData(1, GL_SHORT, texel1[0], texel1[1], texel1[2], texel1[3]),
6224                                      getRGBA16IPixelData(0, GL_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6225                                      getRGBA16IPixelData(1, GL_SHORT, texel2[0], texel2[1], texel2[2], texel2[3]),
6226                                      getRGBA16IPixelData(0, GL_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6227                                      getRGBA16IPixelData(1, GL_SHORT, texel3[0], texel3[1], texel3[2], texel3[3]),
6228                                      getRGBA16IPixelData(0, GL_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6229                                      getRGBA16IPixelData(1, GL_SHORT, texel4[0], texel4[1], texel4[2], texel4[3]),
6230                                      getRGBA16IPixelData(0, GL_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6231                                      PIXEL_COMPARE_CHANNEL_RGBA);
6232     }
6233 
6234     /* GL_RGBA16UI */
6235     {
6236         const unsigned short texel1[4] = {65535, 43690, 21845, 0};
6237         const unsigned short texel2[4] = {43690, 21845, 0, 65535};
6238         const unsigned short texel3[4] = {21845, 0, 65535, 43690};
6239         const unsigned short texel4[4] = {0, 65535, 43690, 21845};
6240 
6241         /* GL_RGBA16UI => GL_R16UI */
6242         addEntryToConversionDatabase(
6243             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel1[0], texel1[1], texel1[2], texel1[3]),
6244             getR16UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
6245             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel2[0], texel2[1], texel2[2], texel2[3]),
6246             getR16UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
6247             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel3[0], texel3[1], texel3[2], texel3[3]),
6248             getR16UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
6249             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel4[0], texel4[1], texel4[2], texel4[3]),
6250             getR16UIPixelData(0, GL_UNSIGNED_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6251 
6252         /* GL_RGBA16UI => GL_RG16UI */
6253         addEntryToConversionDatabase(
6254             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel1[0], texel1[1], texel1[2], texel1[3]),
6255             getRG16UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1]),
6256             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel2[0], texel2[1], texel2[2], texel2[3]),
6257             getRG16UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1]),
6258             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel3[0], texel3[1], texel3[2], texel3[3]),
6259             getRG16UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1]),
6260             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel4[0], texel4[1], texel4[2], texel4[3]),
6261             getRG16UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1]), PIXEL_COMPARE_CHANNEL_RG);
6262 
6263         /* GL_RGBA16UI => GL_RGB16UI */
6264         addEntryToConversionDatabase(
6265             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel1[0], texel1[1], texel1[2], texel1[3]),
6266             getRGB16UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2]),
6267             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel2[0], texel2[1], texel2[2], texel2[3]),
6268             getRGB16UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2]),
6269             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel3[0], texel3[1], texel3[2], texel3[3]),
6270             getRGB16UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2]),
6271             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel4[0], texel4[1], texel4[2], texel4[3]),
6272             getRGB16UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2]), PIXEL_COMPARE_CHANNEL_RGB);
6273 
6274         /* GL_RGBA16UI => GL_RGBA16UI */
6275         addEntryToConversionDatabase(
6276             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel1[0], texel1[1], texel1[2], texel1[3]),
6277             getRGBA16UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6278             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel2[0], texel2[1], texel2[2], texel2[3]),
6279             getRGBA16UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6280             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel3[0], texel3[1], texel3[2], texel3[3]),
6281             getRGBA16UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6282             getRGBA16UIPixelData(1, GL_UNSIGNED_SHORT, texel4[0], texel4[1], texel4[2], texel4[3]),
6283             getRGBA16UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6284             PIXEL_COMPARE_CHANNEL_RGBA);
6285     }
6286 
6287     /* GL_RGBA32I */
6288     {
6289         const int texel1[4] = {2147483647, 715827883, -715827881, -2147483647};
6290         const int texel2[4] = {715827883, -715827881, -2147483647, 2147483647};
6291         const int texel3[4] = {-715827881, -2147483647, 2147483647, 715827883};
6292         const int texel4[4] = {-2147483647, 2147483647, 715827883, -715827881};
6293 
6294         /* GL_RGBA32I => GL_R32I */
6295         addEntryToConversionDatabase(getRGBA32IPixelData(GL_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6296                                      getR32IPixelData(0, GL_INT, texel1[0]),
6297                                      getRGBA32IPixelData(GL_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6298                                      getR32IPixelData(0, GL_INT, texel2[0]),
6299                                      getRGBA32IPixelData(GL_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6300                                      getR32IPixelData(0, GL_INT, texel3[0]),
6301                                      getRGBA32IPixelData(GL_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6302                                      getR32IPixelData(0, GL_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6303 
6304         /* GL_RGBA32I => GL_RG32I */
6305         addEntryToConversionDatabase(getRGBA32IPixelData(GL_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6306                                      getRG32IPixelData(0, GL_INT, texel1[0], texel1[1]),
6307                                      getRGBA32IPixelData(GL_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6308                                      getRG32IPixelData(0, GL_INT, texel2[0], texel2[1]),
6309                                      getRGBA32IPixelData(GL_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6310                                      getRG32IPixelData(0, GL_INT, texel3[0], texel3[1]),
6311                                      getRGBA32IPixelData(GL_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6312                                      getRG32IPixelData(0, GL_INT, texel4[0], texel4[1]), PIXEL_COMPARE_CHANNEL_RG);
6313 
6314         /* GL_RGBA32I => GL_RGB32I */
6315         addEntryToConversionDatabase(getRGBA32IPixelData(GL_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6316                                      getRGB32IPixelData(0, GL_INT, texel1[0], texel1[1], texel1[2]),
6317                                      getRGBA32IPixelData(GL_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6318                                      getRGB32IPixelData(0, GL_INT, texel2[0], texel2[1], texel2[2]),
6319                                      getRGBA32IPixelData(GL_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6320                                      getRGB32IPixelData(0, GL_INT, texel3[0], texel3[1], texel3[2]),
6321                                      getRGBA32IPixelData(GL_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6322                                      getRGB32IPixelData(0, GL_INT, texel4[0], texel4[1], texel4[2]),
6323                                      PIXEL_COMPARE_CHANNEL_RGB);
6324 
6325         /* GL_RGBA32I => GL_RGBA32I */
6326         addEntryToConversionDatabase(getRGBA32IPixelData(GL_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6327                                      getRGBA32IPixelData(GL_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6328                                      getRGBA32IPixelData(GL_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6329                                      getRGBA32IPixelData(GL_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6330                                      getRGBA32IPixelData(GL_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6331                                      getRGBA32IPixelData(GL_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6332                                      getRGBA32IPixelData(GL_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6333                                      getRGBA32IPixelData(GL_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6334                                      PIXEL_COMPARE_CHANNEL_RGBA);
6335     }
6336 
6337     /* GL_RGBA32UI */
6338     {
6339         const unsigned int texel1[4] = {4294967295u, 2863311530u, 1431655765u, 0};
6340         const unsigned int texel2[4] = {2863311530u, 1431655765u, 0, 4294967295u};
6341         const unsigned int texel3[4] = {1431655765u, 0, 4294967295u, 2863311530u};
6342         const unsigned int texel4[4] = {0, 4294967295u, 2863311530u, 1431655765u};
6343 
6344         /* GL_RGBA32UI => GL_R32UI */
6345         addEntryToConversionDatabase(getRGBA32UIPixelData(GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6346                                      getR32UIPixelData(0, GL_UNSIGNED_INT, texel1[0]),
6347                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6348                                      getR32UIPixelData(0, GL_UNSIGNED_INT, texel2[0]),
6349                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6350                                      getR32UIPixelData(0, GL_UNSIGNED_INT, texel3[0]),
6351                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6352                                      getR32UIPixelData(0, GL_UNSIGNED_INT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6353 
6354         /* GL_RGBA32UI => GL_RG32UI */
6355         addEntryToConversionDatabase(getRGBA32UIPixelData(GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6356                                      getRG32UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1]),
6357                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6358                                      getRG32UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1]),
6359                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6360                                      getRG32UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1]),
6361                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6362                                      getRG32UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1]),
6363                                      PIXEL_COMPARE_CHANNEL_RG);
6364 
6365         /* GL_RGBA32UI => GL_RGB32UI */
6366         addEntryToConversionDatabase(getRGBA32UIPixelData(GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6367                                      getRGB32UIPixelData(0, GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2]),
6368                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6369                                      getRGB32UIPixelData(0, GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2]),
6370                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6371                                      getRGB32UIPixelData(0, GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2]),
6372                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6373                                      getRGB32UIPixelData(0, GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2]),
6374                                      PIXEL_COMPARE_CHANNEL_RGB);
6375 
6376         /* GL_RGBA32UI => GL_RGBA32UI */
6377         addEntryToConversionDatabase(getRGBA32UIPixelData(GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6378                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel1[0], texel1[1], texel1[2], texel1[3]),
6379                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6380                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel2[0], texel2[1], texel2[2], texel2[3]),
6381                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6382                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel3[0], texel3[1], texel3[2], texel3[3]),
6383                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6384                                      getRGBA32UIPixelData(GL_UNSIGNED_INT, texel4[0], texel4[1], texel4[2], texel4[3]),
6385                                      PIXEL_COMPARE_CHANNEL_RGBA);
6386     }
6387 
6388     /* GL_R16F */
6389     {
6390         const float texel1[1] = {1};
6391         const float texel2[1] = {4096};
6392         const float texel3[1] = {-4096};
6393         const float texel4[1] = {32000};
6394 
6395         /* GL_R16F => GL_R16F */
6396         addEntryToConversionDatabase(
6397             getR16FPixelData(1, GL_HALF_FLOAT, texel1[0]), getR16FPixelData(0, GL_HALF_FLOAT, texel1[0]),
6398             getR16FPixelData(1, GL_HALF_FLOAT, texel2[0]), getR16FPixelData(0, GL_HALF_FLOAT, texel2[0]),
6399             getR16FPixelData(1, GL_HALF_FLOAT, texel3[0]), getR16FPixelData(0, GL_HALF_FLOAT, texel3[0]),
6400             getR16FPixelData(1, GL_HALF_FLOAT, texel4[0]), getR16FPixelData(0, GL_HALF_FLOAT, texel4[0]),
6401             PIXEL_COMPARE_CHANNEL_R);
6402     }
6403 
6404     /* GL_RG16F */
6405     {
6406         const float texel1[2] = {1, 0};
6407         const float texel2[2] = {4096, -4096};
6408         const float texel3[2] = {-32000, 32000};
6409         const float texel4[2] = {1.5f, -4.7f};
6410 
6411         /* GL_RG16F => GL_R16F */
6412         addEntryToConversionDatabase(
6413             getRG16FPixelData(1, GL_HALF_FLOAT, texel1[0], texel1[1]), getR16FPixelData(0, GL_HALF_FLOAT, texel1[0]),
6414             getRG16FPixelData(1, GL_HALF_FLOAT, texel2[0], texel2[1]), getR16FPixelData(0, GL_HALF_FLOAT, texel2[0]),
6415             getRG16FPixelData(1, GL_HALF_FLOAT, texel3[0], texel3[1]), getR16FPixelData(0, GL_HALF_FLOAT, texel3[0]),
6416             getRG16FPixelData(1, GL_HALF_FLOAT, texel4[0], texel4[1]), getR16FPixelData(0, GL_HALF_FLOAT, texel4[0]),
6417             PIXEL_COMPARE_CHANNEL_R);
6418 
6419         /* GL_RG16F => GL_RG16F */
6420         addEntryToConversionDatabase(getRG16FPixelData(1, GL_HALF_FLOAT, texel1[0], texel1[1]),
6421                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel1[0], texel1[1]),
6422                                      getRG16FPixelData(1, GL_HALF_FLOAT, texel2[0], texel2[1]),
6423                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel2[0], texel2[1]),
6424                                      getRG16FPixelData(1, GL_HALF_FLOAT, texel3[0], texel3[1]),
6425                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel3[0], texel3[1]),
6426                                      getRG16FPixelData(1, GL_HALF_FLOAT, texel4[0], texel4[1]),
6427                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel4[0], texel4[1]),
6428                                      PIXEL_COMPARE_CHANNEL_RG);
6429     }
6430 
6431     /* GL_R32F */
6432     {
6433         const float texel1[1] = {1};
6434         const float texel2[1] = {4096};
6435         const float texel3[1] = {-4096};
6436         const float texel4[1] = {32000};
6437 
6438         /* GL_R32F => GL_R32F */
6439         addEntryToConversionDatabase(getR32FPixelData(1, GL_FLOAT, texel1[0]), getR32FPixelData(0, GL_FLOAT, texel1[0]),
6440                                      getR32FPixelData(1, GL_FLOAT, texel2[0]), getR32FPixelData(0, GL_FLOAT, texel2[0]),
6441                                      getR32FPixelData(1, GL_FLOAT, texel3[0]), getR32FPixelData(0, GL_FLOAT, texel3[0]),
6442                                      getR32FPixelData(1, GL_FLOAT, texel4[0]), getR32FPixelData(0, GL_FLOAT, texel4[0]),
6443                                      PIXEL_COMPARE_CHANNEL_R);
6444     }
6445 
6446     /* GL_RG32F */
6447     {
6448         const float texel1[2] = {1, 0};
6449         const float texel2[2] = {4096, -4096};
6450         const float texel3[2] = {-32000, 32000};
6451         const float texel4[2] = {1.5f, -4.7f};
6452 
6453         /* GL_RG32F => GL_R32F */
6454         addEntryToConversionDatabase(
6455             getRG32FPixelData(1, GL_FLOAT, texel1[0], texel1[1]), getR32FPixelData(0, GL_FLOAT, texel1[0]),
6456             getRG32FPixelData(1, GL_FLOAT, texel2[0], texel2[1]), getR32FPixelData(0, GL_FLOAT, texel2[0]),
6457             getRG32FPixelData(1, GL_FLOAT, texel3[0], texel3[1]), getR32FPixelData(0, GL_FLOAT, texel3[0]),
6458             getRG32FPixelData(1, GL_FLOAT, texel4[0], texel4[1]), getR32FPixelData(0, GL_FLOAT, texel4[0]),
6459             PIXEL_COMPARE_CHANNEL_R);
6460 
6461         /* GL_RG32F => GL_RG32F */
6462         addEntryToConversionDatabase(
6463             getRG32FPixelData(1, GL_FLOAT, texel1[0], texel1[1]), getRG32FPixelData(0, GL_FLOAT, texel1[0], texel1[1]),
6464             getRG32FPixelData(1, GL_FLOAT, texel2[0], texel2[1]), getRG32FPixelData(0, GL_FLOAT, texel2[0], texel2[1]),
6465             getRG32FPixelData(1, GL_FLOAT, texel3[0], texel3[1]), getRG32FPixelData(0, GL_FLOAT, texel3[0], texel3[1]),
6466             getRG32FPixelData(1, GL_FLOAT, texel4[0], texel4[1]), getRG32FPixelData(0, GL_FLOAT, texel4[0], texel4[1]),
6467             PIXEL_COMPARE_CHANNEL_RG);
6468     }
6469 
6470     /* GL_RGB16F */
6471     {
6472         const float texel1[3] = {1, 0, -1};
6473         const float texel2[3] = {4096, -4096, 127.5f};
6474         const float texel3[3] = {-32000, 32000, -456.7f};
6475         const float texel4[3] = {1.5f, -4.7f, 123.6f};
6476 
6477         /* GL_RGB16F => GL_R16F */
6478         addEntryToConversionDatabase(getRGB16FPixelData(1, GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2]),
6479                                      getR16FPixelData(0, GL_HALF_FLOAT, texel1[0]),
6480                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2]),
6481                                      getR16FPixelData(0, GL_HALF_FLOAT, texel2[0]),
6482                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2]),
6483                                      getR16FPixelData(0, GL_HALF_FLOAT, texel3[0]),
6484                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2]),
6485                                      getR16FPixelData(0, GL_HALF_FLOAT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6486 
6487         /* GL_RGB16F => GL_RG16F */
6488         addEntryToConversionDatabase(getRGB16FPixelData(1, GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2]),
6489                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel1[0], texel1[1]),
6490                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2]),
6491                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel2[0], texel2[1]),
6492                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2]),
6493                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel3[0], texel3[1]),
6494                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2]),
6495                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel4[0], texel4[1]),
6496                                      PIXEL_COMPARE_CHANNEL_RG);
6497 
6498         /* GL_RGB16F => GL_RGB16F */
6499         addEntryToConversionDatabase(getRGB16FPixelData(1, GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2]),
6500                                      getRGB16FPixelData(0, GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2]),
6501                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2]),
6502                                      getRGB16FPixelData(0, GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2]),
6503                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2]),
6504                                      getRGB16FPixelData(0, GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2]),
6505                                      getRGB16FPixelData(1, GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2]),
6506                                      getRGB16FPixelData(0, GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2]),
6507                                      PIXEL_COMPARE_CHANNEL_RGB);
6508     }
6509 
6510     /* GL_RGBA16F */
6511     {
6512         const float texel1[4] = {1, 0, -1, 0.25f};
6513         const float texel2[4] = {4096, -4096, 127.5f, 0.5f};
6514         const float texel3[4] = {-32000, 32000, -456.7f, 0.75f};
6515         const float texel4[4] = {1.5f, -4.7f, 123.6f, 1};
6516 
6517         /* GL_RGBA16F => GL_R16F */
6518         addEntryToConversionDatabase(getRGBA16FPixelData(GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6519                                      getR16FPixelData(0, GL_HALF_FLOAT, texel1[0]),
6520                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6521                                      getR16FPixelData(0, GL_HALF_FLOAT, texel2[0]),
6522                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6523                                      getR16FPixelData(0, GL_HALF_FLOAT, texel3[0]),
6524                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6525                                      getR16FPixelData(0, GL_HALF_FLOAT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6526 
6527         /* GL_RGBA16F => GL_RG16F */
6528         addEntryToConversionDatabase(getRGBA16FPixelData(GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6529                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel1[0], texel1[1]),
6530                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6531                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel2[0], texel2[1]),
6532                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6533                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel3[0], texel3[1]),
6534                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6535                                      getRG16FPixelData(0, GL_HALF_FLOAT, texel4[0], texel4[1]),
6536                                      PIXEL_COMPARE_CHANNEL_RG);
6537 
6538         /* GL_RGBA16F => GL_RGB16F */
6539         addEntryToConversionDatabase(getRGBA16FPixelData(GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6540                                      getRGB16FPixelData(0, GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2]),
6541                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6542                                      getRGB16FPixelData(0, GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2]),
6543                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6544                                      getRGB16FPixelData(0, GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2]),
6545                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6546                                      getRGB16FPixelData(0, GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2]),
6547                                      PIXEL_COMPARE_CHANNEL_RGB);
6548 
6549         /* GL_RGBA16F => GL_RGBA16F */
6550         addEntryToConversionDatabase(getRGBA16FPixelData(GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6551                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6552                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6553                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6554                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6555                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6556                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6557                                      getRGBA16FPixelData(GL_HALF_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6558                                      PIXEL_COMPARE_CHANNEL_RGBA);
6559     }
6560 
6561     /* GL_RGB32F */
6562     {
6563         const float texel1[3] = {1, 0, -1};
6564         const float texel2[3] = {4096, -4096, 127.5f};
6565         const float texel3[3] = {-32000, 32000, -456.7f};
6566         const float texel4[3] = {1.5f, -4.7f, 123.6f};
6567 
6568         /* GL_RGB32F => GL_R32F */
6569         addEntryToConversionDatabase(
6570             getRGB32FPixelData(1, GL_FLOAT, texel1[0], texel1[1], texel1[2]), getR32FPixelData(0, GL_FLOAT, texel1[0]),
6571             getRGB32FPixelData(1, GL_FLOAT, texel2[0], texel2[1], texel2[2]), getR32FPixelData(0, GL_FLOAT, texel2[0]),
6572             getRGB32FPixelData(1, GL_FLOAT, texel3[0], texel3[1], texel3[2]), getR32FPixelData(0, GL_FLOAT, texel3[0]),
6573             getRGB32FPixelData(1, GL_FLOAT, texel4[0], texel4[1], texel4[2]), getR32FPixelData(0, GL_FLOAT, texel4[0]),
6574             PIXEL_COMPARE_CHANNEL_R);
6575 
6576         /* GL_RGB32F => GL_RG32F */
6577         addEntryToConversionDatabase(getRGB32FPixelData(1, GL_FLOAT, texel1[0], texel1[1], texel1[2]),
6578                                      getRG32FPixelData(0, GL_FLOAT, texel1[0], texel1[1]),
6579                                      getRGB32FPixelData(1, GL_FLOAT, texel2[0], texel2[1], texel2[2]),
6580                                      getRG32FPixelData(0, GL_FLOAT, texel2[0], texel2[1]),
6581                                      getRGB32FPixelData(1, GL_FLOAT, texel3[0], texel3[1], texel3[2]),
6582                                      getRG32FPixelData(0, GL_FLOAT, texel3[0], texel3[1]),
6583                                      getRGB32FPixelData(1, GL_FLOAT, texel4[0], texel4[1], texel4[2]),
6584                                      getRG32FPixelData(0, GL_FLOAT, texel4[0], texel4[1]), PIXEL_COMPARE_CHANNEL_RG);
6585 
6586         /* GL_RGB32F => GL_RGB32F */
6587         addEntryToConversionDatabase(getRGB32FPixelData(1, GL_FLOAT, texel1[0], texel1[1], texel1[2]),
6588                                      getRGB32FPixelData(0, GL_FLOAT, texel1[0], texel1[1], texel1[2]),
6589                                      getRGB32FPixelData(1, GL_FLOAT, texel2[0], texel2[1], texel2[2]),
6590                                      getRGB32FPixelData(0, GL_FLOAT, texel2[0], texel2[1], texel2[2]),
6591                                      getRGB32FPixelData(1, GL_FLOAT, texel3[0], texel3[1], texel3[2]),
6592                                      getRGB32FPixelData(0, GL_FLOAT, texel3[0], texel3[1], texel3[2]),
6593                                      getRGB32FPixelData(1, GL_FLOAT, texel4[0], texel4[1], texel4[2]),
6594                                      getRGB32FPixelData(0, GL_FLOAT, texel4[0], texel4[1], texel4[2]),
6595                                      PIXEL_COMPARE_CHANNEL_RGB);
6596     }
6597 
6598     /* GL_RGBA32F */
6599     {
6600         const float texel1[4] = {1, 0, -1, 0.25f};
6601         const float texel2[4] = {4096, -4096, 127.5f, 0.5f};
6602         const float texel3[4] = {-32000, 32000, -456.7f, 0.75f};
6603         const float texel4[4] = {1.5f, -4.7f, 123.6f, 1};
6604 
6605         /* GL_RGBA32F => GL_R32F */
6606         addEntryToConversionDatabase(getRGBA32FPixelData(GL_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6607                                      getR32FPixelData(0, GL_FLOAT, texel1[0]),
6608                                      getRGBA32FPixelData(GL_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6609                                      getR32FPixelData(0, GL_FLOAT, texel2[0]),
6610                                      getRGBA32FPixelData(GL_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6611                                      getR32FPixelData(0, GL_FLOAT, texel3[0]),
6612                                      getRGBA32FPixelData(GL_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6613                                      getR32FPixelData(0, GL_FLOAT, texel4[0]), PIXEL_COMPARE_CHANNEL_R);
6614 
6615         /* GL_RGBA32F => GL_RG32F */
6616         addEntryToConversionDatabase(getRGBA32FPixelData(GL_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6617                                      getRG32FPixelData(0, GL_FLOAT, texel1[0], texel1[1]),
6618                                      getRGBA32FPixelData(GL_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6619                                      getRG32FPixelData(0, GL_FLOAT, texel2[0], texel2[1]),
6620                                      getRGBA32FPixelData(GL_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6621                                      getRG32FPixelData(0, GL_FLOAT, texel3[0], texel3[1]),
6622                                      getRGBA32FPixelData(GL_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6623                                      getRG32FPixelData(0, GL_FLOAT, texel4[0], texel4[1]), PIXEL_COMPARE_CHANNEL_RG);
6624 
6625         /* GL_RGBA32F => GL_RGB32F */
6626         addEntryToConversionDatabase(getRGBA32FPixelData(GL_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6627                                      getRGB32FPixelData(0, GL_FLOAT, texel1[0], texel1[1], texel1[2]),
6628                                      getRGBA32FPixelData(GL_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6629                                      getRGB32FPixelData(0, GL_FLOAT, texel2[0], texel2[1], texel2[2]),
6630                                      getRGBA32FPixelData(GL_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6631                                      getRGB32FPixelData(0, GL_FLOAT, texel3[0], texel3[1], texel3[2]),
6632                                      getRGBA32FPixelData(GL_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6633                                      getRGB32FPixelData(0, GL_FLOAT, texel4[0], texel4[1], texel4[2]),
6634                                      PIXEL_COMPARE_CHANNEL_RGB);
6635 
6636         /* GL_RGBA32F => GL_RGBA32F */
6637         addEntryToConversionDatabase(getRGBA32FPixelData(GL_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6638                                      getRGBA32FPixelData(GL_FLOAT, texel1[0], texel1[1], texel1[2], texel1[3]),
6639                                      getRGBA32FPixelData(GL_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6640                                      getRGBA32FPixelData(GL_FLOAT, texel2[0], texel2[1], texel2[2], texel2[3]),
6641                                      getRGBA32FPixelData(GL_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6642                                      getRGBA32FPixelData(GL_FLOAT, texel3[0], texel3[1], texel3[2], texel3[3]),
6643                                      getRGBA32FPixelData(GL_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6644                                      getRGBA32FPixelData(GL_FLOAT, texel4[0], texel4[1], texel4[2], texel4[3]),
6645                                      PIXEL_COMPARE_CHANNEL_RGBA);
6646     }
6647 }
6648 
6649 class TestBase : public deqp::TestCase
6650 {
6651 public:
6652     TestBase(deqp::Context &context, GLenum source_attachment_type, GLenum destination_attachment_type);
6653     virtual ~TestBase();
6654 
6655 protected:
6656     bool getFormatAndTypeCompatibleWithInternalformat(GLenum internalformat, int index, GLenum *out_format,
6657                                                       GLenum *out_type) const;
6658     bool getFormatForInternalformat(GLenum internalformat, GLenum *out_format) const;
6659     GLenum getFBOEffectiveInternalFormatAtIndex(unsigned int index) const;
6660     GLenum getCopyTexImage2DInternalFormatAtIndex(unsigned int index) const;
6661     const char *getTargetName(GLenum target) const;
6662     GLenum getGeneralTargetForDetailedTarget(GLenum target);
6663 
6664     GLuint generateGLObject(GLenum object_type);
6665     bool configureGLObject(int is_source_gl_object, GLenum object_target, GLint object_id, GLenum internal_format,
6666                            GLenum format, GLenum type, void *data);
6667     void destroyGLObject(GLenum target, GLuint object_id);
6668 
6669     bool isValidRBOInternalFormat(GLenum internalformat) const;
6670     bool isColorRenderableInternalFormat(GLenum internalformat) const;
6671     bool isDepthRenderableInternalFormat(GLenum internalformat) const;
6672     bool isDepthStencilRenderableInternalFormat(GLenum internalformat) const;
6673     bool isFBOEffectiveInternalFormatCompatibleWithDestinationInternalFormat(GLenum src_internalformat,
6674                                                                              GLenum dst_internalformat) const;
6675     const char *getInternalformatString(GLenum internalformat);
6676 
6677 protected:
6678     GLenum m_source_attachment_type;
6679     GLenum m_destination_attachment_type;
6680 };
6681 
TestBase(deqp::Context & context,GLenum source_attachment_type,GLenum destination_attachment_type)6682 TestBase::TestBase(deqp::Context &context, GLenum source_attachment_type, GLenum destination_attachment_type)
6683     : deqp::TestCase(context, "", "")
6684     , m_source_attachment_type(source_attachment_type)
6685     , m_destination_attachment_type(destination_attachment_type)
6686 {
6687     static std::map<GLenum, std::string> attachment_name_map;
6688     if (attachment_name_map.empty())
6689     {
6690         attachment_name_map[GL_TEXTURE_2D]                  = "texture2d";
6691         attachment_name_map[GL_TEXTURE_CUBE_MAP_NEGATIVE_X] = "cubemap_negx";
6692         attachment_name_map[GL_TEXTURE_CUBE_MAP_NEGATIVE_Y] = "cubemap_negy";
6693         attachment_name_map[GL_TEXTURE_CUBE_MAP_NEGATIVE_Z] = "cubemap_negz";
6694         attachment_name_map[GL_TEXTURE_CUBE_MAP_POSITIVE_X] = "cubemap_posx";
6695         attachment_name_map[GL_TEXTURE_CUBE_MAP_POSITIVE_Y] = "cubemap_posy";
6696         attachment_name_map[GL_TEXTURE_CUBE_MAP_POSITIVE_Z] = "cubemap_posz";
6697         attachment_name_map[GL_TEXTURE_2D_ARRAY]            = "texture_array";
6698         attachment_name_map[GL_TEXTURE_3D]                  = "texture3d";
6699         attachment_name_map[GL_RENDERBUFFER]                = "renderbuffer";
6700     }
6701 
6702     m_name = attachment_name_map[m_source_attachment_type] + "_" + attachment_name_map[m_destination_attachment_type];
6703 }
6704 
~TestBase()6705 TestBase::~TestBase()
6706 {
6707 }
6708 
6709 /** For every valid GLES internalformat, gl.readPixels() can often work with a variety of different
6710  *  format+type combinations. This function allows to enumerate valid pairs for user-specified
6711  *  internal formats.
6712  *
6713  *  Enumeration should start from 0 and continue until the function starts reporting failure.
6714  *
6715  *  @param internalformat GLES internal format to consider.
6716  *  @param index          Index of format+type pair to look up.
6717  *  @param out_format     Deref will be used to store compatible GLES format. Cannot be NULL.
6718  *  @param out_type       Deref will be used to store compatible GLES type. Cannot be NULL.
6719  *
6720  *  @return true if successful and relevant format & type information has been stored under
6721  *          dereferences of corresponding arguments, false otherwise.
6722  **/
getFormatAndTypeCompatibleWithInternalformat(GLenum internalformat,int index,GLenum * out_format,GLenum * out_type) const6723 bool TestBase::getFormatAndTypeCompatibleWithInternalformat(GLenum internalformat, int index, GLenum *out_format,
6724                                                             GLenum *out_type) const
6725 {
6726     const glu::ContextInfo &contextInfo   = m_context.getContextInfo();
6727     bool is_ext_texture_storage_supported = contextInfo.isExtensionSupported("GL_EXT_texture_storage");
6728     bool is_ext_texture_type_2_10_10_10_rev_supported =
6729         contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV");
6730 
6731     DE_ASSERT(out_format != NULL);
6732     DE_ASSERT(out_type != NULL);
6733 
6734     if (!getFormatForInternalformat(internalformat, out_format))
6735         TCU_FAIL("No format known for requested internalformat");
6736 
6737     switch (internalformat)
6738     {
6739     case GL_ALPHA:
6740     {
6741         if (index == 0)
6742             *out_type = GL_UNSIGNED_BYTE;
6743         else
6744             return false;
6745         break;
6746     }
6747 
6748     case GL_LUMINANCE:
6749     {
6750         if (index == 0)
6751             *out_type = GL_UNSIGNED_BYTE;
6752         else
6753             return false;
6754         break;
6755     }
6756 
6757     case GL_R8:
6758     {
6759         if (index == 0)
6760             *out_type = GL_UNSIGNED_BYTE;
6761         else
6762             return false;
6763         break;
6764     }
6765 
6766     case GL_LUMINANCE_ALPHA:
6767     {
6768         if (index == 0)
6769             *out_type = GL_UNSIGNED_BYTE;
6770         else
6771             return false;
6772         break;
6773     }
6774 
6775     case GL_RG8:
6776     {
6777         if (index == 0)
6778             *out_type = GL_UNSIGNED_BYTE;
6779         else
6780             return false;
6781         break;
6782     }
6783 
6784     case GL_SRGB:
6785     case GL_RGB:
6786     {
6787         if (index == 0)
6788             *out_type = GL_UNSIGNED_BYTE;
6789         else if (index == 1)
6790             *out_type = GL_UNSIGNED_SHORT_5_6_5;
6791         else if (index == 2)
6792             *out_type = GL_UNSIGNED_INT_2_10_10_10_REV;
6793         else if (index == 3)
6794             *out_type = GL_HALF_FLOAT;
6795         else if (index == 4)
6796             *out_type = GL_FLOAT;
6797         else
6798             return false;
6799         break;
6800     }
6801 
6802     case GL_SRGB8:
6803     case GL_RGB8:
6804     {
6805         if (index == 0)
6806             *out_type = GL_UNSIGNED_BYTE;
6807         else
6808             return false;
6809         break;
6810     }
6811 
6812     case GL_RGB565:
6813     {
6814         if (index == 0)
6815             *out_type = GL_UNSIGNED_SHORT_5_6_5;
6816         else if (index == 1)
6817             *out_type = GL_UNSIGNED_BYTE;
6818         else
6819             return false;
6820         break;
6821     }
6822 
6823     case GL_RGBA:
6824     {
6825         if (index == 0)
6826             *out_type = GL_UNSIGNED_BYTE;
6827         else if (index == 1)
6828             *out_type = GL_UNSIGNED_SHORT_4_4_4_4;
6829         else if (index == 2)
6830             *out_type = GL_UNSIGNED_SHORT_5_5_5_1;
6831         else if (index == 3)
6832             *out_type = GL_HALF_FLOAT;
6833         else if (index == 4)
6834             *out_type = GL_FLOAT;
6835         else
6836             return false;
6837         break;
6838     }
6839 
6840     case GL_RGBA4:
6841     {
6842         if (index == 0)
6843             *out_type = GL_UNSIGNED_SHORT_4_4_4_4;
6844         else if (index == 1)
6845             *out_type = GL_UNSIGNED_BYTE;
6846         else
6847             return false;
6848         break;
6849     }
6850 
6851     case GL_RGB5_A1:
6852     {
6853         if (index == 0)
6854             *out_type = GL_UNSIGNED_SHORT_5_5_5_1;
6855         else if (index == 1)
6856             *out_type = GL_UNSIGNED_BYTE;
6857         else if (index == 2)
6858             *out_type = GL_UNSIGNED_INT_2_10_10_10_REV;
6859         else
6860             return false;
6861         break;
6862     }
6863 
6864     case GL_RGBA8:
6865     {
6866         if (index == 0)
6867             *out_type = GL_UNSIGNED_BYTE;
6868         else
6869             return false;
6870         break;
6871     }
6872 
6873     case GL_RGB10_A2:
6874     {
6875         if (index == 0)
6876             *out_type = GL_UNSIGNED_INT_2_10_10_10_REV;
6877         else
6878             return false;
6879         break;
6880     }
6881 
6882     case GL_RGB10_A2UI:
6883     {
6884         if (index == 0)
6885         {
6886             *out_type = GL_UNSIGNED_INT_2_10_10_10_REV;
6887         } /* if (index == 0) */
6888         else
6889         {
6890             return false;
6891         }
6892 
6893         break;
6894     }
6895 
6896     case GL_SRGB8_ALPHA8:
6897     {
6898         if (index == 0)
6899             *out_type = GL_UNSIGNED_BYTE;
6900         else
6901             return false;
6902         break;
6903     }
6904 
6905     case GL_R8I:
6906     {
6907         if (index == 0)
6908             *out_type = GL_BYTE;
6909         else
6910             return false;
6911         break;
6912     }
6913 
6914     case GL_R8UI:
6915     {
6916         if (index == 0)
6917             *out_type = GL_UNSIGNED_BYTE;
6918         else
6919             return false;
6920         break;
6921     }
6922 
6923     case GL_R16I:
6924     {
6925         if (index == 0)
6926             *out_type = GL_SHORT;
6927         else
6928             return false;
6929         break;
6930     }
6931 
6932     case GL_R16UI:
6933     {
6934         if (index == 0)
6935             *out_type = GL_UNSIGNED_SHORT;
6936         else
6937             return false;
6938         break;
6939     }
6940 
6941     case GL_R32I:
6942     {
6943         if (index == 0)
6944             *out_type = GL_INT;
6945         else
6946             return false;
6947         break;
6948     }
6949 
6950     case GL_R32UI:
6951     {
6952         if (index == 0)
6953             *out_type = GL_UNSIGNED_INT;
6954         else
6955             return false;
6956         break;
6957     }
6958 
6959     case GL_RG8I:
6960     {
6961         if (index == 0)
6962             *out_type = GL_BYTE;
6963         else
6964             return false;
6965         break;
6966     }
6967 
6968     case GL_RG8UI:
6969     {
6970         if (index == 0)
6971             *out_type = GL_UNSIGNED_BYTE;
6972         else
6973             return false;
6974         break;
6975     }
6976 
6977     case GL_RG16I:
6978     {
6979         if (index == 0)
6980             *out_type = GL_SHORT;
6981         else
6982             return false;
6983         break;
6984     }
6985 
6986     case GL_RG16UI:
6987     {
6988         if (index == 0)
6989             *out_type = GL_UNSIGNED_SHORT;
6990         else
6991             return false;
6992         break;
6993     }
6994 
6995     case GL_RG32I:
6996     {
6997         if (index == 0)
6998             *out_type = GL_INT;
6999         else
7000             return false;
7001         break;
7002     }
7003 
7004     case GL_RG32UI:
7005     {
7006         if (index == 0)
7007             *out_type = GL_UNSIGNED_INT;
7008         else
7009             return false;
7010         break;
7011     }
7012 
7013     case GL_RGB8I:
7014     {
7015         if (index == 0)
7016             *out_type = GL_BYTE;
7017         else
7018             return false;
7019         break;
7020     }
7021 
7022     case GL_RGB8UI:
7023     {
7024         if (index == 0)
7025             *out_type = GL_UNSIGNED_BYTE;
7026         else
7027             return false;
7028         break;
7029     }
7030 
7031     case GL_RGB16I:
7032     {
7033         if (index == 0)
7034             *out_type = GL_SHORT;
7035         else
7036             return false;
7037         break;
7038     }
7039 
7040     case GL_RGB16UI:
7041     {
7042         if (index == 0)
7043             *out_type = GL_UNSIGNED_SHORT;
7044         else
7045             return false;
7046         break;
7047     }
7048 
7049     case GL_RGB32I:
7050     {
7051         if (index == 0)
7052             *out_type = GL_INT;
7053         else
7054             return false;
7055         break;
7056     }
7057 
7058     case GL_RGB32UI:
7059     {
7060         if (index == 0)
7061             *out_type = GL_UNSIGNED_INT;
7062         else
7063             return false;
7064         break;
7065     }
7066 
7067     case GL_RGBA8I:
7068     {
7069         if (index == 0)
7070             *out_type = GL_BYTE;
7071         else
7072             return false;
7073         break;
7074     }
7075 
7076     case GL_RGBA8UI:
7077     {
7078         if (index == 0)
7079             *out_type = GL_UNSIGNED_BYTE;
7080         else
7081             return false;
7082         break;
7083     }
7084 
7085     case GL_RGBA16I:
7086     {
7087         if (index == 0)
7088             *out_type = GL_SHORT;
7089         else
7090             return false;
7091         break;
7092     }
7093 
7094     case GL_RGBA16UI:
7095     {
7096         if (index == 0)
7097             *out_type = GL_UNSIGNED_SHORT;
7098         else
7099             return false;
7100         break;
7101     }
7102 
7103     case GL_RGBA32I:
7104     {
7105         if (index == 0)
7106             *out_type = GL_INT;
7107         else
7108             return false;
7109         break;
7110     }
7111 
7112     case GL_RGBA32UI:
7113     {
7114         if (index == 0)
7115             *out_type = GL_UNSIGNED_INT;
7116         else
7117             return false;
7118         break;
7119     }
7120 
7121     case GL_R16F:
7122     {
7123         if (index == 0)
7124             *out_type = GL_HALF_FLOAT;
7125         else
7126             return false;
7127         break;
7128     }
7129 
7130     case GL_RG16F:
7131     {
7132         if (index == 0)
7133             *out_type = GL_HALF_FLOAT;
7134         else
7135             return false;
7136         break;
7137     }
7138 
7139     case GL_R32F:
7140     {
7141         if (index == 0)
7142             *out_type = GL_FLOAT;
7143         else
7144             return false;
7145         break;
7146     }
7147 
7148     case GL_RG32F:
7149     {
7150         if (index == 0)
7151             *out_type = GL_FLOAT;
7152         else
7153             return false;
7154         break;
7155     }
7156 
7157     case GL_RGB16F:
7158     {
7159         if (index == 0)
7160             *out_type = GL_HALF_FLOAT;
7161         else
7162             return false;
7163         break;
7164     }
7165 
7166     case GL_RGBA16F:
7167     {
7168         if (index == 0)
7169             *out_type = GL_HALF_FLOAT;
7170         else
7171             return false;
7172         break;
7173     }
7174 
7175     case GL_RGB32F:
7176     {
7177         if (index == 0)
7178             *out_type = GL_FLOAT;
7179         else
7180             return false;
7181         break;
7182     }
7183 
7184     case GL_RGBA32F:
7185     {
7186         if (index == 0)
7187             *out_type = GL_FLOAT;
7188         else
7189             return false;
7190         break;
7191     }
7192 
7193     case GL_RGB10_EXT:
7194     {
7195         if (index == 0)
7196         {
7197             if (is_ext_texture_type_2_10_10_10_rev_supported && is_ext_texture_storage_supported)
7198             {
7199                 *out_type = GL_UNSIGNED_INT_2_10_10_10_REV;
7200             } /* if (is_ext_texture_type_2_10_10_10_rev_supported) */
7201             else
7202             {
7203                 return false;
7204             }
7205         } /* if (index == 0) */
7206         else
7207         {
7208             return false;
7209         }
7210         break;
7211     }
7212 
7213     case GL_ALPHA8_EXT:
7214     {
7215         // TODO: No extension available at the time of writing.
7216         return false;
7217     }
7218 
7219     case GL_LUMINANCE8_EXT:
7220     {
7221         // TODO: No extension available at the time of writing.
7222         return false;
7223     }
7224 
7225     case GL_LUMINANCE8_ALPHA8_EXT:
7226     {
7227         // TODO: No extension available at the time of writing.
7228         return false;
7229     }
7230 
7231     default:
7232     {
7233         TCU_FAIL("Unsupported internalformat");
7234     }
7235     } // switch (internalformat)
7236 
7237     return true;
7238 }
7239 
7240 /** Retrieves GLES format compatible for user-specified GLES internal format.
7241  *
7242  *  @param internalformat GLES internalformat to consider.
7243  *  @param out_format     Deref will be used to store the result. Cannot be NULL.
7244  *
7245  *  @return true if successful, false otherwise.
7246  **/
getFormatForInternalformat(GLenum internalformat,GLenum * out_format) const7247 bool TestBase::getFormatForInternalformat(GLenum internalformat, GLenum *out_format) const
7248 {
7249     DE_ASSERT(out_format != NULL);
7250 
7251     // Find out the format for user-provided internalformat
7252     switch (internalformat)
7253     {
7254     case GL_ALPHA:
7255         *out_format = GL_ALPHA;
7256         break;
7257 
7258     case GL_LUMINANCE_ALPHA:
7259         *out_format = GL_LUMINANCE_ALPHA;
7260         break;
7261 
7262     case GL_LUMINANCE:
7263     case GL_LUMINANCE8_OES:
7264         *out_format = GL_LUMINANCE;
7265         break;
7266 
7267     case GL_R8:
7268     case GL_R8_SNORM:
7269     case GL_R16F:
7270     case GL_R32F:
7271         *out_format = GL_RED;
7272         break;
7273 
7274     case GL_R8UI:
7275     case GL_R8I:
7276     case GL_R16UI:
7277     case GL_R16I:
7278     case GL_R32UI:
7279     case GL_R32I:
7280         *out_format = GL_RED_INTEGER;
7281         break;
7282 
7283     case GL_RG8:
7284     case GL_RG8_SNORM:
7285     case GL_RG16F:
7286     case GL_RG32F:
7287         *out_format = GL_RG;
7288         break;
7289 
7290     case GL_RG8UI:
7291     case GL_RG8I:
7292     case GL_RG16UI:
7293     case GL_RG16I:
7294     case GL_RG32UI:
7295     case GL_RG32I:
7296         *out_format = GL_RG_INTEGER;
7297         break;
7298 
7299     case GL_RGB:
7300     case GL_RGB8:
7301     case GL_SRGB8:
7302     case GL_RGB565:
7303     case GL_RGB8_SNORM:
7304     case GL_R11F_G11F_B10F:
7305     case GL_RGB9_E5:
7306     case GL_RGB16F:
7307     case GL_RGB32F:
7308         *out_format = GL_RGB;
7309         break;
7310 
7311     case GL_RGB8UI:
7312     case GL_RGB8I:
7313     case GL_RGB16UI:
7314     case GL_RGB16I:
7315     case GL_RGB32UI:
7316     case GL_RGB32I:
7317         *out_format = GL_RGB_INTEGER;
7318         break;
7319 
7320     case GL_RGBA:
7321     case GL_RGBA8:
7322     case GL_SRGB8_ALPHA8:
7323     case GL_RGBA8_SNORM:
7324     case GL_RGB5_A1:
7325     case GL_RGBA4:
7326     case GL_RGB10_A2:
7327     case GL_RGBA16F:
7328     case GL_RGBA32F:
7329         *out_format = GL_RGBA;
7330         break;
7331 
7332     case GL_RGBA8UI:
7333     case GL_RGBA8I:
7334     case GL_RGB10_A2UI:
7335     case GL_RGBA16UI:
7336     case GL_RGBA16I:
7337     case GL_RGBA32I:
7338     case GL_RGBA32UI:
7339         *out_format = GL_RGBA_INTEGER;
7340         break;
7341 
7342     case GL_DEPTH_COMPONENT16:
7343     case GL_DEPTH_COMPONENT24:
7344     case GL_DEPTH_COMPONENT32F:
7345         *out_format = GL_DEPTH_COMPONENT;
7346         break;
7347 
7348     case GL_DEPTH24_STENCIL8:
7349     case GL_DEPTH32F_STENCIL8:
7350         *out_format = GL_DEPTH_STENCIL;
7351         break;
7352 
7353     default:
7354         TCU_FAIL("Internalformat not recognized");
7355         return false;
7356     } // switch (internalformat)
7357 
7358     return true;
7359 }
7360 
7361 /** Retrieves FBO effective internal format at user-specified index.
7362  *
7363  *  Pays extra care not to reach outside of fbo_effective_internal_format_ordering array.
7364  *
7365  *  @param index Index to look up the internal format at.
7366  *
7367  *  @return Requested information or GL_NONE if failed or 0xFFFFFFFF if index is
7368  *          outside allowed range.
7369  **/
getFBOEffectiveInternalFormatAtIndex(unsigned int index) const7370 GLenum TestBase::getFBOEffectiveInternalFormatAtIndex(unsigned int index) const
7371 {
7372     const unsigned int n_effective_internalformats = DE_LENGTH_OF_ARRAY(fboEffectiveInternalFormatOrdering);
7373 
7374     DE_ASSERT(index < n_effective_internalformats);
7375     if (index < n_effective_internalformats)
7376         return fboEffectiveInternalFormatOrdering[index];
7377 
7378     // Return glitch
7379     m_testCtx.getLog() << tcu::TestLog::Message
7380                        << "GetFBOEffectiveInternalFormatAtIndex - Invalid index requested: " << index
7381                        << tcu::TestLog::EndMessage;
7382 
7383     return static_cast<GLenum>(0xFFFFFFFF);
7384 }
7385 
7386 /** Retrieves glCopyTexImage2D() internal format at user-specified index.
7387  *
7388  *  Pays extra care not to reach outside of copy_tex_image_2d_internal_format_orderingarray.
7389  *
7390  *  @param index Index to look up the internal format at.
7391  *
7392  *  @return Requested information or GL_NONE if failed or 0xFFFFFFFF if index is outside
7393  *          allowed range.
7394  **/
getCopyTexImage2DInternalFormatAtIndex(unsigned int index) const7395 GLenum TestBase::getCopyTexImage2DInternalFormatAtIndex(unsigned int index) const
7396 {
7397     const unsigned int n_internalformats = DE_LENGTH_OF_ARRAY(copyTexImage2DInternalFormatOrdering);
7398 
7399     DE_ASSERT(index < n_internalformats);
7400     if (index < n_internalformats)
7401         return copyTexImage2DInternalFormatOrdering[index];
7402 
7403     // Return glitch
7404     m_testCtx.getLog() << tcu::TestLog::Message
7405                        << "GetCopyTexImage2DInternalFormatAtIndex - Invalid index requested: " << index
7406                        << tcu::TestLog::EndMessage;
7407 
7408     return static_cast<GLenum>(0xFFFFFFFF);
7409 }
7410 
7411 /** Retrieves a string representing name of target passed by argument.
7412  *
7413  *  @param target GLES target to retrieve a string for.
7414  *
7415  *  @return A relevant string or "?" (without double quotation marks)
7416  *          if type is unrecognized.
7417  **/
getTargetName(GLenum target) const7418 const char *TestBase::getTargetName(GLenum target) const
7419 {
7420     const char *result = "?";
7421 
7422     switch (target)
7423     {
7424     case GL_RENDERBUFFER:
7425         result = "GL_RENDERBUFFER";
7426         break;
7427     case GL_TEXTURE_2D:
7428         result = "GL_TEXTURE_2D";
7429         break;
7430     case GL_TEXTURE_2D_ARRAY:
7431         result = "GL_TEXTURE_2D_ARRAY";
7432         break;
7433     case GL_TEXTURE_3D:
7434         result = "GL_TEXTURE_3D";
7435         break;
7436     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
7437         result = "GL_TEXTURE_CUBE_MAP_NEGATIVE_X";
7438         break;
7439     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
7440         result = "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y";
7441         break;
7442     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
7443         result = "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z";
7444         break;
7445     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
7446         result = "GL_TEXTURE_CUBE_MAP_POSITIVE_X";
7447         break;
7448     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
7449         result = "GL_TEXTURE_CUBE_MAP_POSITIVE_Y";
7450         break;
7451     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
7452         result = "GL_TEXTURE_CUBE_MAP_POSITIVE_Z";
7453         break;
7454     }
7455 
7456     return result;
7457 }
7458 
7459 /** Returns a general texture target for cube-map texture targets or
7460  *  user-specified target otherwise.
7461  *
7462  *  @param target GLES target to consider. Allowed values:
7463  *                1)  GL_RENDERBUFFER,
7464  *                2)  GL_TEXTURE_2D,
7465  *                3)  GL_TEXTURE_2D_ARRAY,
7466  *                4)  GL_TEXTURE_3D,
7467  *                5)  GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
7468  *                6)  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
7469  *                7)  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
7470  *                8)  GL_TEXTURE_CUBE_MAP_POSITIVE_X,
7471  *                9)  GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
7472  *                10) GL_TEXTURE_CUBE_MAP_POSITIVE_Z.
7473  *
7474  *  @return General texture target or used-specified target
7475  *          if successful, GL_NONE otherwise.
7476  */
getGeneralTargetForDetailedTarget(GLenum target)7477 GLenum TestBase::getGeneralTargetForDetailedTarget(GLenum target)
7478 {
7479     GLenum result = GL_NONE;
7480 
7481     switch (target)
7482     {
7483     case GL_RENDERBUFFER:
7484     case GL_TEXTURE_2D:
7485     case GL_TEXTURE_2D_ARRAY:
7486     case GL_TEXTURE_3D:
7487     {
7488         result = target;
7489 
7490         break;
7491     } // renderbuffer & 2D/3D texture targets
7492 
7493     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
7494     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
7495     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
7496     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
7497     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
7498     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
7499     {
7500         result = GL_TEXTURE_CUBE_MAP;
7501 
7502         break;
7503     } // cube-map texture targets
7504 
7505     default:
7506     {
7507         TCU_FAIL("Unrecognized target");
7508     }
7509     }
7510 
7511     return result;
7512 }
7513 
7514 /** Generates a GL object of an user-requested type.
7515  *
7516  *  NOTE: It is expected no error is reported by OpenGL ES prior to
7517  *        the call.
7518  *
7519  *  @param object_type Type of a GL object to create. Allowed values:
7520  *                     1)  GL_RENDERBUFFER,
7521  *                     2)  GL_TEXTURE_2D,
7522  *                     3)  GL_TEXTURE_2D_ARRAY,
7523  *                     4)  GL_TEXTURE_3D,
7524  *                     5)  GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
7525  *                     6)  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
7526  *                     7)  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
7527  *                     8)  GL_TEXTURE_CUBE_MAP_POSITIVE_X,
7528  *                     9)  GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
7529  *                     10) GL_TEXTURE_CUBE_MAP_POSITIVE_Z.
7530  *
7531  *  @return GLES ID (different than zero) of the created object if
7532  *          successful, zero otherwise.
7533  */
generateGLObject(GLenum object_type)7534 GLuint TestBase::generateGLObject(GLenum object_type)
7535 {
7536     const Functions &gl = m_context.getRenderContext().getFunctions();
7537     GLenum error_code   = GL_NO_ERROR;
7538     GLuint result       = 0;
7539 
7540     switch (object_type)
7541     {
7542     case GL_RENDERBUFFER:
7543     {
7544         gl.genRenderbuffers(1, &result);
7545         break;
7546     }
7547 
7548     case GL_TEXTURE_2D:
7549     case GL_TEXTURE_2D_ARRAY:
7550     case GL_TEXTURE_3D:
7551     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
7552     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
7553     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
7554     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
7555     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
7556     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
7557     {
7558         gl.genTextures(1, &result);
7559         break;
7560     }
7561 
7562     default:
7563         TCU_FAIL("Unsupported source attachment type");
7564     }
7565 
7566     // check if all is good with our new object
7567     error_code = gl.getError();
7568 
7569     if (error_code != GL_NO_ERROR)
7570     {
7571         m_testCtx.getLog() << tcu::TestLog::Message
7572                            << "Could not generate a renderbuffer OR texture object. GL reported error: [" << error_code
7573                            << "]" << tcu::TestLog::EndMessage;
7574         return 0;
7575     }
7576 
7577     return result;
7578 }
7579 
7580 /** Sets up a GL object and binds it to either GL_DRAW_FRAMEBUFFER
7581  *  (if @param is_source_gl_object is 0) or GL_READ_FRAMEBUFFER zeroth
7582  *  color attachment.
7583  *
7584  *  NOTE: The function assumes the object at @param object_id of @param
7585  *        object_target type has already been generated!
7586  *
7587  *  @param is_source_gl_object 1 if the object should be bound to
7588  *                             GL_DRAW_FRAMEBUFFER target once configured,
7589  *                             0 to bound the object to GL_READ_FRAMEBUFFER
7590  *                             target instead.
7591  *  @param object_target       Type of the object to configure. Allowed values:
7592  *                             1)  GL_RENDERBUFFER,
7593  *                             2)  GL_TEXTURE_2D,
7594  *                             3)  GL_TEXTURE_2D_ARRAY,
7595  *                             4)  GL_TEXTURE_3D,
7596  *                             5)  GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
7597  *                             6)  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
7598  *                             7)  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
7599  *                             8)  GL_TEXTURE_CUBE_MAP_POSITIVE_X,
7600  *                             9)  GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
7601  *                             10) GL_TEXTURE_CUBE_MAP_POSITIVE_Z.
7602  *  @param object_id           GLES ID of the object to configure.
7603  *  @param internal_format     Internal-format of the data under @param data.
7604  *  @param format              Format of the data under @param data.
7605  *  @param type                Type the data @param data is represented with.
7606  *  @param data                Buffer with the data to fill the object with.
7607  *                             Cannot be NULL.
7608  *
7609  *  @return true if successful, false otherwise.,
7610  **/
configureGLObject(int is_source_gl_object,GLenum object_target,GLint object_id,GLenum internal_format,GLenum format,GLenum type,void * data)7611 bool TestBase::configureGLObject(int is_source_gl_object, GLenum object_target, GLint object_id, GLenum internal_format,
7612                                  GLenum format, GLenum type, void *data)
7613 {
7614     const Functions &gl = m_context.getRenderContext().getFunctions();
7615     GLenum fbo_target   = (is_source_gl_object == 0) ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER;
7616     bool result         = true;
7617 
7618     // Special case for GL_HALF_FLOAT -> input data is in GL_FLOAT
7619     if (type == GL_HALF_FLOAT)
7620         type = GL_FLOAT;
7621 
7622     switch (object_target)
7623     {
7624     case GL_RENDERBUFFER:
7625     {
7626         GLint current_draw_fbo_id    = 0;
7627         GLint current_read_fbo_id    = 0;
7628         GLuint temporary_draw_fbo_id = 0;
7629         GLuint temporary_read_fbo_id = 0;
7630         GLuint temporary_to_id       = 0;
7631 
7632         // Retrieve current draw/read fbo bindings
7633         gl.getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_draw_fbo_id);
7634         gl.getIntegerv(GL_READ_FRAMEBUFFER_BINDING, &current_read_fbo_id);
7635 
7636         // Set up the RBO */
7637         gl.bindRenderbuffer(GL_RENDERBUFFER, object_id);
7638         gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, TEXTURE_WIDTH, TEXTURE_HEIGHT);
7639 
7640         // Generate a temporary 2D texture object and copy the data into it
7641         gl.genTextures(1, &temporary_to_id);
7642         gl.bindTexture(GL_TEXTURE_2D, temporary_to_id);
7643         gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, internal_format, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0 /* border */,
7644                       format, type, data);
7645 
7646         // Set up a temporary read FBO with the texture object attached to zeroth color attachment..
7647         gl.genFramebuffers(1, &temporary_read_fbo_id);
7648         gl.bindFramebuffer(GL_READ_FRAMEBUFFER, temporary_read_fbo_id);
7649         gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temporary_to_id,
7650                                 0 /* level */);
7651 
7652         // and another one we'll bind to draw framebuffer target with the renderbuffer object attached
7653         gl.genFramebuffers(1, &temporary_draw_fbo_id);
7654         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, temporary_draw_fbo_id);
7655         gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, object_id);
7656 
7657         // Blit the texture contents into the renderbuffer.
7658         gl.blitFramebuffer(0 /* srcX0 */, 0 /* srcY0 */, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0 /* dstX0 */, 0 /* dstY0 */,
7659                            TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
7660 
7661         // Restore pre-call configuration
7662         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, current_draw_fbo_id);
7663         gl.bindFramebuffer(GL_READ_FRAMEBUFFER, current_read_fbo_id);
7664 
7665         // Get rid of the temporary objects
7666         gl.bindTexture(GL_TEXTURE_2D, 0);
7667         gl.deleteTextures(1, &temporary_to_id);
7668         gl.deleteFramebuffers(1, &temporary_draw_fbo_id);
7669         gl.deleteFramebuffers(1, &temporary_read_fbo_id);
7670 
7671         // Update the pre-call framebuffer's attachment configuration
7672         gl.framebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, object_id);
7673         break;
7674     }
7675 
7676     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
7677     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
7678     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
7679     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
7680     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
7681     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
7682     {
7683         const GLenum cm_targets[] = {GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
7684                                      GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
7685                                      GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z};
7686         GLenum general_target     = getGeneralTargetForDetailedTarget(object_target);
7687         unsigned int n_cm_target  = 0;
7688 
7689         // Set up base mipmap for our source texture.
7690         gl.bindTexture(general_target, object_id);
7691 
7692         // Set up *all* faces of a cube-map (as per Bugzilla #9689 & #9807),
7693         // so that the CM texture is cube complete.
7694         for (n_cm_target = 0; n_cm_target < sizeof(cm_targets) / sizeof(cm_targets[0]); ++n_cm_target)
7695         {
7696             gl.texImage2D(cm_targets[n_cm_target], 0 /* level */, internal_format, TEXTURE_WIDTH, TEXTURE_HEIGHT,
7697                           0 /* border */, format, type, data);
7698         }
7699 
7700         gl.texParameterf(general_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7701         gl.texParameterf(general_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7702         gl.texParameterf(general_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7703         gl.texParameterf(general_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7704 
7705         // Set up the FBO attachment
7706         if (is_source_gl_object)
7707             gl.framebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0, object_target, object_id, 0);
7708 
7709         gl.bindTexture(general_target, 0);
7710         break;
7711     }
7712 
7713     case GL_TEXTURE_2D:
7714     {
7715         // Set up base mipmap for our source texture.
7716         gl.bindTexture(object_target, object_id);
7717         gl.texImage2D(object_target, 0 /* level */, internal_format, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0 /* border */,
7718                       format, type, data);
7719 
7720         gl.texParameterf(object_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7721         gl.texParameterf(object_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7722         gl.texParameterf(object_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7723         gl.texParameterf(object_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7724 
7725         // Set up the FBO attachment
7726         if (is_source_gl_object)
7727             gl.framebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0, object_target, object_id, 0);
7728 
7729         gl.bindTexture(object_target, 0);
7730         break;
7731     }
7732 
7733     case GL_TEXTURE_2D_ARRAY:
7734     case GL_TEXTURE_3D:
7735     {
7736         // Set up base mipmap for our source texture.
7737         gl.bindTexture(object_target, object_id);
7738         gl.texImage3D(object_target, 0 /* level */, internal_format, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH,
7739                       0 /* border */, format, type, NULL);
7740         gl.texSubImage3D(object_target, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */, TEXTURE_WIDTH,
7741                          TEXTURE_HEIGHT, 1 /* depth */, format, type, data);
7742 
7743         gl.texParameterf(object_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7744         gl.texParameterf(object_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7745         gl.texParameterf(object_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7746         gl.texParameterf(object_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7747         gl.texParameterf(object_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
7748 
7749         DE_ASSERT(is_source_gl_object);
7750 
7751         // Set up the FBO attachment. Make sure there is an actual difference from gl.framebufferTexture2D()
7752         // and use the second layer of the texture.
7753         gl.framebufferTextureLayer(fbo_target, GL_COLOR_ATTACHMENT0, object_id, 0 /* level */, 1 /* layer */);
7754 
7755         gl.bindTexture(object_target, 0);
7756         break;
7757     }
7758 
7759     default:
7760     {
7761         // ASSERTION FAILURE: unsupported source attachment type
7762         DE_ASSERT(0);
7763         result = false;
7764     }
7765     } /* switch (source_attachment_type) */
7766 
7767     if (result)
7768     {
7769         GLenum error_code = gl.getError();
7770 
7771         if (error_code != GL_NO_ERROR)
7772         {
7773             m_testCtx.getLog() << tcu::TestLog::Message << "Could not set up a GL object ["
7774                                << (is_source_gl_object ? "source" : "destination") << "] of format ["
7775                                << getInternalformatString(internal_format) << "] to be used as "
7776                                << getTargetName(object_target) << " attachment for the test. GL reported error ["
7777                                << error_code << "]";
7778             return false;
7779         }
7780     }
7781 
7782     return result;
7783 }
7784 
7785 /** Releases a GL object. If @param target represents a texture,
7786  *  the object is unbound from the target prior to a gl.deleteTextures()
7787  *  call.
7788  *
7789  *  @param target    Type of the object to release. Allowed values:
7790  *                   1)  GL_RENDERBUFFER,
7791  *                   2)  GL_TEXTURE_2D,
7792  *                   3)  GL_TEXTURE_2D_ARRAY,
7793  *                   4)  GL_TEXTURE_3D,
7794  *                   5)  GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
7795  *                   6)  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
7796  *                   7)  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
7797  *                   8)  GL_TEXTURE_CUBE_MAP_POSITIVE_X,
7798  *                   9)  GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
7799  *                   10) GL_TEXTURE_CUBE_MAP_POSITIVE_Z.
7800  *
7801  *  @param object_id GLES ID of the object to release.
7802  */
destroyGLObject(GLenum target,GLuint object_id)7803 void TestBase::destroyGLObject(GLenum target, GLuint object_id)
7804 {
7805     const Functions &gl = m_context.getRenderContext().getFunctions();
7806     switch (target)
7807     {
7808     case GL_RENDERBUFFER:
7809     {
7810         gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
7811         gl.deleteRenderbuffers(1, &object_id);
7812         break;
7813     }
7814 
7815     case GL_TEXTURE_2D:
7816     case GL_TEXTURE_2D_ARRAY:
7817     case GL_TEXTURE_3D:
7818     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
7819     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
7820     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
7821     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
7822     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
7823     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
7824     {
7825         GLenum general_attachment_type = getGeneralTargetForDetailedTarget(target);
7826         gl.bindTexture(general_attachment_type, 0);
7827         gl.deleteTextures(1, &object_id);
7828         break;
7829     }
7830 
7831     default:
7832     {
7833         TCU_FAIL("Unsupported attachment type.");
7834     }
7835     }
7836 }
7837 
7838 /** Tells whether @param internalformat can be used for
7839  *  a gl.renderbufferStorage*() call.
7840  *
7841  *  @param internalformat Internalformat to consider.
7842  *
7843  *  @return true if the internal format can be used for the call,
7844  *          false otherwise.
7845  **/
isValidRBOInternalFormat(GLenum internalformat) const7846 bool TestBase::isValidRBOInternalFormat(GLenum internalformat) const
7847 {
7848     // Internal format can be used for gl.renderbufferStorage()
7849     // call if it's either color-, depth- or stencil-renderable.
7850     return isColorRenderableInternalFormat(internalformat) || isDepthRenderableInternalFormat(internalformat) ||
7851            isDepthStencilRenderableInternalFormat(internalformat);
7852 }
7853 
7854 /** Tells whether internal format @param internalformat is color-renderable.
7855  *
7856  *  @param internalformat GLES internal format to consider.
7857  *
7858  *  @return true if @param internalformat is color-renderable, false otherwise
7859  **/
isColorRenderableInternalFormat(GLenum internalformat) const7860 bool TestBase::isColorRenderableInternalFormat(GLenum internalformat) const
7861 {
7862     const glu::ContextInfo &contextInfo = m_context.getContextInfo();
7863 
7864     bool supports_fp_textures      = contextInfo.isExtensionSupported("GL_EXT_color_buffer_float");
7865     bool supports_half_fp_textures = contextInfo.isExtensionSupported("GL_EXT_color_buffer_half_float");
7866 
7867     // Floating-point textures are only supported if
7868     // implementation supports GL_EXT_color_buffer_float extension
7869     if (!supports_fp_textures && (internalformat == GL_R32F || internalformat == GL_RG32F ||
7870                                   internalformat == GL_RGB32F || internalformat == GL_RGBA32F))
7871     {
7872         return false;
7873     }
7874 
7875     // Half floating-point textures are only supported if
7876     // implementation supports GL_EXT_color_buffer_half_float extension
7877     if (!supports_half_fp_textures && (internalformat == GL_R16F || internalformat == GL_RG16F ||
7878                                        internalformat == GL_RGB16F || internalformat == GL_RGBA16F))
7879     {
7880         return false;
7881     }
7882 
7883     switch (internalformat)
7884     {
7885     case GL_RGB:
7886     case GL_RGBA:
7887     case GL_R8:
7888     case GL_RG8:
7889     case GL_RGB8:
7890     case GL_RGB565:
7891     case GL_RGBA4:
7892     case GL_RGB5_A1:
7893     case GL_RGBA8:
7894     case GL_RGB10_A2:
7895     case GL_RGB10_A2UI:
7896     case GL_SRGB8_ALPHA8:
7897     case GL_R8I:
7898     case GL_R8UI:
7899     case GL_R16I:
7900     case GL_R16UI:
7901     case GL_R32I:
7902     case GL_R32UI:
7903     case GL_RG8I:
7904     case GL_RG8UI:
7905     case GL_RG16I:
7906     case GL_RG16UI:
7907     case GL_RG32I:
7908     case GL_RG32UI:
7909     case GL_RGBA8I:
7910     case GL_RGBA8UI:
7911     case GL_RGBA16I:
7912     case GL_RGBA16UI:
7913     case GL_RGBA32I:
7914     case GL_RGBA32UI:
7915         // GLES3.0 color-renderable internalformats
7916         return true;
7917 
7918     case GL_R16F:
7919     case GL_R32F:
7920     case GL_RG16F:
7921     case GL_RG32F:
7922     case GL_RGB16F:
7923     // GL_RGB32F not supported
7924     case GL_RGBA16F:
7925     case GL_RGBA32F:
7926         // Since we passed the above checks, we can assume
7927         // the internalformats are color-renderable
7928         return true;
7929 
7930     default:
7931         return false;
7932     }
7933 
7934     return false;
7935 }
7936 
7937 /** Tells whether internal format @param internalformat is depth-renderable.
7938  *
7939  *  @param internalformat GLES internal format to consider.
7940  *
7941  *  @return true if @param internalformat is depth-renderable, false otherwise
7942  **/
isDepthRenderableInternalFormat(GLenum internalformat) const7943 bool TestBase::isDepthRenderableInternalFormat(GLenum internalformat) const
7944 {
7945     switch (internalformat)
7946     {
7947     case GL_DEPTH_COMPONENT16:
7948     case GL_DEPTH_COMPONENT24:
7949     case GL_DEPTH_COMPONENT32F:
7950         return true;
7951     }
7952 
7953     return false;
7954 }
7955 
7956 /** Tells whether internal format @param internalformat is depth+stencil-renderable.
7957  *
7958  *  @param internalformat GLES internal format to consider.
7959  *
7960  *  @return true if @param internalformat is depth+stencil-renderable, false otherwise
7961  **/
isDepthStencilRenderableInternalFormat(GLenum internalformat) const7962 bool TestBase::isDepthStencilRenderableInternalFormat(GLenum internalformat) const
7963 {
7964     switch (internalformat)
7965     {
7966     case GL_DEPTH24_STENCIL8:
7967     case GL_DEPTH32F_STENCIL8:
7968         return true;
7969     }
7970 
7971     return false;
7972 }
7973 
7974 /** Tells whether OpenGL ES 3.0 implementations should accept copying texture image data from
7975  *  a read buffer using @param src_internalformat internalformat-based storage to a texture object
7976  *  using an internal format @param dst_internalformat.
7977  *
7978  *  @param src_internalformat Internal format to be used for source object's data storage.
7979  *  @param dst_internalformat Internal format to be used for destination texture object's data storage.
7980  *
7981  *  @return true if the operation is expected to execute successfully, false otherwise.
7982  */
isFBOEffectiveInternalFormatCompatibleWithDestinationInternalFormat(GLenum src_internalformat,GLenum dst_internalformat) const7983 bool TestBase::isFBOEffectiveInternalFormatCompatibleWithDestinationInternalFormat(GLenum src_internalformat,
7984                                                                                    GLenum dst_internalformat) const
7985 {
7986     const unsigned int n_copyteximage_internalformats = DE_LENGTH_OF_ARRAY(copyTexImage2DInternalFormatOrdering);
7987     unsigned int n_dst_internalformat                 = 0;
7988     const unsigned int n_effective_internalformats    = DE_LENGTH_OF_ARRAY(fboEffectiveInternalFormatOrdering);
7989     unsigned int n_src_internalformat                 = 0;
7990     bool result                                       = false;
7991 
7992     // Find out which index does the source internalformat use
7993     while (n_src_internalformat < n_effective_internalformats)
7994     {
7995         GLenum internalformat_at_n = getFBOEffectiveInternalFormatAtIndex(n_src_internalformat);
7996 
7997         if (internalformat_at_n == src_internalformat)
7998             break;
7999         else
8000             ++n_src_internalformat;
8001     }
8002 
8003     DE_ASSERT(n_src_internalformat != n_effective_internalformats);
8004     if (n_src_internalformat == n_effective_internalformats)
8005         return false;
8006 
8007     // Find out which index does the target internalformat use
8008     while (n_dst_internalformat < n_copyteximage_internalformats)
8009     {
8010         GLenum internalformat_at_n = getCopyTexImage2DInternalFormatAtIndex(n_dst_internalformat);
8011 
8012         if (internalformat_at_n == dst_internalformat)
8013             break;
8014         else
8015             ++n_dst_internalformat;
8016     }
8017 
8018     DE_ASSERT(n_dst_internalformat != n_copyteximage_internalformats);
8019     if (n_dst_internalformat == n_copyteximage_internalformats)
8020         return false;
8021 
8022     // Find out if the conversion is allowed
8023     unsigned int conversion_array_index = n_copyteximage_internalformats * n_src_internalformat + n_dst_internalformat;
8024 
8025     DE_ASSERT(conversion_array_index < (sizeof(conversionArray) / sizeof(GLenum)));
8026     if (conversion_array_index < (sizeof(conversionArray) / sizeof(GLenum)))
8027         result = (conversionArray[conversion_array_index] != GL_NONE);
8028 
8029     return result;
8030 }
8031 
8032 /** Retrieves a string representing name of internal format passed by argument.
8033  *
8034  *  @param internalformat GLES internal format to retrieve a string for.
8035  *
8036  *  @return A relevant string or "?" (without double quotation marks)
8037  *          if type is unrecognized.
8038  **/
getInternalformatString(GLenum internalformat)8039 const char *TestBase::getInternalformatString(GLenum internalformat)
8040 {
8041     switch (internalformat)
8042     {
8043     case GL_ALPHA:
8044         return "GL_ALPHA";
8045     case GL_ALPHA8_OES:
8046         return "GL_ALPHA8";
8047     case GL_LUMINANCE:
8048         return "GL_LUMINANCE";
8049     case GL_LUMINANCE8_OES:
8050         return "GL_LUMINANCE8";
8051     case GL_LUMINANCE8_ALPHA8_OES:
8052         return "GL_LUMINANCE8_ALPHA8";
8053     case GL_LUMINANCE_ALPHA:
8054         return "GL_LUMINANCE_ALPHA";
8055     case GL_R11F_G11F_B10F:
8056         return "GL_R11F_G11F_B10F";
8057     case GL_R16F:
8058         return "GL_R16F";
8059     case GL_R16I:
8060         return "GL_R16I";
8061     case GL_R16UI:
8062         return "GL_R16UI";
8063     case GL_R32F:
8064         return "GL_R32F";
8065     case GL_R32I:
8066         return "GL_R32I";
8067     case GL_R32UI:
8068         return "GL_R32UI";
8069     case GL_R8:
8070         return "GL_R8";
8071     case GL_R8I:
8072         return "GL_R8I";
8073     case GL_R8UI:
8074         return "GL_R8UI";
8075     case GL_R8_SNORM:
8076         return "GL_R8_SNORM";
8077     case GL_RG16F:
8078         return "GL_RG16F";
8079     case GL_RG16I:
8080         return "GL_RG16I";
8081     case GL_RG16UI:
8082         return "GL_RG16UI";
8083     case GL_RG32F:
8084         return "GL_RG32F";
8085     case GL_RG32I:
8086         return "GL_RG32I";
8087     case GL_RG32UI:
8088         return "GL_RG32UI";
8089     case GL_RG8:
8090         return "GL_RG8";
8091     case GL_RG8I:
8092         return "GL_RG8I";
8093     case GL_RG8UI:
8094         return "GL_RG8UI";
8095     case GL_RG8_SNORM:
8096         return "GL_RG8_SNORM";
8097     case GL_RGB:
8098         return "GL_RGB";
8099     case GL_RGB10_A2:
8100         return "GL_RGB10_A2";
8101     case GL_RGB10_A2UI:
8102         return "GL_RGB10_A2UI";
8103     case GL_RGB16F:
8104         return "GL_RGB16F";
8105     case GL_RGB16I:
8106         return "GL_RGB16I";
8107     case GL_RGB16UI:
8108         return "GL_RGB16UI";
8109     case GL_RGB32F:
8110         return "GL_RGB32F";
8111     case GL_RGB32I:
8112         return "GL_RGB32I";
8113     case GL_RGB32UI:
8114         return "GL_RGB32UI";
8115     case GL_RGB5_A1:
8116         return "GL_RGB5_A1";
8117     case GL_RGB8:
8118         return "GL_RGB8";
8119     case GL_RGB8I:
8120         return "GL_RGB8I";
8121     case GL_RGB8UI:
8122         return "GL_RGB8UI";
8123     case GL_RGB8_SNORM:
8124         return "GL_RGB8_SNORM";
8125     case GL_RGB9_E5:
8126         return "GL_RGB9_E5";
8127     case GL_RGBA:
8128         return "GL_RGBA";
8129     case GL_RGBA16I:
8130         return "GL_RGBA16I";
8131     case GL_RGBA16UI:
8132         return "GL_RGBA16UI";
8133     case GL_RGBA4:
8134         return "GL_RGBA4";
8135     case GL_RGBA32I:
8136         return "GL_RGBA32I";
8137     case GL_RGBA32UI:
8138         return "GL_RGBA32UI";
8139     case GL_RGBA8I:
8140         return "GL_RGBA8I";
8141     case GL_RGBA8UI:
8142         return "GL_RGBA8UI";
8143     case GL_RGB565:
8144         return "GL_RGB565";
8145     case GL_RGBA16F:
8146         return "GL_RGBA16F";
8147     case GL_RGBA32F:
8148         return "GL_RGBA32F";
8149     case GL_RGBA8:
8150         return "GL_RGBA8";
8151     case GL_RGBA8_SNORM:
8152         return "GL_RGBA8_SNORM";
8153     case GL_SRGB8:
8154         return "GL_SRGB8";
8155     case GL_SRGB8_ALPHA8:
8156         return "GL_SRGB8_ALPHA8";
8157     }
8158 
8159     return "GL_NONE";
8160 }
8161 
8162 /* SPECIFICATION:
8163  *
8164  * This conformance test verifies that glCopyTexImage2D() implementation accepts
8165  * internalformats that are compatible with effective internalformat of current
8166  * read buffer.
8167  *
8168  * The test starts from creating two framebuffer objects, that it accordingly binds
8169  * to GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER targets. It then enters two-level loop:
8170  *
8171  * a) First level determines source attachment type: this could either be a 2D texture/cube-map
8172  *    face mip-map, a specific mip-map of a slice coming from a 2D texture array OR a 3D texture,
8173  *    or finally a render-buffer. All of these can be bound to an attachment point that is
8174  *    later pointed to by read buffer configuration.
8175  * b) Second level configures attachment type of destination. Since glCopyTexImage2D()
8176  *    specification limits accepted targets, only 2D texture or cube-map face targets are
8177  *    accepted.
8178  *
8179  * For each viable source/destination configuration, the test then enters another two-level loop:
8180  *
8181  * I)  First sub-level determines what internal format should be used for the source attachment.
8182  *     All texture formats required from a conformant GLES3.0 implementation are iterated over.
8183  * II) Second sub-level determines internal format that should be passed as a parameter to
8184  *     a glCopyTexImage2D() call.
8185  *
8186  * For each internal format pair, the test creates and configures a corresponding GL object and
8187  * attaches it to the read framebuffer. The test also uses a pre-generated texture object ID that
8188  * will be re-configured with each glCopyTexImage2D() call.
8189  *
8190  * Source data is a 2x2 array consisting of up to 4 channels with different values, represented
8191  * in an iteration-specific format and type. For more details, please see implementation of
8192  * ConfigureConversionDatabase() entry-point.
8193  *
8194  * The test then loops over all supported format+type combinations for the internal-format considered
8195  * and feeds them into actual glCopyTexImage2D() call. It is against the specification for the call
8196  * to fail at this point. Should this be the case, the test is considered to fail but will continue
8197  * iterating over all the loops to make sure all problems are reported within a single run.
8198  *
8199  * Once the call is determined to have finished successfully, the test attempts to read the result data.
8200  * This needs to be handled in two ways:
8201  *
8202  * - if internalformat is color-renderable, we can attach the result texture to the read framebuffer object
8203  *   and do a glReadPixels() call. For some combinations of internalformat and attachment types the implementations
8204  *   are allowed to report unsupported framebuffer configuration, in which case the test will proceed with testing
8205  *   remaining source/destination/internalformat combinations and will not consider this an error.
8206  * - if internalformat is not color-renderable, we need to bind the result texture to a texture unit and
8207  *   use a program object to determine whether the data made available are valid. THIS CASE IS NOT IMPLEMENTED
8208  *   YET!
8209  *
8210  * Once the data are downloaded, they are compared against reference texture data. Should the rendered output
8211  * diverge outside the allowed epsilon, the test will report an error but will continue iterating to make sure
8212  * all source/destination/internalformat combinations are covered.
8213  */
8214 class RequiredCase : public TestBase
8215 {
8216 public:
8217     RequiredCase(deqp::Context &context, de::SharedPtr<ConversionDatabase> database, GLenum sourceAttachmentTypes,
8218                  GLenum destinationAttachmentTypes);
8219     virtual ~RequiredCase();
8220 
8221     void deinit(void);
8222     tcu::TestNode::IterateResult iterate(void);
8223 
8224 protected:
8225     bool execute(GLenum src_internalformat, GLenum dst_internalformat,
8226                  NonRenderableInternalformatSupportObjects *objects_ptr);
8227     bool bindTextureToTargetToSpecificTextureUnit(GLuint to_id, GLenum texture_target, GLenum texture_unit);
8228     bool setUniformValues(GLint source_2D_texture_uniform_location, GLenum source_2D_texture_unit,
8229                           GLint source_2DArray_texture_uniform_location, GLenum source_2DArray_texture_unit,
8230                           GLint source_3D_texture_uniform_location, GLenum source_3D_texture_unit,
8231                           GLint source_Cube_texture_uniform_location, GLenum source_Cube_texture_unit,
8232                           GLint destination_2D_texture_uniform_location, GLenum destination_2D_texture_unit,
8233                           GLint destination_Cube_texture_uniform_location, GLenum destination_Cube_texture_unit,
8234                           GLint channels_to_compare_uniform_location, GLint channels_to_compare,
8235                           GLint samplers_to_use_uniform_location, GLint samplers_to_use);
8236     bool copyDataFromBufferObject(GLuint bo_id, std::vector<GLint> &retrieved_data);
8237     bool findEntryInConversionDatabase(unsigned int index, GLenum src_internalformat, GLenum src_type,
8238                                        GLenum copyteximage2d_internalformat, GLenum *out_result_internalformat,
8239                                        GLenum *out_dst_type, PixelData *out_src_topleft, PixelData *out_src_topright,
8240                                        PixelData *out_src_bottomleft, PixelData *out_src_bottomright,
8241                                        PixelData *out_dst_topleft, PixelData *out_dst_topright,
8242                                        PixelData *out_dst_bottomleft, PixelData *out_dst_bottomright,
8243                                        PixelCompareChannel *out_channels_to_compare);
8244     int getIndexOfCopyTexImage2DInternalFormat(GLenum internalformat);
8245     int getIndexOfFramebufferEffectiveInternalFormat(GLenum internalformat);
8246     bool compareExpectedResultsByReadingPixels(PixelData source_tl_pixel_data, PixelData source_tr_pixel_data,
8247                                                PixelData source_bl_pixel_data, PixelData source_br_pixel_data,
8248                                                PixelData reference_tl_pixel_data, PixelData reference_tr_pixel_data,
8249                                                PixelData reference_bl_pixel_data, PixelData reference_br_pixel_data,
8250                                                GLenum read_type, GLenum result_internalformat);
8251     unsigned int getSizeOfPixel(GLenum format, GLenum type);
8252     bool getPixelDataFromRawData(void *raw_data, GLenum raw_data_format, GLenum raw_data_type, PixelData *out_result);
8253     bool comparePixelData(PixelData downloaded_pixel, PixelData reference_pixel, PixelData source_pixel,
8254                           GLenum result_internalformat, bool has_test_failed_already);
8255     bool getNumberOfBitsForInternalFormat(GLenum internalformat, int *out_rgba_bits);
8256 
8257     bool getRawDataFromPixelData(std::vector<char> &result, PixelData topleft, PixelData topright, PixelData bottomleft,
8258                                  PixelData bottomright);
8259     bool getNumberOfBitsForChannelDataType(ChannelDataType channel_data_type, int *out_n_bits);
8260 
8261     bool getChannelOrderForInternalformatAndType(GLenum internalformat, GLenum type, ChannelOrder *out_channel_order);
8262     bool generateObjectsToSupportNonColorRenderableInternalformats();
8263     bool prepareSupportForNonRenderableTexture(NonRenderableInternalformatSupportObjects &objects,
8264                                                DataSamplerType src_texture_sampler_type,
8265                                                DataSamplerType dst_texture_sampler_type, GLenum source_attachment_type,
8266                                                GLenum destination_attachment_type);
8267     bool calculateBufferDataSize(DataSamplerType sampler_type, GLuint *buffer_data_size_ptr);
8268     const float *getTexCoordinates(GLenum attachment_type) const;
8269     bool prepareProgramAndShaderObjectsToSupportNonRenderableTexture(GLuint program_object_id,
8270                                                                      GLuint fragment_shader_object_id,
8271                                                                      GLuint vertex_shader_object_id,
8272                                                                      DataSamplerType src_texture_sampler_type,
8273                                                                      DataSamplerType dst_texture_sampler_type);
8274     bool setSourceForShaderObjectsUsedForNonRenderableTextureSupport(GLuint fragment_shader_object_id,
8275                                                                      GLuint vertex_shader_object_id,
8276                                                                      DataSamplerType src_texture_sampler_type,
8277                                                                      DataSamplerType dst_texture_sampler_type);
8278     bool compileAndCheckShaderCompilationStatus(GLuint shader_object_id);
8279     bool linkAndCheckProgramLinkStatus(GLuint program_object_id);
8280     bool getUniformLocations(GLuint program_object_id, GLint *source_2D_texture_uniform_location_ptr,
8281                              GLint *source_2DArray_texture_uniform_location_ptr,
8282                              GLint *source_3D_texture_uniform_location_ptr,
8283                              GLint *source_Cube_texture_uniform_location_ptr,
8284                              GLint *destination_2D_texture_uniform_location_ptr,
8285                              GLint *destination_Cube_texture_uniform_location_ptr,
8286                              GLint *channels_to_compare_uniform_location_ptr,
8287                              GLint *samplers_to_use_uniform_location_ptr);
8288     void displayPixelComparisonFailureMessage(GLint source_pixel_r, GLint source_pixel_g, GLint source_pixel_b,
8289                                               GLint source_pixel_a, GLenum source_internalformat, GLenum source_type,
8290                                               GLint reference_pixel_r, GLint reference_pixel_g, GLint reference_pixel_b,
8291                                               GLint reference_pixel_a, GLenum reference_internalformat,
8292                                               GLenum reference_type, GLint result_pixel_r, GLint result_pixel_g,
8293                                               GLint result_pixel_b, GLint result_pixel_a, GLenum result_internalformat,
8294                                               GLenum result_type, GLint max_epsilon_r, GLint max_epsilon_g,
8295                                               GLint max_epsilon_b, GLint max_epsilon_a);
8296     DataSamplerType getDataSamplerTypeForInternalformat(GLenum internalformat);
8297     bool isInternalFormatCompatibleWithFPSampler(GLenum internalformat);
8298     bool isInternalFormatCompatibleWithIntegerSampler(GLenum internalformat);
8299     bool isInternalFormatCompatibleWithUnsignedIntegerSampler(GLenum internalformat);
8300     void destroyObjectsSupportingNonRenderableInternalformats(NonRenderableInternalformatSupportObjects &objects);
8301     void unbindAndDestroyBufferObject(GLuint bo_id);
8302     void destroyTransformFeedbackObject(GLuint transform_feedback_object_id);
8303     void destroyProgramAndShaderObjects(GLuint program_object_id, GLuint fragment_shader_id, GLuint vertex_shader_id);
8304     void unbindColorAttachments();
8305     void restoreBindings(GLenum src_attachment_point, GLenum dst_attachment_point, GLint bound_draw_fbo_id,
8306                          GLint bound_read_fbo_id);
8307 
8308 private:
8309     GLuint m_dst_object_id;
8310     GLuint m_src_object_id;
8311 
8312     de::SharedPtr<ConversionDatabase> m_conversion_database;
8313 
8314     // Some of the internalformats considered during the test are not renderable, meaning
8315     // we cannot use glReadPixels() to retrieve their contents.
8316     // Instead, a special program object needs to be used to perform the verification in
8317     // actual shader.
8318     // We create a program object for possible each float/int/uint->float/int/uint combination.
8319     // All objects created during the process are stored in a dedicated
8320     // _non_renderable_internalformat_support_objects instance and released once the test ends.
8321     NonRenderableInternalformatSupportObjects m_f_src_f_dst_internalformat;
8322     NonRenderableInternalformatSupportObjects m_i_src_i_dst_internalformat;
8323     NonRenderableInternalformatSupportObjects m_ui_src_ui_dst_internalformat;
8324 };
8325 
RequiredCase(deqp::Context & context,de::SharedPtr<ConversionDatabase> database,GLenum sourceAttachmentTypes,GLenum destinationAttachmentTypes)8326 RequiredCase::RequiredCase(deqp::Context &context, de::SharedPtr<ConversionDatabase> database,
8327                            GLenum sourceAttachmentTypes, GLenum destinationAttachmentTypes)
8328     : TestBase(context, sourceAttachmentTypes, destinationAttachmentTypes)
8329     , m_dst_object_id(0)
8330     , m_src_object_id(0)
8331     , m_conversion_database(database)
8332 {
8333     deMemset(&m_f_src_f_dst_internalformat, 0, sizeof(m_f_src_f_dst_internalformat));
8334     deMemset(&m_i_src_i_dst_internalformat, 0, sizeof(m_i_src_i_dst_internalformat));
8335     deMemset(&m_ui_src_ui_dst_internalformat, 0, sizeof(m_ui_src_ui_dst_internalformat));
8336 }
8337 
~RequiredCase()8338 RequiredCase::~RequiredCase()
8339 {
8340 }
8341 
deinit(void)8342 void RequiredCase::deinit(void)
8343 {
8344     // free shared pointer
8345     m_conversion_database.clear();
8346 
8347     // Release the source object before we continue
8348     if (m_src_object_id != 0)
8349     {
8350         destroyGLObject(m_source_attachment_type, m_src_object_id);
8351 
8352         m_src_object_id = 0;
8353     }
8354 
8355     if (m_dst_object_id != 0)
8356     {
8357         destroyGLObject(m_destination_attachment_type, m_dst_object_id);
8358 
8359         m_dst_object_id = 0;
8360     }
8361 
8362     destroyObjectsSupportingNonRenderableInternalformats(m_f_src_f_dst_internalformat);
8363     destroyObjectsSupportingNonRenderableInternalformats(m_i_src_i_dst_internalformat);
8364     destroyObjectsSupportingNonRenderableInternalformats(m_ui_src_ui_dst_internalformat);
8365 }
8366 
iterate(void)8367 tcu::TestNode::IterateResult RequiredCase::iterate(void)
8368 {
8369     glu::RenderContext &renderContext = m_context.getRenderContext();
8370     const Functions &gl               = renderContext.getFunctions();
8371 
8372     GLuint draw_fbo_id = 0;
8373     GLuint read_fbo_id = 0;
8374     gl.genFramebuffers(1, &draw_fbo_id);
8375     gl.genFramebuffers(1, &read_fbo_id);
8376 
8377     gl.bindTexture(GL_TEXTURE_2D, 0);
8378     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, draw_fbo_id);
8379     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, read_fbo_id);
8380 
8381     // We will be reading from zeroth color attachment
8382     gl.readBuffer(GL_COLOR_ATTACHMENT0);
8383 
8384     // Make sure the pixel storage is configured accordingly to our data sets!
8385     gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
8386     gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
8387     GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei");
8388 
8389     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8390 
8391     // Quick checks
8392     DE_ASSERT(m_destination_attachment_type == GL_TEXTURE_2D ||
8393               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
8394               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
8395               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
8396               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
8397               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
8398               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
8399 
8400     // Determine general attachment type
8401     GLenum general_attachment_type = getGeneralTargetForDetailedTarget(m_source_attachment_type);
8402     if (general_attachment_type == GL_NONE)
8403         return STOP;
8404 
8405     // Set up source object
8406     m_src_object_id = generateGLObject(m_source_attachment_type);
8407     if (m_src_object_id == 0)
8408         return STOP;
8409 
8410     // Set up destination object
8411     m_dst_object_id = generateGLObject(m_destination_attachment_type);
8412     if (m_dst_object_id == 0)
8413         return STOP;
8414 
8415     // Generate all objects required to execute the non-renderable internalformat tests.
8416     // Can't use the shader on GL_RENDERBUFFER as source.
8417     if (m_source_attachment_type != GL_RENDERBUFFER && !generateObjectsToSupportNonColorRenderableInternalformats())
8418     {
8419         return STOP;
8420     }
8421 
8422     m_conversion_database.get()->initializeDatabase();
8423 
8424     // Run through all FBO internal formats.
8425     bool result                      = true;
8426     const int n_dst_internal_formats = DE_LENGTH_OF_ARRAY(copyTexImage2DInternalFormatOrdering);
8427     const int n_fbo_internal_formats = DE_LENGTH_OF_ARRAY(fboEffectiveInternalFormatOrdering);
8428     for (int n_fbo_internal_format = 0; n_fbo_internal_format < n_fbo_internal_formats; ++n_fbo_internal_format)
8429     {
8430         GLenum fbo_internalformat = fboEffectiveInternalFormatOrdering[n_fbo_internal_format];
8431 
8432         // Run through all destination internal formats.
8433         for (int n_dst_internal_format = 0; n_dst_internal_format < n_dst_internal_formats; ++n_dst_internal_format)
8434         {
8435             GLenum dst_internalformat = copyTexImage2DInternalFormatOrdering[n_dst_internal_format];
8436 
8437             switch (getDataSamplerTypeForInternalformat(fbo_internalformat))
8438             {
8439             case DATA_SAMPLER_FLOAT:
8440             {
8441                 switch (getDataSamplerTypeForInternalformat(dst_internalformat))
8442                 {
8443                 case DATA_SAMPLER_FLOAT:
8444                 {
8445                     if (!execute(fbo_internalformat, dst_internalformat, &m_f_src_f_dst_internalformat))
8446                     {
8447                         // At least one conversion was invalid or failed. Test should fail,
8448                         // but let's continue iterating over internalformats.
8449                         result = false;
8450                     }
8451 
8452                     break;
8453                 }
8454 
8455                 case DATA_SAMPLER_INTEGER:
8456                 case DATA_SAMPLER_UNSIGNED_INTEGER:
8457                 {
8458                     // There shouldn't be any valid conversion formats in this case. Just pass NULL for the non-renderable case's objects.
8459                     // The test will fail if we try to verify the copy for different data type formats
8460                     if (!execute(fbo_internalformat, dst_internalformat, NULL))
8461                     {
8462                         // At least one conversion was invalid or failed. Test should
8463                         // fail, but let's continue iterating over internalformats.
8464                         result = false;
8465                     }
8466 
8467                     break;
8468                 }
8469 
8470                 default:
8471                 {
8472                     // Unrecognized destination internalformat
8473                     DE_ASSERT(0);
8474                     break;
8475                 }
8476                 } // switch (GetDataSamplerTypeForInternalformat(dst_internalformat) )
8477 
8478                 break;
8479             }
8480 
8481             case DATA_SAMPLER_INTEGER:
8482             {
8483                 switch (getDataSamplerTypeForInternalformat(dst_internalformat))
8484                 {
8485                 case DATA_SAMPLER_INTEGER:
8486                 {
8487                     if (!execute(fbo_internalformat, dst_internalformat, &m_i_src_i_dst_internalformat))
8488                     {
8489                         // At least one conversion was invalid or failed. Test should fail,
8490                         // but let's continue iterating over internalformats.
8491                         result = false;
8492                     }
8493 
8494                     break;
8495                 }
8496 
8497                 case DATA_SAMPLER_FLOAT:
8498                 case DATA_SAMPLER_UNSIGNED_INTEGER:
8499                 {
8500                     // There shouldn't be any valid conversion formats in this case. Just pass NULL for the non-renderable case's objects.
8501                     // The test will fail if we try to verify the copy for different data type formats
8502                     if (!execute(fbo_internalformat, dst_internalformat, NULL))
8503                     {
8504                         // At least one conversion was invalid or failed. Test should fail,
8505                         // but let's continue iterating over internalformats.
8506                         result = false;
8507                     }
8508 
8509                     break;
8510                 }
8511 
8512                 default:
8513                 {
8514                     // Unrecognized destination internalformat
8515                     DE_ASSERT(0);
8516 
8517                     break;
8518                 }
8519                 } // switch (GetDataSamplerTypeForInternalformat(dst_internalformat) )
8520 
8521                 break;
8522             } // case DATA_SAMPLER_INTEGER:
8523 
8524             case DATA_SAMPLER_UNSIGNED_INTEGER:
8525             {
8526                 switch (getDataSamplerTypeForInternalformat(dst_internalformat))
8527                 {
8528                 case DATA_SAMPLER_UNSIGNED_INTEGER:
8529                 {
8530                     if (!execute(fbo_internalformat, dst_internalformat, &m_ui_src_ui_dst_internalformat))
8531                     {
8532                         // At least one conversion was invalid or failed. Test should fail,
8533                         // but let's continue iterating over internalformats.
8534                         result = false;
8535                     }
8536 
8537                     break;
8538                 }
8539 
8540                 case DATA_SAMPLER_FLOAT:
8541                 case DATA_SAMPLER_INTEGER:
8542                 {
8543                     // There shouldn't be any valid conversion formats in this case. Just pass NULL for the non-renderable case's objects.
8544                     // The test will fail if we try to verify the copy for different data type formats
8545                     if (!execute(fbo_internalformat, dst_internalformat, NULL))
8546                     {
8547                         // At least one conversion was invalid or failed. Test should fail,
8548                         // but let's continue iterating over internalformats.
8549                         result = false;
8550                     }
8551 
8552                     break;
8553                 }
8554 
8555                 default:
8556                 {
8557                     // Unrecognized destination internalformat?
8558                     DE_ASSERT(0);
8559                     break;
8560                 }
8561                 } // switch (GetDataSamplerTypeForInternalformat(dst_internalformat) )
8562 
8563                 break;
8564             } // case DATA_SAMPLER_UNSIGNED_INTEGER
8565 
8566             default:
8567             {
8568                 // Unrecognized source internalformat
8569                 DE_ASSERT(0);
8570                 break;
8571             }
8572             } // switch (GetDataSamplerTypeForInternalformat(fbo_internalformat) )
8573         }     // for (all destination internalformats)
8574     }         // for (all FBO internalformats)
8575 
8576     if (result)
8577         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8578     return STOP;
8579 }
8580 
8581 /** This function verifies if glCopyTexImage2D() implementation performs conversions as
8582  *  per GLES3.0.3 spec, and that the result data is valid. For more detailed description,
8583  *  please see specification of copy_tex_image_conversions_required conformance test.
8584  *
8585  *  @param conversion_database         Conversion database handle. Cannot be NULL.
8586  *  @param source_attachment_type      Tells what GL object (or which texture target)
8587  *                                     should be used as a read buffer for
8588  *                                     a glCopyTexImage2D) call. Allowed values:
8589  *                                     1) GL_TEXTURE_2D,
8590  *                                     2) GL_TEXTURE_2D_ARRAY,
8591  *                                     3) GL_TEXTURE_3D,
8592  *                                     4) GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
8593  *                                     5) GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
8594  *                                     6) GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
8595  *                                     7) GL_TEXTURE_CUBE_MAP_POSITIVE_X,
8596  *                                     8) GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
8597  *                                     9) GL_TEXTURE_CUBE_MAP_POSITIVE_Z.
8598  *  @param destination_attachment_type Tells which texture target should be used for
8599  *                                     a glCopyTexImage2D() call. Allowed values:
8600  *                                     1) GL_TEXTURE_2D,
8601  *                                     2) GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
8602  *                                     3) GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
8603  *                                     4) GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
8604  *                                     5) GL_TEXTURE_CUBE_MAP_POSITIVE_X,
8605  *                                     6) GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
8606  *                                     7) GL_TEXTURE_CUBE_MAP_POSITIVE_Z.
8607  *  @param src_internalformat          GLES internalformat that read buffer should use.
8608  *  @param dst_internalformat          GLES internalformat that should be used for glReadPixels() call.
8609  *                                     This should NOT be the expected effective internalformat!
8610  *  @param objects_ptr                 Deref where generated object ids are stored
8611  *                                     (objects which were generated to support non-color-renderable internalformats).
8612  *                                     Cannot be NULL.
8613  *
8614  *  @return true if successful, false otherwise.
8615  */
execute(GLenum src_internalformat,GLenum dst_internalformat,NonRenderableInternalformatSupportObjects * objects_ptr)8616 bool RequiredCase::execute(GLenum src_internalformat, GLenum dst_internalformat,
8617                            NonRenderableInternalformatSupportObjects *objects_ptr)
8618 {
8619     GLenum fbo_completeness                    = GL_NONE;
8620     GLenum general_destination_attachment_type = GL_NONE;
8621     int n_format_type_pair                     = 0;
8622     GLenum src_format                          = GL_NONE;
8623     GLenum src_type                            = GL_NONE;
8624 
8625     glu::RenderContext &renderContext = m_context.getRenderContext();
8626     const Functions &gl               = renderContext.getFunctions();
8627 
8628     // If we're using a renderbuffer as a source, make sure the internalformat
8629     // we'll try to use to store data in it is actually renderable
8630     if (m_destination_attachment_type == GL_RENDERBUFFER && !isValidRBOInternalFormat(src_internalformat))
8631         return true;
8632 
8633     // Only accept source internal formats that are color renderable
8634     if (!isColorRenderableInternalFormat(src_internalformat))
8635         return true;
8636 
8637     // Retrieve general destination attachment type before we continue
8638     if ((general_destination_attachment_type = getGeneralTargetForDetailedTarget(m_destination_attachment_type)) ==
8639         GL_NONE)
8640     {
8641         return false;
8642     }
8643 
8644     // Good. Check if the conversion is required - if so, we can run the test!
8645     if (!isFBOEffectiveInternalFormatCompatibleWithDestinationInternalFormat(src_internalformat, dst_internalformat))
8646         return true;
8647 
8648     bool result = true;
8649     std::vector<char> fbo_data(4);
8650 
8651     // Try using all compatible format+type pairs
8652     while (getFormatAndTypeCompatibleWithInternalformat(src_internalformat, n_format_type_pair, &src_format, &src_type))
8653     {
8654         // Try to find a rule in the conversion database, so that we know what data we should fill
8655         // the source attachment with.
8656         // There may be many entries for a single source internal format + type pair, so
8657         // iterate until the find() function fails.
8658         GLenum effective_internalformat = GL_NONE;
8659         int n_conversion_rule           = 0;
8660         PixelData result_bottomleft_pixel_data;
8661         PixelData result_bottomright_pixel_data;
8662         PixelData result_topleft_pixel_data;
8663         PixelData result_topright_pixel_data;
8664         GLenum result_type = GL_NONE;
8665         PixelData src_bottomleft_pixel_data;
8666         PixelData src_bottomright_pixel_data;
8667         PixelData src_topleft_pixel_data;
8668         PixelData src_topright_pixel_data;
8669         PixelCompareChannel channels_to_compare;
8670 
8671         while (findEntryInConversionDatabase(
8672             n_conversion_rule, src_internalformat, src_type, dst_internalformat, &effective_internalformat,
8673             &result_type, &src_topleft_pixel_data, &src_topright_pixel_data, &src_bottomleft_pixel_data,
8674             &src_bottomright_pixel_data, &result_topleft_pixel_data, &result_topright_pixel_data,
8675             &result_bottomleft_pixel_data, &result_bottomright_pixel_data, &channels_to_compare))
8676         {
8677 #if 0
8678             m_testCtx.getLog() << tcu::TestLog::Message
8679                                << "Testing [src "
8680                                << getInternalformatString(src_internalformat)
8681                                << " " << glu::getTypeStr(src_type).toString()
8682                                << "]=>[" << getInternalformatString(dst_internalformat) << "effective: "
8683                                << getInternalformatString(effective_internalformat) << "] read with type: ["
8684                                << glu::getTypeStr(result_type).toString() << ", src target: [" << GetTargetName(m_source_attachment_type)
8685                                << "], dst target: " << GetTargetName(m_destination_attachment_type)
8686                                << tcu::TestLog::EndMessage;
8687 #endif
8688 
8689             // Retrieve source data we can have uploaded to the source attachment
8690             if (!getRawDataFromPixelData(fbo_data, src_topleft_pixel_data, src_topright_pixel_data,
8691                                          src_bottomleft_pixel_data, src_bottomright_pixel_data))
8692             {
8693                 unbindColorAttachments();
8694                 return false;
8695             }
8696 
8697             // Set up source attachment
8698             if (!configureGLObject(1, m_source_attachment_type, m_src_object_id, src_internalformat, src_format,
8699                                    src_type, &fbo_data[0]))
8700             {
8701                 unbindColorAttachments();
8702                 return false;
8703             }
8704 
8705             // Make sure the source FBO configuration is supported.
8706             fbo_completeness = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
8707 
8708             if (fbo_completeness != GL_FRAMEBUFFER_COMPLETE)
8709             {
8710                 if (fbo_completeness == GL_FRAMEBUFFER_UNSUPPORTED)
8711                 {
8712                     // The implementation does not allow us to use source data built using this internal-format,
8713                     // using this particular attachment type. Break out of the loop, there's no need to carry on
8714                     // trying.
8715                     break;
8716                 }
8717                 else
8718                 {
8719                     m_testCtx.getLog() << tcu::TestLog::Message << "FBO error - incompleteness reason ["
8720                                        << fbo_completeness << "]" << tcu::TestLog::EndMessage;
8721 
8722                     // This should never happen. Consider test failed
8723                     unbindColorAttachments();
8724                     return false;
8725                 }
8726             }
8727 
8728             // Ask the implementation to perform the conversion!
8729             switch (m_destination_attachment_type)
8730             {
8731             case GL_TEXTURE_2D:
8732             {
8733                 gl.bindTexture(m_destination_attachment_type, m_dst_object_id);
8734 
8735                 gl.copyTexImage2D(m_destination_attachment_type, 0, dst_internalformat, 0 /* x */, 0 /* y */,
8736                                   TEXTURE_WIDTH, TEXTURE_HEIGHT, 0 /* border */);
8737 
8738                 gl.texParameterf(m_destination_attachment_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8739                 gl.texParameterf(m_destination_attachment_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8740                 gl.texParameterf(m_destination_attachment_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
8741                 gl.texParameterf(m_destination_attachment_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
8742 
8743                 gl.bindTexture(m_destination_attachment_type, 0);
8744 
8745                 break;
8746             }
8747 
8748             case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
8749             case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
8750             case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
8751             case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
8752             case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
8753             case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
8754             {
8755                 unsigned int j = 0;
8756                 GLuint dst_format, dst_type;
8757 
8758                 getFormatAndTypeCompatibleWithInternalformat(dst_internalformat, 0, &dst_format, &dst_type);
8759 
8760                 gl.bindTexture(general_destination_attachment_type, m_dst_object_id);
8761 
8762                 // Initialize all faces so that the texture is CM complete
8763                 // It's needed in case we need to use a shader to verify the copy operation
8764                 for (j = GL_TEXTURE_CUBE_MAP_POSITIVE_X; j <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; j++)
8765                 {
8766                     if (j == m_destination_attachment_type)
8767                     {
8768                         // Do the copy to the destination face
8769                         gl.copyTexImage2D(j, 0, dst_internalformat, 0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT,
8770                                           0 /* border */);
8771                     }
8772                     else
8773                     {
8774                         // Clear the remaining faces to catch "copy to the wrong face" errors
8775                         static std::vector<char> zero_data(TEXTURE_WIDTH * TEXTURE_HEIGHT * 4 * sizeof(float), 0);
8776                         gl.texImage2D(j, 0, dst_internalformat, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, dst_format, dst_type,
8777                                       &zero_data[0]);
8778                     }
8779                 }
8780 
8781                 gl.texParameterf(general_destination_attachment_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8782                 gl.texParameterf(general_destination_attachment_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8783                 gl.texParameterf(general_destination_attachment_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
8784                 gl.texParameterf(general_destination_attachment_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
8785 
8786                 gl.bindTexture(general_destination_attachment_type, 0);
8787 
8788                 break;
8789             } // cube-map texture target cases
8790 
8791             default:
8792             {
8793                 // Unsupported destination attachment type
8794                 DE_ASSERT(0);
8795             }
8796             } // switch (destination_attachment_type)
8797 
8798             // Has the conversion succeeded as expected?
8799             GLenum error_code = gl.getError();
8800 
8801             if (error_code != GL_NO_ERROR)
8802             {
8803                 m_testCtx.getLog() << tcu::TestLog::Message << "glCopyTexImage2D() reported an error for ["
8804                                    << getInternalformatString(src_internalformat) << "]=>["
8805                                    << getInternalformatString(dst_internalformat)
8806                                    << "] internalformat conversion [target=" << getTargetName(m_source_attachment_type)
8807                                    << "], as opposed to ES specification requirements!" << tcu::TestLog::EndMessage;
8808 
8809                 // This test is now considered failed
8810                 result = false;
8811             }
8812             else
8813             {
8814                 // Conversion succeeded. We now need to compare the data stored by OpenGL ES with reference data.
8815                 if (isColorRenderableInternalFormat(effective_internalformat))
8816                 {
8817                     gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_destination_attachment_type,
8818                                             m_dst_object_id, 0);
8819 
8820                     fbo_completeness = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
8821                     if (fbo_completeness != GL_FRAMEBUFFER_COMPLETE)
8822                     {
8823                         // Per spec:
8824                         // Although the GL defines a wide variety of internal formats for framebuffer-
8825                         // attachable image, such as texture images and renderbuffer images, some imple-
8826                         // mentations may not support rendering to particular combinations of internal for-
8827                         // mats. If the combination of formats of the images attached to a framebuffer object
8828                         // are not supported by the implementation, then the framebuffer is not complete un-
8829                         // der the clause labeled FRAMEBUFFER_UNSUPPORTED.
8830                         if (fbo_completeness != GL_FRAMEBUFFER_UNSUPPORTED)
8831                         {
8832                             m_testCtx.getLog() << tcu::TestLog::Message
8833                                                << "Framebuffer is considered incomplete [reason: " << fbo_completeness
8834                                                << "] - cannot proceed with the test case" << tcu::TestLog::EndMessage;
8835                             result = false;
8836                         }
8837                     }
8838                     else
8839                     {
8840                         if (!compareExpectedResultsByReadingPixels(
8841                                 src_topleft_pixel_data, src_topright_pixel_data, src_bottomleft_pixel_data,
8842                                 src_bottomright_pixel_data, result_topleft_pixel_data, result_topright_pixel_data,
8843                                 result_bottomleft_pixel_data, result_bottomright_pixel_data, result_type,
8844                                 effective_internalformat))
8845                         {
8846                             // This test is now considered failed
8847                             result = false;
8848                         }
8849                     }
8850                     gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_destination_attachment_type, 0,
8851                                             0);
8852                 } // if (IsColorRenderableInternalFormat(effective_internalformat) )
8853                 else if (m_source_attachment_type != GL_RENDERBUFFER)
8854                 {
8855                     // We cannot use glReadPixels()-approach to test this internalformat.
8856                     // The approach to be taken for non-color-renderable internalformats will
8857                     // be to use a special vertex shader to verify texture data. Outcome of the
8858                     // comparison will be captured using transform feedback.
8859                     GLint bound_draw_fbo_id  = 0;
8860                     GLint bound_read_fbo_id  = 0;
8861                     int compare_result_index = 0;
8862                     std::vector<GLint> copied_compare_result_data;
8863                     std::vector<GLint> copied_dst_texture_data;
8864                     std::vector<GLint> copied_src_texture_data;
8865                     GLenum dst_attachment_point = GL_TEXTURE2;
8866                     GLenum src_attachment_point = GL_TEXTURE1;
8867                     GLint samplers_to_use       = 0;
8868                     // unique sampler values
8869                     GLint src_2D_texture_attachment      = GL_TEXTURE3;
8870                     GLint src_2DArray_texture_attachment = GL_TEXTURE4;
8871                     GLint src_3D_texture_attachment      = GL_TEXTURE5;
8872                     GLint src_Cube_texture_attachment    = GL_TEXTURE6;
8873                     GLint dst_2D_texture_attachment      = GL_TEXTURE7;
8874                     GLint dst_Cube_texture_attachment    = GL_TEXTURE8;
8875 
8876                     if (m_source_attachment_type == GL_TEXTURE_2D_ARRAY)
8877                     {
8878                         samplers_to_use                = TEXTURE_2D_ARRAY_SAMPLER_TYPE;
8879                         src_2DArray_texture_attachment = src_attachment_point;
8880                     }
8881                     else if (m_source_attachment_type == GL_TEXTURE_3D)
8882                     {
8883                         samplers_to_use           = TEXTURE_3D_SAMPLER_TYPE;
8884                         src_3D_texture_attachment = src_attachment_point;
8885                     }
8886                     else if (m_source_attachment_type != GL_TEXTURE_2D)
8887                     {
8888                         samplers_to_use             = TEXTURE_CUBE_SAMPLER_TYPE;
8889                         src_Cube_texture_attachment = src_attachment_point;
8890                     }
8891                     else
8892                         src_2D_texture_attachment = src_attachment_point;
8893 
8894                     if (m_destination_attachment_type != GL_TEXTURE_2D)
8895                     {
8896                         samplers_to_use             = (samplers_to_use | (TEXTURE_CUBE_SAMPLER_TYPE << 8));
8897                         dst_Cube_texture_attachment = dst_attachment_point;
8898                     }
8899                     else
8900                         dst_2D_texture_attachment = dst_attachment_point;
8901 
8902                     // We will get a NULL pointer here if src and dst data type are different
8903                     // (NORM -> INT, UNSIGNED INT -> INT etc.). It's not allowed by the spec.
8904                     if (objects_ptr == NULL)
8905                     {
8906                         m_testCtx.getLog() << tcu::TestLog::Message
8907                                            << "Source and destination should be of the same data type - "
8908                                               "cannot proceed with the test case"
8909                                            << tcu::TestLog::EndMessage;
8910                         result = false;
8911                         restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id,
8912                                         bound_read_fbo_id);
8913                         continue;
8914                     }
8915 
8916                     // Retrieve currently bound framebuffer (draw and read) object IDs.
8917                     // If there is any FBO bound, glDraw*() function uses it, which is not wanted in this situation.
8918                     // What we do here is: unbinding FBOs, issue draw calls, bind FBOs again.
8919                     gl.getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &bound_draw_fbo_id);
8920                     gl.getIntegerv(GL_READ_FRAMEBUFFER_BINDING, &bound_read_fbo_id);
8921 
8922                     // Use default framebuffer object for this case purposes.
8923                     gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
8924 
8925                     // Bind source texture object to specific texture unit.
8926                     if (!bindTextureToTargetToSpecificTextureUnit(m_src_object_id, m_source_attachment_type,
8927                                                                   src_attachment_point))
8928                     {
8929                         result = false;
8930                         restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id,
8931                                         bound_read_fbo_id);
8932                         continue;
8933                     }
8934 
8935                     // Bind destination texture object to specific texture unit.
8936                     if (!bindTextureToTargetToSpecificTextureUnit(m_dst_object_id, m_destination_attachment_type,
8937                                                                   dst_attachment_point))
8938                     {
8939                         result = false;
8940                         restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id,
8941                                         bound_read_fbo_id);
8942                         continue;
8943                     }
8944 
8945                     // Set active program object.
8946                     gl.useProgram(objects_ptr->program_object_id);
8947 
8948                     if (!setUniformValues(objects_ptr->src_2D_texture_uniform_location, src_2D_texture_attachment,
8949                                           objects_ptr->src_2DArray_texture_uniform_location,
8950                                           src_2DArray_texture_attachment, objects_ptr->src_3D_texture_uniform_location,
8951                                           src_3D_texture_attachment, objects_ptr->src_Cube_texture_uniform_location,
8952                                           src_Cube_texture_attachment, objects_ptr->dst_2D_texture_uniform_location,
8953                                           dst_2D_texture_attachment, objects_ptr->dst_Cube_texture_uniform_location,
8954                                           dst_Cube_texture_attachment,
8955                                           objects_ptr->channels_to_compare_uniform_location, channels_to_compare,
8956                                           objects_ptr->samplers_to_use_uniform_location, samplers_to_use))
8957                     {
8958                         result = false;
8959                         restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id,
8960                                         bound_read_fbo_id);
8961                         continue;
8962                     }
8963 
8964                     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, COMPARISON_RESULT_BUFFER_OBJECT_INDEX,
8965                                       objects_ptr->comparison_result_buffer_object_id);
8966                     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, SOURCE_TEXTURE_PIXELS_BUFFER_OBJECT_INDEX,
8967                                       objects_ptr->src_texture_pixels_buffer_object_id);
8968                     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, DESTINATION_TEXTURE_PIXELS_BUFFER_OBJECT_INDEX,
8969                                       objects_ptr->dst_texture_pixels_buffer_object_id);
8970 
8971                     // Enable texture corrdinates (vertex attribs 0 & 1)
8972                     gl.enableVertexAttribArray(SRC_TEXTURE_COORDS_ATTRIB_INDEX);
8973                     gl.enableVertexAttribArray(DST_TEXTURE_COORDS_ATTRIB_INDEX);
8974 
8975                     // Begin transform feedback operations.
8976                     gl.enable(GL_RASTERIZER_DISCARD);
8977 
8978                     // Issue transform feedback operations.
8979                     gl.beginTransformFeedback(GL_POINTS);
8980                     error_code = gl.getError();
8981                     if (GL_NO_ERROR != error_code)
8982                     {
8983                         m_testCtx.getLog()
8984                             << tcu::TestLog::Message << "An error [" << error_code
8985                             << "] occurred after glBeginTransformFeedback() call." << tcu::TestLog::EndMessage;
8986                         result = false;
8987                         restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id,
8988                                         bound_read_fbo_id);
8989                         continue;
8990                     }
8991 
8992                     gl.drawArrays(GL_POINTS, 0, NUMBER_OF_POINTS_TO_DRAW);
8993 
8994                     error_code = gl.getError();
8995                     if (GL_NO_ERROR != error_code)
8996                     {
8997                         m_testCtx.getLog() << tcu::TestLog::Message << "An error [" << error_code
8998                                            << "] occurred after glDrawArrays() call." << tcu::TestLog::EndMessage;
8999                         result = false;
9000                         restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id,
9001                                         bound_read_fbo_id);
9002                         continue;
9003                     }
9004 
9005                     gl.endTransformFeedback();
9006 
9007                     error_code = gl.getError();
9008                     if (GL_NO_ERROR != error_code)
9009                     {
9010                         m_testCtx.getLog()
9011                             << tcu::TestLog::Message << "An error [" << error_code
9012                             << "] occurred after glEndTransformFeedback() call." << tcu::TestLog::EndMessage;
9013                         result = false;
9014                         restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id,
9015                                         bound_read_fbo_id);
9016                         continue;
9017                     }
9018 
9019                     // Restore default active program object.
9020                     gl.useProgram(0);
9021 
9022                     // Make sure no error was generated at this point.
9023                     error_code = gl.getError();
9024                     if (GL_NO_ERROR != error_code)
9025                     {
9026                         m_testCtx.getLog()
9027                             << tcu::TestLog::Message << "An error [" << error_code
9028                             << "] occurred while working with transform feedback object." << tcu::TestLog::EndMessage;
9029                         result = false;
9030                         restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id,
9031                                         bound_read_fbo_id);
9032                         continue;
9033                     }
9034 
9035                     gl.disable(GL_RASTERIZER_DISCARD);
9036 
9037                     // Let's read the buffer data now.
9038                     copyDataFromBufferObject(objects_ptr->comparison_result_buffer_object_id,
9039                                              copied_compare_result_data);
9040                     copyDataFromBufferObject(objects_ptr->src_texture_pixels_buffer_object_id, copied_src_texture_data);
9041                     copyDataFromBufferObject(objects_ptr->dst_texture_pixels_buffer_object_id, copied_dst_texture_data);
9042 
9043                     // Check the results.
9044                     for (compare_result_index = 0; compare_result_index < NUMBER_OF_POINTS_TO_DRAW;
9045                          compare_result_index++)
9046                     {
9047                         if (copied_compare_result_data[compare_result_index] != 1)
9048                         {
9049                             int index_in_vec4_array = compare_result_index * NUMBER_OF_ELEMENTS_IN_VEC4;
9050 
9051                             // Returned result indicates that textures are different.
9052                             // Print texture object contents as well.
9053                             displayPixelComparisonFailureMessage(copied_src_texture_data[index_in_vec4_array],
9054                                                                  copied_src_texture_data[index_in_vec4_array + 1],
9055                                                                  copied_src_texture_data[index_in_vec4_array + 2],
9056                                                                  copied_src_texture_data[index_in_vec4_array + 3],
9057                                                                  src_internalformat, src_type, 0, 0, 0, 0, GL_NONE,
9058                                                                  GL_NONE, copied_dst_texture_data[index_in_vec4_array],
9059                                                                  copied_dst_texture_data[index_in_vec4_array + 1],
9060                                                                  copied_dst_texture_data[index_in_vec4_array + 2],
9061                                                                  copied_dst_texture_data[index_in_vec4_array + 3],
9062                                                                  dst_internalformat, result_type, 0, 0, 0, 0);
9063 
9064                             // Report failure.
9065                             result = false;
9066                         }
9067                     }
9068 
9069                     fbo_completeness = GL_FRAMEBUFFER_COMPLETE;
9070 
9071                     restoreBindings(src_attachment_point, dst_attachment_point, bound_draw_fbo_id, bound_read_fbo_id);
9072                 } // if (source_attachment_type != GL_RENDERBUFFER && destination_attachment_type != GL_RENDERBUFFER)
9073             }     // if (no error was reported by GLES)
9074 
9075             n_conversion_rule++;
9076         }
9077 
9078         // There should be at least ONE conversion rule defined
9079         // for each valid FBO effective internalformat =>copyteximage2d internalformat defined!
9080         // NOTE: This assertion can fail IF GLES implementation does not support particular FBO attachment combination.
9081         //       Make sure the check is not performed, should GL_FRAMEBUFFER_UNSUPPORTED fbo status be reported.
9082         if (fbo_completeness != GL_FRAMEBUFFER_UNSUPPORTED)
9083         {
9084             if (n_conversion_rule == 0)
9085             {
9086                 m_testCtx.getLog() << tcu::TestLog::Message << "No conversion rule for [src "
9087                                    << getInternalformatString(src_internalformat) << " "
9088                                    << glu::getTypeStr(src_type).toString() << "]=>["
9089                                    << getInternalformatString(dst_internalformat)
9090                                    << "effective: " << getInternalformatString(effective_internalformat)
9091                                    << "] read with type: [" << glu::getTypeStr(result_type).toString()
9092                                    << ", src target: [" << getTargetName(m_source_attachment_type)
9093                                    << "], dst target: " << getTargetName(m_destination_attachment_type)
9094                                    << tcu::TestLog::EndMessage;
9095             }
9096         }
9097 
9098         // Check next format+type combination
9099         n_format_type_pair++;
9100 
9101         // If we're copying from a renderbuffer, we don't really care about compatible format+type pairs, as
9102         // the effective internalformat is explicitly configured by glRenderbufferStorage() call.
9103         if (m_source_attachment_type == GL_RENDERBUFFER)
9104         {
9105             break;
9106         } // if (general_attachment_type == GL_RENDERBUFFER)
9107     }     // while (internalformat has n-th legal format+type pair)
9108 
9109     unbindColorAttachments();
9110     return result;
9111 }
9112 
9113 /** Binds texture object to a given texture target of a specified texture unit.
9114  *
9115  * @param to_id          Valid texture object ID to be bound.
9116  * @param texture_target Valid texture target to which @param to_id will be bound.
9117  * @param texture_unit   Texture unit to which @param to_id will be bound.
9118  *
9119  * @return GTFtrue if successful, GTFfalse otherwise.
9120  */
bindTextureToTargetToSpecificTextureUnit(GLuint to_id,GLenum texture_target,GLenum texture_unit)9121 bool RequiredCase::bindTextureToTargetToSpecificTextureUnit(GLuint to_id, GLenum texture_target, GLenum texture_unit)
9122 {
9123     glu::RenderContext &renderContext = m_context.getRenderContext();
9124     const Functions &gl               = renderContext.getFunctions();
9125 
9126     // Set active texture unit.
9127     gl.activeTexture(texture_unit);
9128     GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
9129 
9130     if (texture_target == GL_TEXTURE_CUBE_MAP_POSITIVE_X || texture_target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
9131         texture_target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y || texture_target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
9132         texture_target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z || texture_target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
9133     {
9134         texture_target = GL_TEXTURE_CUBE_MAP;
9135     }
9136 
9137     // Bind texture object to specific texture target of specified texture unit.
9138     gl.bindTexture(texture_target, to_id);
9139     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
9140 
9141     // Restore default active texture unit.
9142     gl.activeTexture(GL_TEXTURE0);
9143     GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
9144 
9145     return true;
9146 }
9147 
9148 /** Sets values of uniforms, that will later be used to perform data check-up for non-renderable internalformats.
9149  *
9150  * @param source_2D_texture_uniform_location        Location for source 2D texture sample uniform.
9151  * @param source_2D_texture_unit                    Texture unit which the source 2D texture object is bound to.
9152  *                                                  Will be used to set value for @param source_2D_texture_uniform_location.
9153  * @param source_2DArray_texture_uniform_location   Location for source 2DArray texture sample uniform.
9154  * @param source_2DArray_texture_unit               Texture unit which the source 2DArray texture object is bound to.
9155  *                                                  Will be used to set value for @param source_2DArray_texture_uniform_location.
9156  * @param source_3D_texture_uniform_location        Location for source 3D texture sample uniform.
9157  * @param source_3D_texture_unit                    Texture unit which the source 3D texture object is bound to.
9158  *                                                  Will be used to set value for @param source_Cube_texture_uniform_location.
9159  * @param source_Cube_texture_uniform_location      Location for source Cube texture sample uniform.
9160  * @param source_Cube_texture_unit                  Texture unit which the source 2D texture object is bound to.
9161  *                                                  Will be used to set value for @param source_2D_texture_uniform_location.
9162  * @param destination_2D_texture_uniform_location   Location for destination texture sample uniform.
9163  * @param destination_2D_texture_unit               Texture unit which the destination texture object is bound to.
9164  *                                                  Will be used to set value for @param destination_2D_texture_uniform_location.
9165  * @param destination_Cube_texture_uniform_location Location for destination texture sample uniform.
9166  * @param destination_Cube_texture_unit             Texture unit which the destination texture object is bound to.
9167  *                                                  Will be used to set value for @param destination_Cube_texture_uniform_location.
9168  * @param channels_to_compare_uniform_location      Location for components to compare value uniform.
9169  * @param channels_to_compare                       Components to compare value.
9170  * @param samplers_to_use_uniform_location          Location for samplers to use value uniform.
9171  * @param samplers_to_use                           samplers to use value.
9172  *
9173  * @return GTFtrue if the operation succeeded (no error was generated),
9174  *         GTFfalse otherwise.
9175  */
setUniformValues(GLint source_2D_texture_uniform_location,GLenum source_2D_texture_unit,GLint source_2DArray_texture_uniform_location,GLenum source_2DArray_texture_unit,GLint source_3D_texture_uniform_location,GLenum source_3D_texture_unit,GLint source_Cube_texture_uniform_location,GLenum source_Cube_texture_unit,GLint destination_2D_texture_uniform_location,GLenum destination_2D_texture_unit,GLint destination_Cube_texture_uniform_location,GLenum destination_Cube_texture_unit,GLint channels_to_compare_uniform_location,GLint channels_to_compare,GLint samplers_to_use_uniform_location,GLint samplers_to_use)9176 bool RequiredCase::setUniformValues(GLint source_2D_texture_uniform_location, GLenum source_2D_texture_unit,
9177                                     GLint source_2DArray_texture_uniform_location, GLenum source_2DArray_texture_unit,
9178                                     GLint source_3D_texture_uniform_location, GLenum source_3D_texture_unit,
9179                                     GLint source_Cube_texture_uniform_location, GLenum source_Cube_texture_unit,
9180                                     GLint destination_2D_texture_uniform_location, GLenum destination_2D_texture_unit,
9181                                     GLint destination_Cube_texture_uniform_location,
9182                                     GLenum destination_Cube_texture_unit, GLint channels_to_compare_uniform_location,
9183                                     GLint channels_to_compare, GLint samplers_to_use_uniform_location,
9184                                     GLint samplers_to_use)
9185 {
9186     glu::RenderContext &renderContext = m_context.getRenderContext();
9187     const Functions &gl               = renderContext.getFunctions();
9188 
9189     if (source_2D_texture_uniform_location == -1 || source_2DArray_texture_uniform_location == -1 ||
9190         source_3D_texture_uniform_location == -1 || source_Cube_texture_uniform_location == -1 ||
9191         destination_2D_texture_uniform_location == -1 || destination_Cube_texture_uniform_location == -1 ||
9192         channels_to_compare_uniform_location == -1 || samplers_to_use_uniform_location == -1)
9193     {
9194         m_testCtx.getLog() << tcu::TestLog::Message << "Cannot set uniform values for invalid uniform locations."
9195                            << tcu::TestLog::EndMessage;
9196 
9197         return false;
9198     } // if (input uniform locations are invalid)
9199 
9200     // We are now ready to set uniform values.
9201     gl.uniform1i(destination_2D_texture_uniform_location, destination_2D_texture_unit - GL_TEXTURE0);
9202     gl.uniform1i(destination_Cube_texture_uniform_location, destination_Cube_texture_unit - GL_TEXTURE0);
9203     gl.uniform1i(source_2D_texture_uniform_location, source_2D_texture_unit - GL_TEXTURE0);
9204     gl.uniform1i(source_2DArray_texture_uniform_location, source_2DArray_texture_unit - GL_TEXTURE0);
9205     gl.uniform1i(source_3D_texture_uniform_location, source_3D_texture_unit - GL_TEXTURE0);
9206     gl.uniform1i(source_Cube_texture_uniform_location, source_Cube_texture_unit - GL_TEXTURE0);
9207     gl.uniform1i(channels_to_compare_uniform_location, channels_to_compare);
9208     gl.uniform1i(samplers_to_use_uniform_location, samplers_to_use);
9209     GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
9210 
9211     return true;
9212 }
9213 
9214 /** Retrieves and copies data stored in buffer object into allocated memory buffer.
9215  *  It is user's responsibility to free allocated memory.
9216  *
9217  * @param bo_id                  Valid buffer object ID from which data is retrieved.
9218  * @param retrieved_data_ptr_ptr Deref will be used to store retrieved buffer object data.
9219  *
9220  * @return GTFtrue if successful, GTFfalse otherwise.
9221  */
copyDataFromBufferObject(GLuint bo_id,std::vector<GLint> & retrieved_data)9222 bool RequiredCase::copyDataFromBufferObject(GLuint bo_id, std::vector<GLint> &retrieved_data)
9223 {
9224     glu::RenderContext &renderContext = m_context.getRenderContext();
9225     const Functions &gl               = renderContext.getFunctions();
9226 
9227     GLint buffer_size = 0;
9228     gl.bindBuffer(GL_ARRAY_BUFFER, bo_id);
9229     gl.getBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &buffer_size);
9230     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv");
9231 
9232     GLint *buffer_data_ptr = NULL;
9233     buffer_data_ptr        = (GLint *)gl.mapBufferRange(GL_ARRAY_BUFFER, 0, buffer_size, GL_MAP_READ_BIT);
9234     GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange");
9235 
9236     if (buffer_data_ptr == NULL)
9237     {
9238         m_testCtx.getLog() << tcu::TestLog::Message << "Could not map buffer object." << tcu::TestLog::EndMessage;
9239         return false;
9240     }
9241 
9242     // Copy retrieved buffer data.
9243     retrieved_data.resize(buffer_size / sizeof(GLint));
9244     std::memcpy(&retrieved_data[0], buffer_data_ptr, buffer_size);
9245 
9246     gl.unmapBuffer(GL_ARRAY_BUFFER);
9247     GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
9248 
9249     return true;
9250 }
9251 
9252 /** Allocates a buffer of sufficient size to hold 2x2 texture data represented
9253  *  with @param read_type GL type, issues a glReadPixels() call and then compares
9254  *  retrieved data with reference data (provided by the caller using reference_*
9255  *  arguments).
9256  *  Should it happen that the call resulted in an indirect conversion, the function
9257  *  calculates an epsilon, taking differences in amount of bits that were used to
9258  *  represent the data during any stage of the conversion into consideration.
9259  *
9260  *  @param source_tl_pixel_data    Describes pixel data that was used to build source
9261  *                                 object's contents (top-left corner).
9262  *  @param source_tr_pixel_data    Describes pixel data that was used to build source
9263  *                                 object's contents (top-right corner).
9264  *  @param source_bl_pixel_data    Describes pixel data that was used to build source
9265  *                                 object's contents (bottom-left corner).
9266  *  @param source_br_pixel_data    Describes pixel data that was used to build source
9267  *                                 object's contents (bottom-right corner).
9268  *  @param reference_tl_pixel_data Describes ideal result pixel data. (top-left corner).
9269  *  @param reference_tr_pixel_data Describes ideal result pixel data. (top-right corner).
9270  *  @param reference_bl_pixel_data Describes ideal result pixel data. (bottom-left corner).
9271  *  @param reference_br_pixel_data Describes ideal result pixel data. (bottom-right corner).
9272  *  @param read_type               GL type that will be used for glReadPixels() call. This
9273  *                                 type should be directly related with data type used in
9274  *                                 all reference_* pixel data arguments.
9275  *  @param result_internalformat   Effective internal-format, expected to be used by the
9276  *                                 implementation to hold destination object's data.
9277  *  @param src_format              GL format used for source object's data storage.
9278  *  @param src_type                GL type used for source object's data storage.
9279  *  @param src_attachment_type     Object type or texture target of the source object.
9280  *  @param dst_attachment_type     Object type or texture target of the destination object.
9281  *
9282  *  @return GTFtrue if all read pixels were correct, GTFfalse otherwise
9283  **/
compareExpectedResultsByReadingPixels(PixelData source_tl_pixel_data,PixelData source_tr_pixel_data,PixelData source_bl_pixel_data,PixelData source_br_pixel_data,PixelData reference_tl_pixel_data,PixelData reference_tr_pixel_data,PixelData reference_bl_pixel_data,PixelData reference_br_pixel_data,GLenum read_type,GLenum result_internalformat)9284 bool RequiredCase::compareExpectedResultsByReadingPixels(PixelData source_tl_pixel_data, PixelData source_tr_pixel_data,
9285                                                          PixelData source_bl_pixel_data, PixelData source_br_pixel_data,
9286                                                          PixelData reference_tl_pixel_data,
9287                                                          PixelData reference_tr_pixel_data,
9288                                                          PixelData reference_bl_pixel_data,
9289                                                          PixelData reference_br_pixel_data, GLenum read_type,
9290                                                          GLenum result_internalformat)
9291 {
9292     char *data_traveller_ptr              = NULL;
9293     int n                                 = 0;
9294     unsigned int n_bytes_per_result_pixel = 0;
9295     GLenum read_format                    = GL_NONE;
9296     bool result                           = true;
9297 
9298     PixelData *reference_pixels[] = {
9299         &reference_bl_pixel_data,
9300         &reference_br_pixel_data,
9301         &reference_tl_pixel_data,
9302         &reference_tr_pixel_data,
9303     };
9304     PixelData *source_pixels[] = {&source_bl_pixel_data, &source_br_pixel_data, &source_tl_pixel_data,
9305                                   &source_tr_pixel_data};
9306     PixelData result_pixels[4];
9307 
9308     // Determine which read format should be used for reading.
9309     // Note that GLES3 accepts GL_RGBA_INTEGER format for GL_RGB10_A2UI internalformat
9310     // and GL_RGBA for GL_RGB10_A2 - handle this in a special case.
9311     if (((read_type == GL_UNSIGNED_INT_2_10_10_10_REV) && (result_internalformat == GL_RGB10_A2UI)) ||
9312         (read_type == GL_UNSIGNED_INT) || (read_type == GL_INT))
9313     {
9314         read_format = GL_RGBA_INTEGER;
9315     }
9316     else
9317     {
9318         read_format = GL_RGBA;
9319     }
9320 
9321     // Update read_type for GL_HALF_FLOAT
9322     if (read_type == GL_HALF_FLOAT)
9323     {
9324         read_type = GL_FLOAT;
9325     }
9326 
9327     // Allocate data buffer
9328     n_bytes_per_result_pixel = getSizeOfPixel(read_format, read_type);
9329     std::vector<char> data(TEXTURE_WIDTH * TEXTURE_HEIGHT * n_bytes_per_result_pixel);
9330 
9331     glu::RenderContext &renderContext = m_context.getRenderContext();
9332     const Functions &gl               = renderContext.getFunctions();
9333 
9334     // Retrieve the data.
9335     gl.readPixels(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT, read_format, read_type, &data[0]);
9336 
9337     // Was the operation successful?
9338     GLenum error_code = gl.getError();
9339     if (error_code != GL_NO_ERROR)
9340     {
9341         m_testCtx.getLog() << tcu::TestLog::Message << "glReadPixels() failed with error: [" << error_code << "]"
9342                            << tcu::TestLog::EndMessage;
9343         return false;
9344     }
9345 
9346     // Convert the data we read back to pixel data structures
9347     data_traveller_ptr = &data[0];
9348 
9349     for (n = 0; n < DE_LENGTH_OF_ARRAY(reference_pixels); ++n)
9350     {
9351         PixelData *result_pixel_ptr = result_pixels + n;
9352 
9353         if (!getPixelDataFromRawData(data_traveller_ptr, read_format, read_type, result_pixel_ptr))
9354         {
9355             m_testCtx.getLog() << tcu::TestLog::Message << "GetPixelDataFromRawData failed!"
9356                                << tcu::TestLog::EndMessage;
9357 
9358             // Could not convert raw data to pixel data instance!
9359             DE_ASSERT(0);
9360             return false;
9361         } // if (raw data->pixel data conversion failed)
9362 
9363         // Move the data traveller
9364         data_traveller_ptr += n_bytes_per_result_pixel;
9365     } // for (all pixels)
9366 
9367     // Compare each pixel with reference data. For debugging purposes, compare every single pixel,
9368     // even if at least one comparison has already failed.
9369     DE_ASSERT(DE_LENGTH_OF_ARRAY(reference_pixels) == DE_LENGTH_OF_ARRAY(result_pixels));
9370 
9371     for (n = 0; n < DE_LENGTH_OF_ARRAY(reference_pixels); ++n)
9372     {
9373         result &= comparePixelData(result_pixels[n], *(reference_pixels[n]), *(source_pixels[n]), result_internalformat,
9374                                    (result == 0));
9375     } // For each pixel
9376 
9377     if (result == false)
9378     {
9379         // Log a separator line for clarity
9380         m_testCtx.getLog() << tcu::TestLog::Message << "<-- Erroneous test case finishes." << tcu::TestLog::EndMessage;
9381     }
9382 
9383     return result;
9384 }
9385 
9386 /** Retrieves size (expressed in bytes) of a single pixel represented by
9387  *  a @param format format + @param type type pair.
9388  *
9389  *  @param format GLES format to consider.
9390  *  @param type   GLES type to consider.
9391  *
9392  *  @return Size of the pixel or 0 if either of the arguments was not recognized.
9393  **/
getSizeOfPixel(GLenum format,GLenum type)9394 unsigned int RequiredCase::getSizeOfPixel(GLenum format, GLenum type)
9395 {
9396     int result = 0;
9397 
9398     switch (format)
9399     {
9400     case GL_RED:
9401         result = 1;
9402         break;
9403     case GL_RED_INTEGER:
9404         result = 1;
9405         break;
9406     case GL_RG:
9407         result = 2;
9408         break;
9409     case GL_RG_INTEGER:
9410         result = 2;
9411         break;
9412     case GL_RGB:
9413         result = 3;
9414         break;
9415     case GL_RGB_INTEGER:
9416         result = 3;
9417         break;
9418     case GL_RGBA:
9419         result = 4;
9420         break;
9421     case GL_RGBA_INTEGER:
9422         result = 4;
9423         break;
9424     case GL_DEPTH_COMPONENT:
9425         result = 1;
9426         break;
9427     case GL_DEPTH_STENCIL:
9428         result = 2;
9429         break;
9430     case GL_LUMINANCE_ALPHA:
9431         result = 2;
9432         break;
9433     case GL_LUMINANCE:
9434         result = 1;
9435         break;
9436     case GL_ALPHA:
9437         result = 1;
9438         break;
9439 
9440     default:
9441     {
9442         DE_ASSERT(0);
9443         result = 0;
9444     }
9445     }
9446 
9447     switch (type)
9448     {
9449     case GL_UNSIGNED_BYTE:
9450         result *= 1;
9451         break;
9452     case GL_BYTE:
9453         result *= 1;
9454         break;
9455     case GL_UNSIGNED_SHORT:
9456         result *= 2;
9457         break;
9458     case GL_SHORT:
9459         result *= 2;
9460         break;
9461     case GL_UNSIGNED_INT:
9462         result *= 4;
9463         break;
9464     case GL_INT:
9465         result *= 4;
9466         break;
9467     case GL_HALF_FLOAT:
9468         result *= 2;
9469         break;
9470     case GL_FLOAT:
9471         result *= 4;
9472         break;
9473     case GL_UNSIGNED_SHORT_5_6_5:
9474         result = 2;
9475         break;
9476     case GL_UNSIGNED_SHORT_4_4_4_4:
9477         result = 2;
9478         break;
9479     case GL_UNSIGNED_SHORT_5_5_5_1:
9480         result = 2;
9481         break;
9482     case GL_UNSIGNED_INT_2_10_10_10_REV:
9483         result = 4;
9484         break;
9485     case GL_UNSIGNED_INT_10F_11F_11F_REV:
9486         result = 4;
9487         break;
9488     case GL_UNSIGNED_INT_5_9_9_9_REV:
9489         result = 4;
9490         break;
9491     case GL_UNSIGNED_INT_24_8:
9492         result = 4;
9493         break;
9494     case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
9495         result = 8;
9496         break;
9497 
9498     default:
9499     {
9500         DE_ASSERT(0);
9501 
9502         result = 0;
9503     }
9504     }
9505 
9506     return result;
9507 }
9508 
9509 /** Takes a pointer with raw data representation and converts it to
9510  *  four instances of _pixel_data corresponding to four corners of a
9511  *  quad used for verification purposes. Assumes 2x2 resolution.
9512  *
9513  *  @param raw_data        Pointer to a buffer storing the data.
9514  *  @param raw_data_format Format of the data stored under @param raw_data.
9515  *  @param raw_data_type   Type of the data stored under @param raw_data.
9516  *  @param out_result      Deref will be used to store four _pixel_data instances.
9517  *                         Cannot be NULL, must be capacious enough to hold four
9518  *                         instances of the structure.
9519  *
9520  *  @return GTFtrue if successful, GTFfalse otherwise.
9521  **/
getPixelDataFromRawData(void * raw_data,GLenum raw_data_format,GLenum raw_data_type,PixelData * out_result)9522 bool RequiredCase::getPixelDataFromRawData(void *raw_data, GLenum raw_data_format, GLenum raw_data_type,
9523                                            PixelData *out_result)
9524 {
9525     // Quick checks: format should be equal to one of the values supported
9526     //                by glReadPixels()
9527     DE_ASSERT(raw_data_format == GL_RGBA || raw_data_format == GL_RGBA_INTEGER);
9528 
9529     if (raw_data_format != GL_RGBA && raw_data_format != GL_RGBA_INTEGER)
9530     {
9531         return false;
9532     }
9533 
9534     // Quick checks: type should be equal to one of the values supported
9535     //                by glReadPixels()
9536     DE_ASSERT(raw_data_type == GL_UNSIGNED_BYTE || raw_data_type == GL_UNSIGNED_INT || raw_data_type == GL_INT ||
9537               raw_data_type == GL_FLOAT || raw_data_type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
9538 
9539     if (raw_data_type != GL_UNSIGNED_BYTE && raw_data_type != GL_UNSIGNED_INT && raw_data_type != GL_INT &&
9540         raw_data_type != GL_FLOAT && raw_data_type != GL_UNSIGNED_INT_2_10_10_10_REV_EXT)
9541     {
9542         return false;
9543     }
9544 
9545     // Reset the result structure
9546     deMemset(out_result, 0, sizeof(PixelData));
9547 
9548     out_result->data_internalformat = raw_data_format;
9549     out_result->data_type           = raw_data_type;
9550 
9551     // Fill the fields, depending on user-provided format+type pair
9552     if (raw_data_format == GL_RGBA && raw_data_type == GL_UNSIGNED_BYTE)
9553     {
9554         char *raw_data_ptr = reinterpret_cast<char *>(raw_data);
9555 
9556         out_result->alpha.data_type = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
9557         out_result->blue.data_type  = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
9558         out_result->green.data_type = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
9559         out_result->red.data_type   = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS;
9560 
9561         out_result->red.unsigned_byte_data   = raw_data_ptr[0];
9562         out_result->green.unsigned_byte_data = raw_data_ptr[1];
9563         out_result->blue.unsigned_byte_data  = raw_data_ptr[2];
9564         out_result->alpha.unsigned_byte_data = raw_data_ptr[3];
9565     }
9566     else if (raw_data_format == GL_RGBA_INTEGER && raw_data_type == GL_UNSIGNED_INT)
9567     {
9568         unsigned int *raw_data_ptr = reinterpret_cast<unsigned int *>(raw_data);
9569 
9570         out_result->alpha.data_type = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
9571         out_result->blue.data_type  = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
9572         out_result->green.data_type = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
9573         out_result->red.data_type   = CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS;
9574 
9575         out_result->red.unsigned_integer_data   = raw_data_ptr[0];
9576         out_result->green.unsigned_integer_data = raw_data_ptr[1];
9577         out_result->blue.unsigned_integer_data  = raw_data_ptr[2];
9578         out_result->alpha.unsigned_integer_data = raw_data_ptr[3];
9579     }
9580     else if (raw_data_format == GL_RGBA_INTEGER && raw_data_type == GL_INT)
9581     {
9582         signed int *raw_data_ptr = reinterpret_cast<signed int *>(raw_data);
9583 
9584         out_result->alpha.data_type = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
9585         out_result->blue.data_type  = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
9586         out_result->green.data_type = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
9587         out_result->red.data_type   = CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS;
9588 
9589         out_result->red.signed_integer_data   = raw_data_ptr[0];
9590         out_result->green.signed_integer_data = raw_data_ptr[1];
9591         out_result->blue.signed_integer_data  = raw_data_ptr[2];
9592         out_result->alpha.signed_integer_data = raw_data_ptr[3];
9593     }
9594     else if (raw_data_format == GL_RGBA && raw_data_type == GL_FLOAT)
9595     {
9596         float *raw_data_ptr = reinterpret_cast<float *>(raw_data);
9597 
9598         out_result->alpha.data_type = CHANNEL_DATA_TYPE_FLOAT;
9599         out_result->blue.data_type  = CHANNEL_DATA_TYPE_FLOAT;
9600         out_result->green.data_type = CHANNEL_DATA_TYPE_FLOAT;
9601         out_result->red.data_type   = CHANNEL_DATA_TYPE_FLOAT;
9602 
9603         out_result->red.float_data   = raw_data_ptr[0];
9604         out_result->green.float_data = raw_data_ptr[1];
9605         out_result->blue.float_data  = raw_data_ptr[2];
9606         out_result->alpha.float_data = raw_data_ptr[3];
9607     } /* if (raw_data_format == GL_RGBA && raw_data_type == GL_FLOAT) */
9608     else
9609     {
9610         signed int *raw_data_ptr = (signed int *)raw_data;
9611 
9612         DE_ASSERT(raw_data_format == GL_RGBA && raw_data_type == GL_UNSIGNED_INT_2_10_10_10_REV);
9613 
9614         out_result->alpha.data_type = CHANNEL_DATA_TYPE_UNSIGNED_BYTE_2BITS;
9615         out_result->blue.data_type  = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
9616         out_result->green.data_type = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
9617         out_result->red.data_type   = CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS;
9618 
9619         out_result->alpha.unsigned_byte_data  = ((*raw_data_ptr) >> 30) & ((1 << 2) - 1);
9620         out_result->blue.unsigned_short_data  = ((*raw_data_ptr) >> 20) & ((1 << 10) - 1);
9621         out_result->green.unsigned_short_data = ((*raw_data_ptr) >> 10) & ((1 << 10) - 1);
9622         out_result->red.unsigned_short_data   = ((*raw_data_ptr)) & ((1 << 10) - 1);
9623     }
9624 
9625     return true;
9626 }
9627 
9628 /** Checks if downloaded pixel data is valid. Should the rendered values differ
9629  *  outside allowed range, the function logs detailed information about the problem.
9630  *
9631  *  @param downloaded_pixel        Instance of _pixel_data describing a pixel
9632  *                                 that was rendered by the implementation.
9633  *  @param reference_pixel         Instance of _pixel_data describing ideal
9634  *                                 pixel data.
9635  *  @param source_pixel            Instance of _pixel_data describing the pixel
9636  *                                 prior to conversion.
9637  *  @param result_internalformat   Internal format the implementation is expected
9638  *                                 to be using for the converted data.
9639  *  @param src_attachment_type     Type of the source object used for the conversion.
9640  *  @param dst_attachment_type     Type of the destination object used for the conversion.
9641  *  @param has_test_failed_already 1 if any of the other pixels making up the test 2x2
9642  *                                 data-set has already been determined to be corrupt.
9643  *                                 0 otherwise.
9644  *  @param src_internalformat      Internal-format used for source object's data storage.
9645  *  @param src_datatype            Type used for source object's data storage.
9646  *
9647  *  @return 1 if the pixels match, 0 otherwise.
9648  **/
comparePixelData(PixelData downloaded_pixel,PixelData reference_pixel,PixelData source_pixel,GLenum result_internalformat,bool has_test_failed_already)9649 bool RequiredCase::comparePixelData(PixelData downloaded_pixel, PixelData reference_pixel, PixelData source_pixel,
9650                                     GLenum result_internalformat, bool has_test_failed_already)
9651 {
9652     ChannelData *channel_data[12] = {0};
9653     int max_epsilon[4]            = {0};
9654     int has_pixel_failed          = 0;
9655     int n_channel                 = 0;
9656     bool result                   = true;
9657     int result_rgba_bits[4]       = {0};
9658     int source_rgba_bits[4]       = {0};
9659 
9660     // Form channel data so we can later analyse channels one after another in a loop
9661     channel_data[0]  = &downloaded_pixel.red;
9662     channel_data[1]  = &reference_pixel.red;
9663     channel_data[2]  = &source_pixel.red;
9664     channel_data[3]  = &downloaded_pixel.green;
9665     channel_data[4]  = &reference_pixel.green;
9666     channel_data[5]  = &source_pixel.green;
9667     channel_data[6]  = &downloaded_pixel.blue;
9668     channel_data[7]  = &reference_pixel.blue;
9669     channel_data[8]  = &source_pixel.blue;
9670     channel_data[9]  = &downloaded_pixel.alpha;
9671     channel_data[10] = &reference_pixel.alpha;
9672     channel_data[11] = &source_pixel.alpha;
9673 
9674     // Retrieve number of bits used for source and result data.
9675     getNumberOfBitsForInternalFormat(source_pixel.data_internalformat, source_rgba_bits);
9676     getNumberOfBitsForInternalFormat(result_internalformat, result_rgba_bits);
9677 
9678     // Time for actual comparison!
9679     for (unsigned int n = 0; n < sizeof(channel_data) / sizeof(channel_data[0]);
9680          n += 3 /* downloaded + reference + source pixel combinations */, ++n_channel)
9681     {
9682         ChannelData *downloaded_channel_ptr = channel_data[n];
9683         ChannelData *reference_channel_ptr  = channel_data[n + 1];
9684 
9685         // Calculate maximum epsilon
9686         int max_n_bits     = 0;
9687         int min_n_bits     = std::numeric_limits<int>::max();
9688         int n_dst_bits     = result_rgba_bits[n_channel];
9689         int n_reading_bits = 0;
9690         int n_source_bits  = source_rgba_bits[n_channel];
9691 
9692         getNumberOfBitsForChannelDataType(downloaded_channel_ptr->data_type, &n_reading_bits);
9693 
9694         if (max_n_bits < n_dst_bits && n_dst_bits != 0)
9695         {
9696             max_n_bits = n_dst_bits;
9697         } /* if (max_n_bits < n_dst_bits && n_dst_bits != 0) */
9698         if (max_n_bits < n_reading_bits && n_reading_bits != 0)
9699         {
9700             max_n_bits = n_reading_bits;
9701         }
9702         if (max_n_bits < n_source_bits && n_source_bits != 0)
9703         {
9704             max_n_bits = n_source_bits;
9705         }
9706 
9707         if (n_dst_bits != 0)
9708         {
9709             min_n_bits = n_dst_bits;
9710         }
9711 
9712         if (min_n_bits > n_reading_bits && n_reading_bits != 0)
9713         {
9714             min_n_bits = n_reading_bits;
9715         }
9716         if (min_n_bits > n_source_bits && n_source_bits != 0)
9717         {
9718             min_n_bits = n_source_bits;
9719         }
9720 
9721         if (max_n_bits != min_n_bits && max_n_bits != 0)
9722         {
9723             DE_ASSERT(min_n_bits != std::numeric_limits<int>::max());
9724 
9725             // Allow rounding in either direction
9726             max_epsilon[n_channel] = deCeilFloatToInt32(((1 << max_n_bits) - 1.0f) / ((1 << min_n_bits) - 1));
9727         }
9728         else
9729         {
9730             max_epsilon[n_channel] = 0;
9731         }
9732 
9733         // At the moment, we only care about data types that correspond to GL types usable for glReadPixels() calls.
9734         // Please feel free to expand this switch() with support for data types you need.
9735         switch (downloaded_channel_ptr->data_type)
9736         {
9737         case CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS:
9738         {
9739             int delta = (downloaded_channel_ptr->signed_integer_data - reference_channel_ptr->signed_integer_data);
9740 
9741             if (abs(delta) > max_epsilon[n_channel])
9742             {
9743                 if (result)
9744                 {
9745                     has_pixel_failed = 1;
9746                     result           = false;
9747                 }
9748             }
9749 
9750             break;
9751         }
9752 
9753         case CHANNEL_DATA_TYPE_UNSIGNED_BYTE_2BITS:
9754         case CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS:
9755         {
9756             int delta = (downloaded_channel_ptr->unsigned_byte_data - reference_channel_ptr->unsigned_byte_data);
9757 
9758             if (abs(delta) > max_epsilon[n_channel])
9759             {
9760                 if (result)
9761                 {
9762                     has_pixel_failed = 1;
9763                     result           = false;
9764                 }
9765             }
9766 
9767             break;
9768         }
9769 
9770         case CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS:
9771         {
9772             int delta = static_cast<int>(downloaded_channel_ptr->unsigned_integer_data -
9773                                          reference_channel_ptr->unsigned_integer_data);
9774 
9775             if (abs(delta) > max_epsilon[n_channel])
9776             {
9777                 if (result)
9778                 {
9779                     has_pixel_failed = 1;
9780                     result           = false;
9781                 }
9782             }
9783 
9784             break;
9785         }
9786 
9787         case CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS:
9788         {
9789             int delta = (downloaded_channel_ptr->unsigned_short_data - reference_channel_ptr->unsigned_short_data);
9790 
9791             if (abs(delta) > max_epsilon[n_channel])
9792             {
9793                 if (result)
9794                 {
9795                     has_pixel_failed = 1;
9796                     result           = false;
9797                 }
9798             }
9799 
9800             break;
9801         } /* case CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS: */
9802 
9803         case CHANNEL_DATA_TYPE_FLOAT:
9804         {
9805             int delta = deChopFloatToInt32(downloaded_channel_ptr->float_data - reference_channel_ptr->float_data);
9806 
9807             if (abs(delta) > max_epsilon[n_channel])
9808             {
9809                 if (result)
9810                 {
9811                     has_pixel_failed = 1;
9812                     result           = false;
9813                 }
9814             }
9815 
9816             break;
9817         }
9818 
9819         default:
9820         {
9821             // Unrecognized data type
9822             DE_ASSERT(0);
9823         }
9824         }
9825 
9826         if (has_pixel_failed && !has_test_failed_already)
9827         {
9828             m_testCtx.getLog() << tcu::TestLog::Message << "Erroneous test case starts-->" << tcu::TestLog::EndMessage;
9829             has_test_failed_already = true;
9830         }
9831     } // for (all channels)
9832 
9833     if (!result)
9834     {
9835         displayPixelComparisonFailureMessage(
9836             channel_data[2] != NULL ? channel_data[2]->unsigned_integer_data : 0,
9837             channel_data[5] != NULL ? channel_data[5]->unsigned_integer_data : 0,
9838             channel_data[8] != NULL ? channel_data[8]->unsigned_integer_data : 0,
9839             channel_data[11] != NULL ? channel_data[11]->unsigned_integer_data : 0, source_pixel.data_internalformat,
9840             source_pixel.data_type, channel_data[1] != NULL ? channel_data[1]->unsigned_integer_data : 0,
9841             channel_data[4] != NULL ? channel_data[4]->unsigned_integer_data : 0,
9842             channel_data[7] != NULL ? channel_data[7]->unsigned_integer_data : 0,
9843             channel_data[10] != NULL ? channel_data[10]->unsigned_integer_data : 0, reference_pixel.data_internalformat,
9844             reference_pixel.data_type, channel_data[0] != NULL ? channel_data[0]->unsigned_integer_data : 0,
9845             channel_data[3] != NULL ? channel_data[3]->unsigned_integer_data : 0,
9846             channel_data[6] != NULL ? channel_data[6]->unsigned_integer_data : 0,
9847             channel_data[9] != NULL ? channel_data[9]->unsigned_integer_data : 0, result_internalformat,
9848             downloaded_pixel.data_type, max_epsilon[0], max_epsilon[1], max_epsilon[2], max_epsilon[3]);
9849     }
9850 
9851     return result;
9852 }
9853 
9854 /** Retrieves number of bits used for a single pixel, were it
9855  *  stored in @param internalformat internal format.
9856  *
9857  *  @param internalformat GLES internal format to consider.
9858  *  @param out_rgba_bits  Deref will be used to store 4 integers
9859  *                        describing amount of bits that the internal
9860  *                        format uses for subsequently R, G, B and A
9861  *                        channels. Cannot be NULL.
9862  *
9863  *  @return GTFtrue if successful, GTFfalse otherwise.
9864  **/
getNumberOfBitsForInternalFormat(GLenum internalformat,int * out_rgba_bits)9865 bool RequiredCase::getNumberOfBitsForInternalFormat(GLenum internalformat, int *out_rgba_bits)
9866 {
9867     deMemset(out_rgba_bits, 0, sizeof(int) * 4);
9868 
9869     switch (internalformat)
9870     {
9871     case GL_LUMINANCE8_OES:
9872         out_rgba_bits[0] = 8;
9873         break;
9874     case GL_R16I:
9875         out_rgba_bits[0] = 16;
9876         break;
9877     case GL_R16UI:
9878         out_rgba_bits[0] = 16;
9879         break;
9880     case GL_R32I:
9881         out_rgba_bits[0] = 32;
9882         break;
9883     case GL_R32UI:
9884         out_rgba_bits[0] = 32;
9885         break;
9886     case GL_R8:
9887         out_rgba_bits[0] = 8;
9888         break;
9889     case GL_R8_SNORM:
9890         out_rgba_bits[0] = 8;
9891         break;
9892     case GL_R8I:
9893         out_rgba_bits[0] = 8;
9894         break;
9895     case GL_R8UI:
9896         out_rgba_bits[0] = 8;
9897         break;
9898     case GL_RG16UI:
9899         out_rgba_bits[0] = 16;
9900         out_rgba_bits[1] = 16;
9901         break;
9902     case GL_RG16I:
9903         out_rgba_bits[0] = 16;
9904         out_rgba_bits[1] = 16;
9905         break;
9906     case GL_RG32I:
9907         out_rgba_bits[0] = 32;
9908         out_rgba_bits[1] = 32;
9909         break;
9910     case GL_RG32UI:
9911         out_rgba_bits[0] = 32;
9912         out_rgba_bits[1] = 32;
9913         break;
9914     case GL_RG8:
9915         out_rgba_bits[0] = 8;
9916         out_rgba_bits[1] = 8;
9917         break;
9918     case GL_RG8_SNORM:
9919         out_rgba_bits[0] = 8;
9920         out_rgba_bits[1] = 8;
9921         break;
9922     case GL_RG8I:
9923         out_rgba_bits[0] = 8;
9924         out_rgba_bits[1] = 8;
9925         break;
9926     case GL_RG8UI:
9927         out_rgba_bits[0] = 8;
9928         out_rgba_bits[1] = 8;
9929         break;
9930     case GL_RGB10_A2:
9931         out_rgba_bits[0] = 10;
9932         out_rgba_bits[1] = 10;
9933         out_rgba_bits[2] = 10;
9934         out_rgba_bits[3] = 2;
9935         break;
9936     case GL_RGB10_A2UI:
9937         out_rgba_bits[0] = 10;
9938         out_rgba_bits[1] = 10;
9939         out_rgba_bits[2] = 10;
9940         out_rgba_bits[3] = 2;
9941         break;
9942     case GL_RGB16I:
9943         out_rgba_bits[0] = 16;
9944         out_rgba_bits[1] = 16;
9945         out_rgba_bits[2] = 16;
9946         break;
9947     case GL_RGB16UI:
9948         out_rgba_bits[0] = 16;
9949         out_rgba_bits[1] = 16;
9950         out_rgba_bits[2] = 16;
9951         break;
9952     case GL_RGB32I:
9953         out_rgba_bits[0] = 32;
9954         out_rgba_bits[1] = 32;
9955         out_rgba_bits[2] = 32;
9956         break;
9957     case GL_RGB32UI:
9958         out_rgba_bits[0] = 32;
9959         out_rgba_bits[1] = 32;
9960         out_rgba_bits[2] = 32;
9961         break;
9962     case GL_RGB5_A1:
9963         out_rgba_bits[0] = 5;
9964         out_rgba_bits[1] = 5;
9965         out_rgba_bits[2] = 5;
9966         out_rgba_bits[3] = 1;
9967         break;
9968     case GL_RGB565:
9969         out_rgba_bits[0] = 5;
9970         out_rgba_bits[1] = 6;
9971         out_rgba_bits[2] = 5;
9972         break;
9973     case GL_RGB8:
9974         out_rgba_bits[0] = 8;
9975         out_rgba_bits[1] = 8;
9976         out_rgba_bits[2] = 8;
9977         break;
9978     case GL_RGB8_SNORM:
9979         out_rgba_bits[0] = 8;
9980         out_rgba_bits[1] = 8;
9981         out_rgba_bits[2] = 8;
9982         break;
9983     case GL_RGB8I:
9984         out_rgba_bits[0] = 8;
9985         out_rgba_bits[1] = 8;
9986         out_rgba_bits[2] = 8;
9987         break;
9988     case GL_RGB8UI:
9989         out_rgba_bits[0] = 8;
9990         out_rgba_bits[1] = 8;
9991         out_rgba_bits[2] = 8;
9992         break;
9993     case GL_RGBA16I:
9994         out_rgba_bits[0] = 16;
9995         out_rgba_bits[1] = 16;
9996         out_rgba_bits[2] = 16;
9997         out_rgba_bits[3] = 16;
9998         break;
9999     case GL_RGBA16UI:
10000         out_rgba_bits[0] = 16;
10001         out_rgba_bits[1] = 16;
10002         out_rgba_bits[2] = 16;
10003         out_rgba_bits[3] = 16;
10004         break;
10005     case GL_RGBA32I:
10006         out_rgba_bits[0] = 32;
10007         out_rgba_bits[1] = 32;
10008         out_rgba_bits[2] = 32;
10009         out_rgba_bits[3] = 32;
10010         break;
10011     case GL_RGBA32UI:
10012         out_rgba_bits[0] = 32;
10013         out_rgba_bits[1] = 32;
10014         out_rgba_bits[2] = 32;
10015         out_rgba_bits[3] = 32;
10016         break;
10017     case GL_RGBA4:
10018         out_rgba_bits[0] = 4;
10019         out_rgba_bits[1] = 4;
10020         out_rgba_bits[2] = 4;
10021         out_rgba_bits[3] = 4;
10022         break;
10023     case GL_RGBA8:
10024         out_rgba_bits[0] = 8;
10025         out_rgba_bits[1] = 8;
10026         out_rgba_bits[2] = 8;
10027         out_rgba_bits[3] = 8;
10028         break;
10029     case GL_RGBA8_SNORM:
10030         out_rgba_bits[0] = 8;
10031         out_rgba_bits[1] = 8;
10032         out_rgba_bits[2] = 8;
10033         out_rgba_bits[3] = 8;
10034         break;
10035     case GL_RGBA8I:
10036         out_rgba_bits[0] = 8;
10037         out_rgba_bits[1] = 8;
10038         out_rgba_bits[2] = 8;
10039         out_rgba_bits[3] = 8;
10040         break;
10041     case GL_RGBA8UI:
10042         out_rgba_bits[0] = 8;
10043         out_rgba_bits[1] = 8;
10044         out_rgba_bits[2] = 8;
10045         out_rgba_bits[3] = 8;
10046         break;
10047     case GL_SRGB8:
10048         out_rgba_bits[0] = 8;
10049         out_rgba_bits[1] = 8;
10050         out_rgba_bits[2] = 8;
10051         break;
10052     case GL_SRGB8_ALPHA8:
10053         out_rgba_bits[0] = 8;
10054         out_rgba_bits[1] = 8;
10055         out_rgba_bits[2] = 8;
10056         out_rgba_bits[3] = 8;
10057         break;
10058     case GL_R16F:
10059         out_rgba_bits[0] = 16;
10060         break;
10061     case GL_RG16F:
10062         out_rgba_bits[0] = 16;
10063         out_rgba_bits[1] = 16;
10064         break;
10065     case GL_RGB16F:
10066         out_rgba_bits[0] = 16;
10067         out_rgba_bits[1] = 16;
10068         out_rgba_bits[2] = 16;
10069         break;
10070     case GL_RGBA16F:
10071         out_rgba_bits[0] = 16;
10072         out_rgba_bits[1] = 16;
10073         out_rgba_bits[2] = 16;
10074         out_rgba_bits[3] = 16;
10075         break;
10076     case GL_R32F:
10077         out_rgba_bits[0] = 32;
10078         break;
10079     case GL_RG32F:
10080         out_rgba_bits[0] = 32;
10081         out_rgba_bits[1] = 32;
10082         break;
10083     case GL_RGB32F:
10084         out_rgba_bits[0] = 32;
10085         out_rgba_bits[1] = 32;
10086         out_rgba_bits[2] = 32;
10087         break;
10088     case GL_RGBA32F:
10089         out_rgba_bits[0] = 32;
10090         out_rgba_bits[1] = 32;
10091         out_rgba_bits[2] = 32;
10092         out_rgba_bits[3] = 32;
10093         break;
10094 
10095     default:
10096     {
10097         DE_ASSERT(0);
10098         return false;
10099     }
10100     }
10101 
10102     return true;
10103 }
10104 
10105 /** Browses the conversion database provided by user and looks for conversion rules
10106  *  that match the following requirements:
10107  *
10108  *  1) Source object's data internal format equal to @param src_internalformat.
10109  *  2) Source object's data type equal to @param src_type.
10110  *  3) Internal format used for glCopyTexImage2D() call equal to @param copyteximage2d_internalformat.
10111  *
10112  *  The function allows to find as many conversion rules matching these requirements as
10113  *  available. For any triple, caller should use incrementing values of @param index,
10114  *  starting from 0.
10115  *
10116  *  Source dataset corresponds to 2x2 image (using up to 4 channels) that the attachment bound to
10117  *  read buffer will use prior to glCopyTexImage2D() call.
10118  *  Destination dataset corresponds to 2x2 image (using up to 4 channels) that the result texture object
10119  *  should match (within acceptable epsilon).
10120  *
10121  *  @param index                         Index of conversion rule the caller is interested in reading.
10122  *  @param src_internalformat            Source object's data internal format to assume.
10123  *  @param src_type                      Source object's data type to assume.
10124  *  @param copyteximage2d_internalformat Internal format to be used for glCopyTexImage2D() call.
10125  *  @param out_result_internalformat     Deref will be used to store internal format that GLES implementation
10126  *                                       should use for storage of the converted data. Cannot be NULL.
10127  *  @param out_dst_type                  Deref will be used to store type that GLES implementation should use
10128  *                                       for storage of the converted data. Cannot be NULL.
10129  *  @param out_src_topleft               Deref will be used to store _pixel_data instance describing top-left
10130  *                                       corner of the source dataset. Cannot be NULL.
10131  *  @param out_src_topright              Deref will be used to store _pixel_data instance describing top-right
10132  *                                       corner of the source dataset. Cannot be NULL.
10133  *  @param out_src_bottomleft            Deref will be used to store _pixel_data instance describing bottom-left
10134  *                                       corner of the source dataset. Cannot be NULL.
10135  *  @param out_src_bottomright           Deref will be used to store _pixel_data instance describing bottom-right
10136  *                                       corner of the source dataset. Cannot be NULL.
10137  *  @param out_dst_topleft               Deref will be used to store _pixel_data instance describing top-left
10138  *                                       corner of the destination dataset.
10139  *  @param out_dst_topright              Deref will be used to store _pixel_data instance describing top-right
10140  *                                       corner of the destination dataset.
10141  *  @param out_dst_bottomleft            Deref will be used to store _pixel_data instance describing bottom-left
10142  *                                       corner of the destination dataset.
10143  *  @param out_dst_bottomright           Deref will be used to store _pixel_data instance describing bottom-right
10144  *                                       corner of the destination dataset.
10145  *
10146  *  @return GTFtrue if @param index -th conversion rule was found, GTFfalse otherwise.
10147  **/
findEntryInConversionDatabase(unsigned int index,GLenum src_internalformat,GLenum src_type,GLenum copyteximage2d_internalformat,GLenum * out_result_internalformat,GLenum * out_dst_type,PixelData * out_src_topleft,PixelData * out_src_topright,PixelData * out_src_bottomleft,PixelData * out_src_bottomright,PixelData * out_dst_topleft,PixelData * out_dst_topright,PixelData * out_dst_bottomleft,PixelData * out_dst_bottomright,PixelCompareChannel * out_channels_to_compare)10148 bool RequiredCase::findEntryInConversionDatabase(unsigned int index, GLenum src_internalformat, GLenum src_type,
10149                                                  GLenum copyteximage2d_internalformat,
10150                                                  GLenum *out_result_internalformat, GLenum *out_dst_type,
10151                                                  PixelData *out_src_topleft, PixelData *out_src_topright,
10152                                                  PixelData *out_src_bottomleft, PixelData *out_src_bottomright,
10153                                                  PixelData *out_dst_topleft, PixelData *out_dst_topright,
10154                                                  PixelData *out_dst_bottomleft, PixelData *out_dst_bottomright,
10155                                                  PixelCompareChannel *out_channels_to_compare)
10156 {
10157     const int conversion_array_width =
10158         sizeof(copyTexImage2DInternalFormatOrdering) / sizeof(copyTexImage2DInternalFormatOrdering[0]);
10159     int copyteximage2d_index               = -1;
10160     int fbo_effective_internalformat_index = -1;
10161     unsigned int n_entry                   = 0;
10162     unsigned int n_matching_entries        = 0;
10163     GLenum result_internalformat           = GL_NONE;
10164     int result_internalformat_index        = -1;
10165 
10166     /* Quick checks */
10167     DE_ASSERT(out_src_topleft != NULL);
10168     DE_ASSERT(out_src_topright != NULL);
10169     DE_ASSERT(out_src_bottomleft != NULL);
10170     DE_ASSERT(out_src_bottomright != NULL);
10171     DE_ASSERT(out_dst_topleft != NULL);
10172     DE_ASSERT(out_dst_topright != NULL);
10173     DE_ASSERT(out_dst_bottomleft != NULL);
10174     DE_ASSERT(out_dst_bottomright != NULL);
10175 
10176     // Retrieve internalformat that converted data will be stored in
10177     copyteximage2d_index               = getIndexOfCopyTexImage2DInternalFormat(copyteximage2d_internalformat);
10178     fbo_effective_internalformat_index = getIndexOfFramebufferEffectiveInternalFormat(src_internalformat);
10179 
10180     DE_ASSERT(copyteximage2d_index != -1 && fbo_effective_internalformat_index != -1);
10181     if (copyteximage2d_index == -1 || fbo_effective_internalformat_index == -1)
10182         return false;
10183 
10184     result_internalformat_index = fbo_effective_internalformat_index * conversion_array_width + copyteximage2d_index;
10185 
10186     DE_ASSERT(result_internalformat_index < DE_LENGTH_OF_ARRAY(conversionArray));
10187     if (result_internalformat_index >= DE_LENGTH_OF_ARRAY(conversionArray))
10188         return false;
10189 
10190     result_internalformat = conversionArray[result_internalformat_index];
10191 
10192     DE_ASSERT(result_internalformat != GL_NONE);
10193     if (result_internalformat == GL_NONE)
10194         return false;
10195 
10196     // We use the simplest approach possible to keep the code as readable as possible.
10197     for (n_entry = 0; n_entry < m_conversion_database->n_entries_added; ++n_entry)
10198     {
10199         ConversionDatabaseEntry &entry_ptr = m_conversion_database->entries[n_entry];
10200 
10201         if (entry_ptr.src_bottomleft_corner.data_internalformat == src_internalformat &&
10202             entry_ptr.src_bottomleft_corner.data_type == src_type &&
10203             entry_ptr.dst_bottomleft_corner.data_internalformat == result_internalformat)
10204         {
10205             /* Is it the n-th match we're being asked for? */
10206             if (index == n_matching_entries)
10207             {
10208                 /* Indeed! */
10209                 *out_src_topleft     = entry_ptr.src_topleft_corner;
10210                 *out_src_topright    = entry_ptr.src_topright_corner;
10211                 *out_src_bottomleft  = entry_ptr.src_bottomleft_corner;
10212                 *out_src_bottomright = entry_ptr.src_bottomright_corner;
10213                 *out_dst_topleft     = entry_ptr.dst_topleft_corner;
10214                 *out_dst_topright    = entry_ptr.dst_topright_corner;
10215                 *out_dst_bottomleft  = entry_ptr.dst_bottomleft_corner;
10216                 *out_dst_bottomright = entry_ptr.dst_bottomright_corner;
10217 
10218                 *out_result_internalformat = entry_ptr.dst_topleft_corner.data_internalformat;
10219                 *out_dst_type              = entry_ptr.dst_topleft_corner.data_type;
10220 
10221                 *out_channels_to_compare = entry_ptr.channels_to_compare;
10222 
10223                 return true;
10224             }
10225             else
10226             {
10227                 ++n_matching_entries;
10228             }
10229         }
10230     }
10231 
10232     return false;
10233 }
10234 
10235 /** Retrieves index under which user-specified internalformat can be found in
10236  *  copy_tex_image_2d_internal_format_ordering array.
10237  *
10238  *  @param internalformat GLES internal format to look for.
10239  *
10240  *  @return Index >= 0 if successful, -1 otherwise.
10241  **/
getIndexOfCopyTexImage2DInternalFormat(GLenum internalformat)10242 int RequiredCase::getIndexOfCopyTexImage2DInternalFormat(GLenum internalformat)
10243 {
10244     int max_index = DE_LENGTH_OF_ARRAY(copyTexImage2DInternalFormatOrdering);
10245     for (int index = 0; index < max_index; ++index)
10246     {
10247         if (copyTexImage2DInternalFormatOrdering[index] == internalformat)
10248             return index;
10249     }
10250 
10251     return -1;
10252 }
10253 
10254 /** Retrieves index under which user-specified internalformat can be found in
10255  *  fbo_effective_internal_format_ordering array.
10256  *
10257  *  @param internalformat GLES internal format to look for.
10258  *
10259  *  @return Index >= 0 if successful, -1 otherwise.
10260  **/
getIndexOfFramebufferEffectiveInternalFormat(GLenum internalformat)10261 int RequiredCase::getIndexOfFramebufferEffectiveInternalFormat(GLenum internalformat)
10262 {
10263     int max_index = DE_LENGTH_OF_ARRAY(fboEffectiveInternalFormatOrdering);
10264     for (int index = 0; index < max_index; ++index)
10265     {
10266         if (fboEffectiveInternalFormatOrdering[index] == internalformat)
10267             return index;
10268     }
10269 
10270     return -1;
10271 }
10272 
10273 /** Takes four pixels (described by _pixel_data structures) making up
10274  *  the 2x2 texture used for source objects, and converts the representation
10275  *  to raw data that can later be fed to glTexImage2D(), glTexImage3D() etc.
10276  *  calls.
10277  *
10278  *  NOTE: It is caller's responsibility to free the returned buffer when no
10279  *        longer used. Use free() function to deallocate the resource.
10280  *
10281  *  @param topleft     Instance of _pixel_data describing top-left corner.
10282  *  @param topright    Instance of _pixel_data describing top-right corner.
10283  *  @param bottomleft  Instance of _pixel_data describing bottom-left corner.
10284  *  @param bottomright Instance of _pixel_data describing bottom-right corner.
10285  *
10286  *  @return Pointer to the buffer or NULL if failed.
10287  **/
getRawDataFromPixelData(std::vector<char> & result,PixelData topleft,PixelData topright,PixelData bottomleft,PixelData bottomright)10288 bool RequiredCase::getRawDataFromPixelData(std::vector<char> &result, PixelData topleft, PixelData topright,
10289                                            PixelData bottomleft, PixelData bottomright)
10290 {
10291     ChannelOrder channel_order     = CHANNEL_ORDER_UNKNOWN;
10292     GLenum format                  = GL_NONE;
10293     GLenum internalformat          = topleft.data_internalformat;
10294     unsigned int n_bytes_needed    = 0;
10295     unsigned int n_bytes_per_pixel = 0;
10296     unsigned int n_pixel           = 0;
10297     const PixelData *pixels[]      = {&bottomleft, &bottomright, &topleft, &topright};
10298     char *result_traveller         = DE_NULL;
10299     GLenum type                    = topleft.data_type;
10300 
10301     // Quick checks
10302     DE_ASSERT(topleft.data_internalformat == topright.data_internalformat);
10303     DE_ASSERT(topleft.data_internalformat == bottomleft.data_internalformat);
10304     DE_ASSERT(topleft.data_internalformat == bottomright.data_internalformat);
10305     DE_ASSERT(topleft.data_type == topright.data_type);
10306     DE_ASSERT(topleft.data_type == bottomleft.data_type);
10307     DE_ASSERT(topleft.data_type == bottomright.data_type);
10308 
10309     // Allocate the buffer
10310     if (!getFormatForInternalformat(internalformat, &format))
10311     {
10312         DE_ASSERT(0);
10313         return false;
10314     } // if (no format known for requested internalformat)
10315 
10316     if (!getChannelOrderForInternalformatAndType(internalformat, type, &channel_order))
10317     {
10318         DE_ASSERT(0);
10319         return false;
10320     } // if (no channel order known for internalformat+type combination)
10321 
10322     // special case for GL_HALF_FLOAT, treat it as a FLOAT
10323     if (type == GL_HALF_FLOAT)
10324         n_bytes_per_pixel = getSizeOfPixel(format, GL_FLOAT);
10325     else
10326         n_bytes_per_pixel = getSizeOfPixel(format, type);
10327     n_bytes_needed = TEXTURE_WIDTH * TEXTURE_HEIGHT * n_bytes_per_pixel;
10328 
10329     if (n_bytes_needed == 0)
10330     {
10331         DE_ASSERT(0);
10332         return false;
10333     }
10334 
10335     result.resize(n_bytes_needed);
10336 
10337     // Fill the raw data buffer with data.
10338     result_traveller = &result[0];
10339 
10340     for (n_pixel = 0; n_pixel < sizeof(pixels) / sizeof(pixels[0]); ++n_pixel)
10341     {
10342         const ChannelData *channels[] = {NULL, NULL, NULL, NULL}; /* We need up to four channels */
10343         int n_bits_for_channel_0      = 0;
10344         int n_bits_for_channel_1      = 0;
10345         int n_bits_for_channel_2      = 0;
10346         int n_bits_for_channel_3      = 0;
10347         const PixelData *pixel_ptr    = pixels[n_pixel];
10348 
10349         switch (channel_order)
10350         {
10351         case CHANNEL_ORDER_ABGR:
10352         {
10353             channels[0] = &pixel_ptr->alpha;
10354             channels[1] = &pixel_ptr->blue;
10355             channels[2] = &pixel_ptr->green;
10356             channels[3] = &pixel_ptr->red;
10357             break;
10358         }
10359 
10360         case CHANNEL_ORDER_BGR:
10361         {
10362             channels[0] = &pixel_ptr->blue;
10363             channels[1] = &pixel_ptr->green;
10364             channels[2] = &pixel_ptr->red;
10365             break;
10366         }
10367 
10368         case CHANNEL_ORDER_BGRA:
10369         {
10370             channels[0] = &pixel_ptr->blue;
10371             channels[1] = &pixel_ptr->green;
10372             channels[2] = &pixel_ptr->red;
10373             channels[3] = &pixel_ptr->alpha;
10374             break;
10375         }
10376 
10377         case CHANNEL_ORDER_R:
10378         {
10379             channels[0] = &pixel_ptr->red;
10380             break;
10381         }
10382 
10383         case CHANNEL_ORDER_RG:
10384         {
10385             channels[0] = &pixel_ptr->red;
10386             channels[1] = &pixel_ptr->green;
10387             break;
10388         }
10389 
10390         case CHANNEL_ORDER_RGB:
10391         {
10392             channels[0] = &pixel_ptr->red;
10393             channels[1] = &pixel_ptr->green;
10394             channels[2] = &pixel_ptr->blue;
10395             break;
10396         }
10397 
10398         case CHANNEL_ORDER_RGBA:
10399         {
10400             channels[0] = &pixel_ptr->red;
10401             channels[1] = &pixel_ptr->green;
10402             channels[2] = &pixel_ptr->blue;
10403             channels[3] = &pixel_ptr->alpha;
10404             break;
10405         }
10406 
10407         default:
10408         {
10409             // Unrecognized channel order
10410             DE_ASSERT(0);
10411         }
10412         }
10413 
10414         // Pack the channel data, depending on channel sizes
10415         if (((channels[0] != NULL) &&
10416              !getNumberOfBitsForChannelDataType(channels[0]->data_type, &n_bits_for_channel_0)) ||
10417             ((channels[1] != NULL) &&
10418              !getNumberOfBitsForChannelDataType(channels[1]->data_type, &n_bits_for_channel_1)) ||
10419             ((channels[2] != NULL) &&
10420              !getNumberOfBitsForChannelDataType(channels[2]->data_type, &n_bits_for_channel_2)) ||
10421             ((channels[3] != NULL) &&
10422              !getNumberOfBitsForChannelDataType(channels[3]->data_type, &n_bits_for_channel_3)))
10423         {
10424             // Unrecognized data type
10425             DE_ASSERT(0);
10426             return false;
10427         } // if (could not determine number of bits making up any of the channels)
10428 
10429         // NOTE: We will read HALF_FLOAT data as FLOAT data (32 bit) to avoid conversion before passing the data to GL
10430         if (channels[0] != NULL && channels[1] != NULL && channels[2] != NULL && channels[3] != NULL)
10431         {
10432             // RGBA32
10433             if (type == GL_HALF_FLOAT || ((n_bits_for_channel_0 == 32) && (n_bits_for_channel_1 == 32) &&
10434                                           (n_bits_for_channel_2 == 32) && (n_bits_for_channel_3 == 32)))
10435             {
10436                 unsigned int *result_traveller32 = (unsigned int *)result_traveller;
10437 
10438                 *result_traveller32 = channels[0]->unsigned_integer_data;
10439                 result_traveller32++;
10440                 *result_traveller32 = channels[1]->unsigned_integer_data;
10441                 result_traveller32++;
10442                 *result_traveller32 = channels[2]->unsigned_integer_data;
10443                 result_traveller32++;
10444                 *result_traveller32 = channels[3]->unsigned_integer_data;
10445 
10446                 result_traveller += 4 * 4;
10447             }
10448             else
10449                 // RGBA16
10450                 if (n_bits_for_channel_0 == 16 && n_bits_for_channel_1 == 16 && n_bits_for_channel_2 == 16 &&
10451                     n_bits_for_channel_3 == 16)
10452                 {
10453                     unsigned short *result_traveller16 = (unsigned short *)result_traveller;
10454 
10455                     *result_traveller16 = channels[0]->unsigned_short_data;
10456                     result_traveller16++;
10457                     *result_traveller16 = channels[1]->unsigned_short_data;
10458                     result_traveller16++;
10459                     *result_traveller16 = channels[2]->unsigned_short_data;
10460                     result_traveller16++;
10461                     *result_traveller16 = channels[3]->unsigned_short_data;
10462 
10463                     result_traveller += 8;
10464                 }
10465                 else
10466                     // RGBA4
10467                     if (n_bits_for_channel_0 == 4 && n_bits_for_channel_1 == 4 && n_bits_for_channel_2 == 4 &&
10468                         n_bits_for_channel_3 == 4)
10469                     {
10470                         unsigned short *result_traveller16 = (unsigned short *)result_traveller;
10471 
10472                         *result_traveller16 = (channels[0]->unsigned_byte_data << 12) +
10473                                               (channels[1]->unsigned_byte_data << 8) +
10474                                               (channels[2]->unsigned_byte_data << 4) + channels[3]->unsigned_byte_data;
10475 
10476                         result_traveller += 2;
10477                     }
10478                     else
10479                         // RGBA8
10480                         if (n_bits_for_channel_0 == 8 && n_bits_for_channel_1 == 8 && n_bits_for_channel_2 == 8 &&
10481                             n_bits_for_channel_3 == 8)
10482                         {
10483                             *result_traveller = channels[0]->unsigned_byte_data;
10484                             result_traveller++;
10485                             *result_traveller = channels[1]->unsigned_byte_data;
10486                             result_traveller++;
10487                             *result_traveller = channels[2]->unsigned_byte_data;
10488                             result_traveller++;
10489                             *result_traveller = channels[3]->unsigned_byte_data;
10490                             result_traveller++;
10491                         }
10492                         else
10493                             // RGB5A1
10494                             if (n_bits_for_channel_0 == 5 && n_bits_for_channel_1 == 5 && n_bits_for_channel_2 == 5 &&
10495                                 n_bits_for_channel_3 == 1)
10496                             {
10497                                 unsigned short *result_traveller16 = (unsigned short *)result_traveller;
10498 
10499                                 *result_traveller16 =
10500                                     (channels[0]->unsigned_byte_data << 11) + (channels[1]->unsigned_byte_data << 6) +
10501                                     (channels[2]->unsigned_byte_data << 1) + channels[3]->unsigned_byte_data;
10502 
10503                                 result_traveller += 2;
10504                             }
10505                             else
10506                                 // RGB10A2_REV
10507                                 if (n_bits_for_channel_0 == 2 && n_bits_for_channel_1 == 10 &&
10508                                     n_bits_for_channel_2 == 10 && n_bits_for_channel_3 == 10)
10509                                 {
10510                                     unsigned int *result_traveller32 = (unsigned int *)result_traveller;
10511 
10512                                     DE_ASSERT(channels[0]->data_type == CHANNEL_DATA_TYPE_UNSIGNED_BYTE_2BITS);
10513                                     DE_ASSERT(channels[1]->data_type == CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS);
10514                                     DE_ASSERT(channels[2]->data_type == CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS);
10515                                     DE_ASSERT(channels[3]->data_type == CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS);
10516 
10517                                     *result_traveller32 = (channels[0]->unsigned_byte_data << 30) +
10518                                                           (channels[1]->unsigned_short_data << 20) +
10519                                                           (channels[2]->unsigned_short_data << 10) +
10520                                                           channels[3]->unsigned_short_data;
10521 
10522                                     result_traveller += 4;
10523                                 }
10524                                 else
10525                                 {
10526                                     // Unsupported bit layout
10527                                     DE_ASSERT(0);
10528                                     return false;
10529                                 }
10530         }
10531         else if (channels[0] != NULL && channels[1] != NULL && channels[2] != NULL)
10532         {
10533             // RGB32
10534             if ((type == GL_HALF_FLOAT) ||
10535                 ((n_bits_for_channel_0 == 32) && (n_bits_for_channel_1 == 32) && (n_bits_for_channel_2 == 32)))
10536             {
10537                 unsigned int *result_traveller32 = (unsigned int *)result_traveller;
10538 
10539                 *result_traveller32 = channels[0]->unsigned_integer_data;
10540                 result_traveller32++;
10541                 *result_traveller32 = channels[1]->unsigned_integer_data;
10542                 result_traveller32++;
10543                 *result_traveller32 = channels[2]->unsigned_integer_data;
10544 
10545                 result_traveller += 3 * 4;
10546             }
10547             else
10548                 // RGB8
10549                 if (n_bits_for_channel_0 == 8 && n_bits_for_channel_1 == 8 && n_bits_for_channel_2 == 8)
10550                 {
10551                     *result_traveller = channels[0]->unsigned_byte_data;
10552                     result_traveller++;
10553                     *result_traveller = channels[1]->unsigned_byte_data;
10554                     result_traveller++;
10555                     *result_traveller = channels[2]->unsigned_byte_data;
10556                     result_traveller++;
10557                 }
10558                 else
10559                     // RGB565
10560                     if (n_bits_for_channel_0 == 5 && n_bits_for_channel_1 == 6 && n_bits_for_channel_2 == 5)
10561                     {
10562                         unsigned short *result_traveller16 = (unsigned short *)result_traveller;
10563 
10564                         *result_traveller16 = (channels[0]->unsigned_byte_data << 11) +
10565                                               (channels[1]->unsigned_byte_data << 5) +
10566                                               (channels[2]->unsigned_byte_data);
10567 
10568                         result_traveller += 2;
10569                     }
10570                     else
10571                     {
10572                         // Unsupported bit layout
10573                         DE_ASSERT(0);
10574                         return false;
10575                     }
10576         }
10577         else if (channels[0] != NULL && channels[1] != NULL)
10578         {
10579             // RG32
10580             if ((type == GL_HALF_FLOAT) || ((n_bits_for_channel_0 == 32) && (n_bits_for_channel_1 == 32)))
10581             {
10582                 unsigned int *result_traveller32 = (unsigned int *)result_traveller;
10583 
10584                 *result_traveller32 = channels[0]->unsigned_integer_data;
10585                 result_traveller32++;
10586                 *result_traveller32 = channels[1]->unsigned_integer_data;
10587 
10588                 result_traveller += 8;
10589             }
10590             else
10591                 // RG16
10592                 if (n_bits_for_channel_0 == 16 && n_bits_for_channel_1 == 16)
10593                 {
10594                     unsigned short *result_traveller16 = (unsigned short *)result_traveller;
10595 
10596                     *result_traveller16 = channels[0]->unsigned_short_data;
10597                     result_traveller16++;
10598                     *result_traveller16 = channels[1]->unsigned_short_data;
10599 
10600                     result_traveller += 4;
10601                 }
10602                 else
10603                     // RG8
10604                     if (n_bits_for_channel_0 == 8 && n_bits_for_channel_1 == 8)
10605                     {
10606                         *result_traveller = channels[0]->unsigned_byte_data;
10607                         result_traveller++;
10608                         *result_traveller = channels[1]->unsigned_byte_data;
10609                         result_traveller++;
10610                     }
10611                     else
10612                     {
10613                         // Unsupported bit layout
10614                         DE_ASSERT(0);
10615                         return false;
10616                     }
10617         }
10618         else if (channels[0] != NULL)
10619         {
10620             // R32
10621             if (type == GL_HALF_FLOAT || n_bits_for_channel_0 == 32)
10622             {
10623                 unsigned int *result_traveller32 = (unsigned int *)result_traveller;
10624 
10625                 *result_traveller32 = channels[0]->unsigned_integer_data;
10626                 result_traveller += 4;
10627             }
10628             else
10629                 // R16
10630                 if (n_bits_for_channel_0 == 16)
10631                 {
10632                     unsigned short *result_traveller16 = (unsigned short *)result_traveller;
10633 
10634                     *result_traveller16 = channels[0]->unsigned_short_data;
10635                     result_traveller += 2;
10636                 }
10637                 else
10638                     // R8
10639                     if (n_bits_for_channel_0 == 8)
10640                     {
10641                         *result_traveller = channels[0]->unsigned_byte_data;
10642                         result_traveller++;
10643                     }
10644                     else
10645                     {
10646                         // Unsupported bit layout
10647                         DE_ASSERT(0);
10648                         return false;
10649                     }
10650         }
10651         else
10652         {
10653             // Unrecognized channel data layout.
10654             DE_ASSERT(0);
10655             return false;
10656         }
10657     } // for (all pixels)
10658 
10659     return true;
10660 }
10661 
10662 /** Retrieves number of bits used for a single channel, were it stored in
10663  *  @param channel_data_type internal channel data type.
10664  *
10665  *  @param channel_data_type Channel data type to consider.
10666  *  @param out_n_bits        Deref will be used to store the amount of bits.
10667  *                           Cannot be NULL.
10668  *
10669  *  @return GTFtrue if successful, GTFfalse otherwise.
10670  **/
getNumberOfBitsForChannelDataType(ChannelDataType channel_data_type,int * out_n_bits)10671 bool RequiredCase::getNumberOfBitsForChannelDataType(ChannelDataType channel_data_type, int *out_n_bits)
10672 {
10673     DE_ASSERT(out_n_bits != NULL);
10674     switch (channel_data_type)
10675     {
10676     case CHANNEL_DATA_TYPE_SIGNED_BYTE_8BITS:
10677         *out_n_bits = 8;
10678         return true;
10679 
10680     case CHANNEL_DATA_TYPE_SIGNED_INTEGER_32BITS:
10681         *out_n_bits = 32;
10682         return true;
10683 
10684     case CHANNEL_DATA_TYPE_SIGNED_SHORT_16BITS:
10685         *out_n_bits = 16;
10686         return true;
10687 
10688     case CHANNEL_DATA_TYPE_UNSIGNED_BYTE_1BIT:
10689         *out_n_bits = 1;
10690         return true;
10691 
10692     case CHANNEL_DATA_TYPE_UNSIGNED_BYTE_2BITS:
10693         *out_n_bits = 2;
10694         return true;
10695 
10696     case CHANNEL_DATA_TYPE_UNSIGNED_BYTE_4BITS:
10697         *out_n_bits = 4;
10698         return true;
10699 
10700     case CHANNEL_DATA_TYPE_UNSIGNED_BYTE_5BITS:
10701         *out_n_bits = 5;
10702         return true;
10703 
10704     case CHANNEL_DATA_TYPE_UNSIGNED_BYTE_6BITS:
10705         *out_n_bits = 6;
10706         return true;
10707 
10708     case CHANNEL_DATA_TYPE_UNSIGNED_BYTE_8BITS:
10709         *out_n_bits = 8;
10710         return true;
10711 
10712     case CHANNEL_DATA_TYPE_UNSIGNED_INTEGER_32BITS:
10713         *out_n_bits = 32;
10714         return true;
10715 
10716     case CHANNEL_DATA_TYPE_UNSIGNED_SHORT_10BITS:
10717         *out_n_bits = 10;
10718         return true;
10719 
10720     case CHANNEL_DATA_TYPE_UNSIGNED_SHORT_16BITS:
10721         *out_n_bits = 16;
10722         return true;
10723 
10724     case CHANNEL_DATA_TYPE_FLOAT:
10725         *out_n_bits = 32;
10726         return true;
10727 
10728     case CHANNEL_DATA_TYPE_NONE:
10729         return true;
10730     }
10731 
10732     // Unrecognized channel data type
10733     DE_ASSERT(0);
10734     return false;
10735 }
10736 
10737 /** Retrieves information on channel order for user-specified internal format+type
10738  *  combination.
10739  *
10740  *  @param internalformat    GLES internal format to consider.
10741  *  @param type              GLES type to consider.
10742  *  @param out_channel_order Deref will be used to store requested information.
10743  *                           Cannot be NULL.
10744  *
10745  *  @return GTFtrue if successful, GTFfalse otherwise.
10746  **/
getChannelOrderForInternalformatAndType(GLenum internalformat,GLenum type,ChannelOrder * out_channel_order)10747 bool RequiredCase::getChannelOrderForInternalformatAndType(GLenum internalformat, GLenum type,
10748                                                            ChannelOrder *out_channel_order)
10749 {
10750     GLenum format = GL_NONE;
10751     DE_ASSERT(out_channel_order != NULL);
10752 
10753     // Determine the order
10754     if (!getFormatForInternalformat(internalformat, &format))
10755     {
10756         DE_ASSERT(0);
10757         return false;
10758     }
10759 
10760     switch (format)
10761     {
10762     case GL_RED:
10763     case GL_RED_INTEGER:
10764         // Only one order is sane
10765         *out_channel_order = CHANNEL_ORDER_R;
10766         return true;
10767 
10768     case GL_RG:
10769     case GL_RG_INTEGER:
10770         // Only one order is sane
10771         *out_channel_order = CHANNEL_ORDER_RG;
10772         return true;
10773 
10774     case GL_RGB:
10775     case GL_RGB_INTEGER:
10776         // Two options here
10777         if (type == GL_UNSIGNED_INT_10F_11F_11F_REV || type == GL_UNSIGNED_INT_5_9_9_9_REV)
10778             *out_channel_order = CHANNEL_ORDER_BGR;
10779         else
10780             *out_channel_order = CHANNEL_ORDER_RGB;
10781         return true;
10782 
10783     case GL_RGBA:
10784     case GL_RGBA_INTEGER:
10785         // Two options here
10786         if (type == GL_UNSIGNED_INT_2_10_10_10_REV)
10787             *out_channel_order = CHANNEL_ORDER_ABGR;
10788         else
10789             *out_channel_order = CHANNEL_ORDER_RGBA;
10790         return true;
10791 
10792     default:
10793         // Unrecognized format?
10794         DE_ASSERT(0);
10795         return false;
10796     }
10797 
10798     return false;
10799 }
10800 
10801 /** Creates objects required to support non color-renderable internalformats of texture objects.
10802  * There are different objects created for each combination of float/integer/unsigned integer internalformats
10803  * of source and destination texture objects created.
10804  *
10805  * @param f_src_f_dst_internalformat_ptr    Deref will be used to store created object IDs for
10806  *                                          float source and float destination texture object.
10807  *                                          Cannot be NULL.
10808  * @param i_src_i_dst_internalformat_ptr    Deref will be used to store created object IDs for
10809  *                                          integer source and integer destination texture object.
10810  *                                          Cannot be NULL.
10811  * @param ui_src_ui_dst_internalformat_ptr  Deref will be used to store created object IDs for
10812  *                                          unsigned integer source and unsigned integer destination texture object.
10813  *                                          Cannot be NULL.
10814  * @param source_attachment_type            Tells what GL object (or which texture target)
10815  *                                          should be used as a read buffer for a glCopyTexImage2D call.
10816  * @param destination_attachment_type       Tells which texture target should be used for
10817  *                                          a glCopyTexImage2D() call.
10818  *
10819  * @return true if successful, false otherwise.
10820  */
generateObjectsToSupportNonColorRenderableInternalformats()10821 bool RequiredCase::generateObjectsToSupportNonColorRenderableInternalformats()
10822 {
10823     // if (failed to prepare objects for float->float shader-based checks)
10824     if (!prepareSupportForNonRenderableTexture(m_f_src_f_dst_internalformat, DATA_SAMPLER_FLOAT, DATA_SAMPLER_FLOAT,
10825                                                m_source_attachment_type, m_destination_attachment_type))
10826     {
10827         return false;
10828     }
10829 
10830     // if (failed to prepare objects for int->int shader-based checks)
10831     if (!prepareSupportForNonRenderableTexture(m_i_src_i_dst_internalformat, DATA_SAMPLER_INTEGER, DATA_SAMPLER_INTEGER,
10832                                                m_source_attachment_type, m_destination_attachment_type))
10833     {
10834         return false;
10835     }
10836 
10837     // if (failed to prepare objects for uint->uint shader-based checks)
10838     if (!prepareSupportForNonRenderableTexture(m_ui_src_ui_dst_internalformat, DATA_SAMPLER_UNSIGNED_INTEGER,
10839                                                DATA_SAMPLER_UNSIGNED_INTEGER, m_source_attachment_type,
10840                                                m_destination_attachment_type))
10841     {
10842         return false;
10843     }
10844 
10845     return true;
10846 }
10847 
10848 /** Creates and prepares buffer and program objects to be used for non-renderable texture support.
10849  * In case the destination texture's internalformat is not renderable,
10850  * glReadPixels() cannot be issued to retrieve texture object data.
10851  * Instead, a program object is used to retrieve and compare source and destination texture data.
10852  * This function creates and prepares all objects needed to support this approach.
10853  *
10854  * @param objects_ptr                 Deref will be used for storing generated object ids. Cannot be NULL.
10855  * @param src_texture_sampler_type    Type of the sampler to be used for sampling source texture (float/int/uint).
10856  * @param dst_texture_sampler_type    Type of the sampler to be used for sampling destination texture (float/int/uint).
10857  * @param source_attachment_type
10858  * @param destination_attachment_type
10859  *
10860  * @return true if the operation succeeded (no error was generated),
10861  *         false otherwise.
10862  */
prepareSupportForNonRenderableTexture(NonRenderableInternalformatSupportObjects & objects,DataSamplerType src_texture_sampler_type,DataSamplerType dst_texture_sampler_type,GLenum source_attachment_type,GLenum destination_attachment_type)10863 bool RequiredCase::prepareSupportForNonRenderableTexture(NonRenderableInternalformatSupportObjects &objects,
10864                                                          DataSamplerType src_texture_sampler_type,
10865                                                          DataSamplerType dst_texture_sampler_type,
10866                                                          GLenum source_attachment_type,
10867                                                          GLenum destination_attachment_type)
10868 {
10869     glu::RenderContext &renderContext = m_context.getRenderContext();
10870     const Functions &gl               = renderContext.getFunctions();
10871 
10872     const GLuint compare_result_size    = NUMBER_OF_POINTS_TO_DRAW * sizeof(GLint);
10873     GLuint destination_buffer_data_size = 0;
10874     GLuint source_buffer_data_size      = 0;
10875     const GLchar *varying_names[]       = {"compare_result", "src_texture_pixel_values", "dst_texture_pixel_values"};
10876     const GLsizei varying_names_count   = DE_LENGTH_OF_ARRAY(varying_names);
10877 
10878     // Create program and shader objects.
10879     objects.program_object_id         = gl.createProgram();
10880     objects.fragment_shader_object_id = gl.createShader(GL_FRAGMENT_SHADER);
10881     objects.vertex_shader_object_id   = gl.createShader(GL_VERTEX_SHADER);
10882 
10883     // Generate buffer and transform feedback objects.
10884     gl.genTransformFeedbacks(1, &objects.transform_feedback_object_id);
10885     gl.genBuffers(1, &objects.comparison_result_buffer_object_id);
10886     gl.genBuffers(1, &objects.src_texture_pixels_buffer_object_id);
10887     gl.genBuffers(1, &objects.dst_texture_pixels_buffer_object_id);
10888     gl.genBuffers(1, &objects.src_texture_coordinates_buffer_object_id);
10889     gl.genBuffers(1, &objects.dst_texture_coordinates_buffer_object_id);
10890 
10891     // Calculate texture data size depending on source and destination sampler types.
10892     if (!calculateBufferDataSize(src_texture_sampler_type, &source_buffer_data_size))
10893         return false;
10894     if (!calculateBufferDataSize(dst_texture_sampler_type, &destination_buffer_data_size))
10895         return false;
10896 
10897     // Initialize buffer objects storage.
10898     gl.bindBuffer(GL_ARRAY_BUFFER, objects.comparison_result_buffer_object_id);
10899     gl.bufferData(GL_ARRAY_BUFFER, compare_result_size, NULL, GL_STATIC_DRAW);
10900     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
10901 
10902     gl.bindBuffer(GL_ARRAY_BUFFER, objects.src_texture_pixels_buffer_object_id);
10903     gl.bufferData(GL_ARRAY_BUFFER, source_buffer_data_size, NULL, GL_STATIC_DRAW);
10904     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
10905 
10906     gl.bindBuffer(GL_ARRAY_BUFFER, objects.dst_texture_pixels_buffer_object_id);
10907     gl.bufferData(GL_ARRAY_BUFFER, destination_buffer_data_size, NULL, GL_STATIC_DRAW);
10908     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
10909 
10910     // Initialize texture coordinates
10911     gl.bindBuffer(GL_ARRAY_BUFFER, objects.src_texture_coordinates_buffer_object_id);
10912     gl.bufferData(GL_ARRAY_BUFFER, TEXTURE_COORDINATES_ARRAY_SIZE, getTexCoordinates(source_attachment_type),
10913                   GL_STATIC_DRAW);
10914     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
10915 
10916     gl.vertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
10917     GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
10918 
10919     gl.bindBuffer(GL_ARRAY_BUFFER, objects.dst_texture_coordinates_buffer_object_id);
10920     gl.bufferData(GL_ARRAY_BUFFER, TEXTURE_COORDINATES_ARRAY_SIZE, getTexCoordinates(destination_attachment_type),
10921                   GL_STATIC_DRAW);
10922     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
10923 
10924     gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
10925     GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
10926 
10927     gl.bindBuffer(GL_ARRAY_BUFFER, 0);
10928 
10929     // Bind buffer objects to GL_TRANSFORM_FEEDBACK target at specific indices.
10930     gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, COMPARISON_RESULT_BUFFER_OBJECT_INDEX,
10931                        objects.comparison_result_buffer_object_id, 0, compare_result_size);
10932     gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, SOURCE_TEXTURE_PIXELS_BUFFER_OBJECT_INDEX,
10933                        objects.src_texture_pixels_buffer_object_id, 0, source_buffer_data_size);
10934     gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, DESTINATION_TEXTURE_PIXELS_BUFFER_OBJECT_INDEX,
10935                        objects.dst_texture_pixels_buffer_object_id, 0, destination_buffer_data_size);
10936 
10937     // Specify values for transform feedback.
10938     gl.transformFeedbackVaryings(objects.program_object_id, varying_names_count, varying_names, GL_SEPARATE_ATTRIBS);
10939     GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings");
10940 
10941     // Prepare program and shader objects.
10942     if (!prepareProgramAndShaderObjectsToSupportNonRenderableTexture(
10943             objects.program_object_id, objects.fragment_shader_object_id, objects.vertex_shader_object_id,
10944             src_texture_sampler_type, dst_texture_sampler_type))
10945     {
10946         return false;
10947     }
10948 
10949     // Retrieve uniform locations.
10950     if (!getUniformLocations(objects.program_object_id, &objects.src_2D_texture_uniform_location,
10951                              &objects.src_2DArray_texture_uniform_location, &objects.src_3D_texture_uniform_location,
10952                              &objects.src_Cube_texture_uniform_location, &objects.dst_2D_texture_uniform_location,
10953                              &objects.dst_Cube_texture_uniform_location, &objects.channels_to_compare_uniform_location,
10954                              &objects.samplers_to_use_uniform_location))
10955     {
10956         return false;
10957     }
10958 
10959     return true;
10960 }
10961 
10962 /** Calculate size needed for texture object data storage to successfully
10963  *  capture all the data needed.
10964  *  For simplicity, we assume all internalformats of our concern use four
10965  *  components. It's not a dreadful waste of memory, given amount of data
10966  *  we will be checking for later on anyway.
10967  *
10968  * @param _data_sampler_type     Type of the sampler used to read the data.
10969  * @param texture_data_size_ptr  Deref will be used to stored calculated result.
10970  *                               Cannot be NULL.
10971  *
10972  * @return true if successful, false otherwise.
10973  */
calculateBufferDataSize(DataSamplerType sampler_type,GLuint * buffer_data_size_ptr)10974 bool RequiredCase::calculateBufferDataSize(DataSamplerType sampler_type, GLuint *buffer_data_size_ptr)
10975 {
10976     if (buffer_data_size_ptr == NULL)
10977     {
10978         m_testCtx.getLog() << tcu::TestLog::Message << "NULL pointer passed as a deref to store calculated result."
10979                            << tcu::TestLog::EndMessage;
10980         return false;
10981     }
10982 
10983     switch (sampler_type)
10984     {
10985     case DATA_SAMPLER_FLOAT:
10986         *buffer_data_size_ptr = NUMBER_OF_POINTS_TO_DRAW * NUMBER_OF_ELEMENTS_IN_VEC4 * sizeof(GLfloat);
10987         return true;
10988 
10989     case DATA_SAMPLER_INTEGER:
10990         *buffer_data_size_ptr = NUMBER_OF_POINTS_TO_DRAW * NUMBER_OF_ELEMENTS_IN_VEC4 * sizeof(GLint);
10991         return true;
10992 
10993     case DATA_SAMPLER_UNSIGNED_INTEGER:
10994         *buffer_data_size_ptr = NUMBER_OF_POINTS_TO_DRAW * NUMBER_OF_ELEMENTS_IN_VEC4 * sizeof(GLuint);
10995         return true;
10996 
10997     default:
10998         m_testCtx.getLog() << tcu::TestLog::Message << "Unrecognized data sampler type." << tcu::TestLog::EndMessage;
10999         return false;
11000     }
11001 
11002     return true;
11003 }
11004 
11005 /** Texture coordinates to use when glReadPixels can't be used to read back the data.
11006  *  Different coordinates for different attachment types.
11007  *
11008  *  @param attachment_type Texture attachment type
11009  *
11010  *  @return Array of 4 3-tuples of texture coordinates to use
11011  */
getTexCoordinates(GLenum attachment_type) const11012 const float *RequiredCase::getTexCoordinates(GLenum attachment_type) const
11013 {
11014     static const float texture_coordinates[7][NUMBER_OF_POINTS_TO_DRAW * 4] = {
11015         // 2D texture, 3D texture and 2D array
11016         {0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0},
11017         // Cube Map NEGATIVE_X
11018         {-1, .99f, -.99f, 0, -1, .99f, .99f, 0, -1, -.99f, .99f, 0, -1, -.99f, -.99f, 0},
11019         // Cube Map NEGATIVE_Y
11020         {-.99f, -1, .99f, 0, .99f, -1, .99f, 0, .99f, -1, -.99f, 0, -.99f, -1, -.99f, 0},
11021         // Cube Map NEGATIVE_Z
11022         {.99f, .99f, -1, 0, -.99f, .99f, -1, 0, -.99f, -.99f, -1, 0, .99f, -.99f, -1, 0},
11023         // Cube Map POSITIVE_X
11024         {1, .99f, .99f, 0, 1, .99f, -.99f, 0, 1, -.99f, -.99f, 0, 1, -.99f, .99f, 0},
11025         // Cube Map POSITIVE_Y
11026         {-.99f, 1, -.99f, 0, .99f, 1, -.99f, 0, .99f, 1, .99f, 0, -.99f, 1, .99f, 0},
11027         // Cube Map POSITIVE_Z
11028         {-.99f, .99f, 1, 0, .99f, .99f, 1, 0, .99f, -.99f, 1, 0, -.99f, -.99f, 1, 0},
11029     };
11030 
11031     switch (attachment_type)
11032     {
11033     case GL_TEXTURE_2D:
11034     case GL_TEXTURE_2D_ARRAY:
11035     case GL_TEXTURE_3D:
11036         return texture_coordinates[0];
11037     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
11038         return texture_coordinates[1];
11039     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
11040         return texture_coordinates[2];
11041     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
11042         return texture_coordinates[3];
11043     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
11044         return texture_coordinates[4];
11045     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
11046         return texture_coordinates[5];
11047     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
11048         return texture_coordinates[6];
11049     default:
11050         DE_ASSERT(!"Invalid attachment type!");
11051         return NULL;
11052     }
11053 }
11054 
11055 /** Sets source for shader objects, compiles them and attaches to program object.
11056  * Program object can be used to verify whether copying texture image works correctly if
11057  * non-renderable internalformats are considered.
11058  * If all the operations succeeded, the program object is activated.
11059  *
11060  * @param program_object_id         ID of a program object to be initialized.
11061  *                                  The value must be a valid program object ID.
11062  * @param fragment_shader_object_id ID of a fragment shader object to be initialized.
11063  *                                  The value must be a valid fragment shader object ID.
11064  * @param vertex_shader_object_id   ID of a vertex shader object to be initialized.
11065  *                                  The value must be a valid vertex shader object ID.
11066  * @param src_texture_sampler_type  Sampler to be used for sampling source texture object.
11067  * @param dst_texture_sampler_type  Sampler to be used for sampling destination texture object.
11068  *
11069  * @return true if the operation succeeded, false otherwise.
11070  */
prepareProgramAndShaderObjectsToSupportNonRenderableTexture(GLuint program_object_id,GLuint fragment_shader_object_id,GLuint vertex_shader_object_id,DataSamplerType src_texture_sampler_type,DataSamplerType dst_texture_sampler_type)11071 bool RequiredCase::prepareProgramAndShaderObjectsToSupportNonRenderableTexture(GLuint program_object_id,
11072                                                                                GLuint fragment_shader_object_id,
11073                                                                                GLuint vertex_shader_object_id,
11074                                                                                DataSamplerType src_texture_sampler_type,
11075                                                                                DataSamplerType dst_texture_sampler_type)
11076 {
11077     glu::RenderContext &renderContext = m_context.getRenderContext();
11078     const Functions &gl               = renderContext.getFunctions();
11079 
11080     // Attach shader objects to program object.
11081     gl.attachShader(program_object_id, fragment_shader_object_id);
11082     gl.attachShader(program_object_id, vertex_shader_object_id);
11083     GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader");
11084 
11085     if (!setSourceForShaderObjectsUsedForNonRenderableTextureSupport(
11086             fragment_shader_object_id, vertex_shader_object_id, src_texture_sampler_type, dst_texture_sampler_type))
11087     {
11088         return false;
11089     }
11090 
11091     if (!compileAndCheckShaderCompilationStatus(fragment_shader_object_id))
11092         return false;
11093 
11094     if (!compileAndCheckShaderCompilationStatus(vertex_shader_object_id))
11095         return false;
11096 
11097     if (!linkAndCheckProgramLinkStatus(program_object_id))
11098         return false;
11099 
11100     return true;
11101 }
11102 
11103 /** Assigns source code to fragment/vertex shaders which will then be used to verify texture data..
11104  *
11105  * @param fragment_shader_object_id ID of an already created fragment shader.
11106  * @param vertex_shader_object_id   ID of an already created vertex shader.
11107  * @param src_texture_sampler_type  Type of sampler to be used for sampling source texture object (float/int/uint).
11108  * @param dst_texture_sampler_type  Type of sampler to be used for sampling destination texture object (float/int/uint).
11109  *
11110  * @return true if successful, false otherwise.
11111  */
setSourceForShaderObjectsUsedForNonRenderableTextureSupport(GLuint fragment_shader_object_id,GLuint vertex_shader_object_id,DataSamplerType src_texture_sampler_type,DataSamplerType dst_texture_sampler_type)11112 bool RequiredCase::setSourceForShaderObjectsUsedForNonRenderableTextureSupport(GLuint fragment_shader_object_id,
11113                                                                                GLuint vertex_shader_object_id,
11114                                                                                DataSamplerType src_texture_sampler_type,
11115                                                                                DataSamplerType dst_texture_sampler_type)
11116 {
11117     glu::RenderContext &renderContext = m_context.getRenderContext();
11118     const Functions &gl               = renderContext.getFunctions();
11119 
11120     std::map<std::string, std::string> specializationMap;
11121 
11122     const GLchar *fragment_shader_source = {"#version 300 es\n"
11123                                             "void main()\n"
11124                                             "{}\n"};
11125     static std::string shader_source[3];
11126     const GLchar *vertex_shader_source = NULL;
11127     const GLchar *source               = "#version 300 es\n"
11128                                          "\n"
11129                                          "     uniform highp ${SAMPLER_PREFIX}sampler2D      dst_texture2D;\n"
11130                                          "     uniform highp ${SAMPLER_PREFIX}samplerCube    dst_textureCube;\n"
11131                                          "     uniform highp ${SAMPLER_PREFIX}sampler2D      src_texture2D;\n"
11132                                          "     uniform highp ${SAMPLER_PREFIX}sampler3D      src_texture3D;\n"
11133                                          "     uniform highp ${SAMPLER_PREFIX}sampler2DArray src_texture2DArray;\n"
11134                                          "     uniform highp ${SAMPLER_PREFIX}samplerCube    src_textureCube;\n"
11135                                          "     uniform int              channels_to_compare;\n"
11136                                          "     uniform int              samplers_to_use;\n"
11137                                          "layout(location = 0) in vec4  dst_texture_coord;\n"
11138                                          "layout(location = 1) in vec4  src_texture_coord;\n"
11139                                          "${OUT_QUALIFIER}   out     ${OUT_TYPE}           dst_texture_pixel_values;\n"
11140                                          "${OUT_QUALIFIER}   out     ${OUT_TYPE}           src_texture_pixel_values;\n"
11141                                          "flat out     int              compare_result;\n"
11142                                          "\n"
11143                                          "void main()\n"
11144                                          "{\n"
11145                                          "    ${OUT_TYPE}      src_texture_data;\n"
11146                                          "    ${OUT_TYPE}      dst_texture_data;\n"
11147                                          "    const ${EPSILON_TYPE}    epsilon          = ${EPSILON_VALUE};\n"
11148                                          "    int         result           = 1;\n"
11149                                          "    bool        compare_red      = (channels_to_compare & 0x1) != 0;\n"
11150                                          "    bool        compare_green = (channels_to_compare & 0x2) != 0;\n"
11151                                          "    bool        compare_blue     = (channels_to_compare & 0x4) != 0;\n"
11152                                          "    bool        compare_alpha = (channels_to_compare & 0x8) != 0;\n"
11153                                          "    int         src_sampler      = samplers_to_use & 0xff;\n"
11154                                          "    int         dst_sampler      = samplers_to_use >> 8;\n"
11155                                          "\n"
11156                                          "    if (src_sampler == 0)\n"
11157                                          "    {\n"
11158                                          "        src_texture_data = texture(src_texture2D, src_texture_coord.xy);\n"
11159                                          "    }\n"
11160                                          "    else if (src_sampler == 1)\n"
11161                                          "    {\n"
11162                                          "        src_texture_data = texture(src_texture3D, src_texture_coord.xyz);\n"
11163                                          "    }\n"
11164                                          "    else if (src_sampler == 2)\n"
11165                                          "    {\n"
11166                                          "        src_texture_data = texture(src_texture2DArray, src_texture_coord.xyz);\n"
11167                                          "    }\n"
11168                                          "    else\n"
11169                                          "    {\n"
11170                                          "        src_texture_data = texture(src_textureCube, src_texture_coord.xyz);\n"
11171                                          "    }\n"
11172                                          "\n"
11173                                          "    if (dst_sampler == 0)\n"
11174                                          "    {\n"
11175                                          "        dst_texture_data = texture(dst_texture2D, dst_texture_coord.xy);\n"
11176                                          "    }\n"
11177                                          "    else\n"
11178                                          "    {\n"
11179                                          "        dst_texture_data = texture(dst_textureCube, dst_texture_coord.xyz);\n"
11180                                          "    }\n"
11181                                          "\n"
11182                                          "    if (compare_red && ${FN}(src_texture_data.x - dst_texture_data.x) > epsilon)\n"
11183                                          "    {\n"
11184                                          "        result = 0;\n"
11185                                          "    }\n"
11186                                          "    if (compare_green && ${FN}(src_texture_data.y - dst_texture_data.y) > epsilon)\n"
11187                                          "    {\n"
11188                                          "        result = 0;\n"
11189                                          "    }\n"
11190                                          "    if (compare_blue && ${FN}(src_texture_data.z - dst_texture_data.z) > epsilon)\n"
11191                                          "    {\n"
11192                                          "        result = 0;\n"
11193                                          "    }\n"
11194                                          "    if (compare_alpha && ${FN}(src_texture_data.w - dst_texture_data.w) > epsilon)\n"
11195                                          "    {\n"
11196                                          "        result = 0;\n"
11197                                          "    }\n"
11198                                          "\n"
11199                                          "    compare_result           = result;\n"
11200                                          "    dst_texture_pixel_values = dst_texture_data;\n"
11201                                          "    src_texture_pixel_values = src_texture_data;\n"
11202                                          "}\n";
11203 
11204     switch (src_texture_sampler_type)
11205     {
11206     case DATA_SAMPLER_FLOAT:
11207     {
11208         switch (dst_texture_sampler_type)
11209         {
11210         case DATA_SAMPLER_FLOAT:
11211         {
11212             specializationMap["SAMPLER_PREFIX"] = "  ";
11213             specializationMap["OUT_QUALIFIER"]  = "  ";
11214             specializationMap["OUT_TYPE"]       = "  vec4";
11215             specializationMap["EPSILON_TYPE"]   = "float";
11216             specializationMap["EPSILON_VALUE"]  = "(1.0/255.0)";
11217             specializationMap["FN"]             = "abs";
11218             shader_source[0]                    = tcu::StringTemplate(source).specialize(specializationMap);
11219 
11220             vertex_shader_source = shader_source[0].c_str();
11221             break;
11222         }
11223 
11224         default:
11225         {
11226             m_testCtx.getLog() << tcu::TestLog::Message << "Unrecognized sampler type for destination texture object."
11227                                << tcu::TestLog::EndMessage;
11228             return false;
11229         }
11230         }
11231 
11232         break;
11233     }
11234 
11235     case DATA_SAMPLER_INTEGER:
11236     {
11237         switch (dst_texture_sampler_type)
11238         {
11239         case DATA_SAMPLER_INTEGER:
11240         {
11241             specializationMap["SAMPLER_PREFIX"] = "i";
11242             specializationMap["OUT_QUALIFIER"]  = "flat";
11243             specializationMap["OUT_TYPE"]       = "ivec4";
11244             specializationMap["EPSILON_TYPE"]   = "int";
11245             specializationMap["EPSILON_VALUE"]  = "0";
11246             specializationMap["FN"]             = "abs";
11247 
11248             shader_source[1]     = tcu::StringTemplate(source).specialize(specializationMap);
11249             vertex_shader_source = shader_source[1].c_str();
11250             break;
11251         }
11252 
11253         default:
11254         {
11255             m_testCtx.getLog() << tcu::TestLog::Message
11256                                << "Unrecognized type of internalformat of destination texture object."
11257                                << tcu::TestLog::EndMessage;
11258             return false;
11259         }
11260         }
11261 
11262         break;
11263     }
11264 
11265     case DATA_SAMPLER_UNSIGNED_INTEGER:
11266     {
11267         switch (dst_texture_sampler_type)
11268         {
11269         case DATA_SAMPLER_UNSIGNED_INTEGER:
11270         {
11271             specializationMap["SAMPLER_PREFIX"] = "u";
11272             specializationMap["OUT_QUALIFIER"]  = "flat";
11273             specializationMap["OUT_TYPE"]       = "uvec4";
11274             specializationMap["EPSILON_TYPE"]   = "uint";
11275             specializationMap["EPSILON_VALUE"]  = "0u";
11276             specializationMap["FN"]             = "";
11277 
11278             shader_source[2]     = tcu::StringTemplate(source).specialize(specializationMap);
11279             vertex_shader_source = shader_source[2].c_str();
11280             break;
11281         }
11282 
11283         default:
11284         {
11285             m_testCtx.getLog() << tcu::TestLog::Message
11286                                << "Unrecognized type of internalformat of destination texture object."
11287                                << tcu::TestLog::EndMessage;
11288             return false;
11289         }
11290         }
11291 
11292         break;
11293     }
11294 
11295     default:
11296     {
11297         m_testCtx.getLog() << tcu::TestLog::Message << "Unrecognized type of internalformat of source texture object."
11298                            << tcu::TestLog::EndMessage;
11299         return false;
11300     }
11301     }
11302 
11303     // Set shader source for fragment shader object.
11304     gl.shaderSource(fragment_shader_object_id, 1 /* part */, &fragment_shader_source, NULL);
11305     GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource");
11306 
11307     // Set shader source for vertex shader object.
11308     gl.shaderSource(vertex_shader_object_id, 1 /* part */, &vertex_shader_source, NULL);
11309     GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource");
11310 
11311     return true;
11312 }
11313 
11314 /** Compiles a shader object and returns compilation status.
11315  *
11316  * @param shader_object_id ID of a shader object to be compiled.
11317  *
11318  * @return true in case operation succeeded (no error was generated and compilation was successful),
11319  *         false otherwise.
11320  */
compileAndCheckShaderCompilationStatus(GLuint shader_object_id)11321 bool RequiredCase::compileAndCheckShaderCompilationStatus(GLuint shader_object_id)
11322 {
11323     glu::RenderContext &renderContext = m_context.getRenderContext();
11324     const Functions &gl               = renderContext.getFunctions();
11325 
11326     // Compile shader object.
11327     gl.compileShader(shader_object_id);
11328     GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader");
11329 
11330     // Check if compilation was successful.
11331     GLint shader_compile_status = GL_FALSE;
11332     gl.getShaderiv(shader_object_id, GL_COMPILE_STATUS, &shader_compile_status);
11333     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv");
11334 
11335     if (GL_FALSE == shader_compile_status)
11336     {
11337         m_testCtx.getLog() << tcu::TestLog::Message << "Shader object compilation failed." << tcu::TestLog::EndMessage;
11338 
11339         // Retrieve shader info log in case of failed compilation.
11340         GLint info_log_length = 0;
11341         gl.getShaderiv(shader_object_id, GL_INFO_LOG_LENGTH, &info_log_length);
11342         if (info_log_length != 0)
11343         {
11344             std::vector<char> log(info_log_length + 1, 0);
11345             gl.getShaderInfoLog(shader_object_id, info_log_length, NULL, &log[0]);
11346             m_testCtx.getLog() << tcu::TestLog::Message << "Shader info log = [" << &log[0] << "]"
11347                                << tcu::TestLog::EndMessage;
11348         }
11349 
11350         return false;
11351     }
11352 
11353     return true;
11354 }
11355 
11356 /** Links a program object and returns link status.
11357  *
11358  * @param program_object_id ID of a program object to be linked.
11359  *
11360  * @return true in case of the operation succeeded (no error was generated and linking end up with success),
11361  *         false otherwise.
11362  */
linkAndCheckProgramLinkStatus(GLuint program_object_id)11363 bool RequiredCase::linkAndCheckProgramLinkStatus(GLuint program_object_id)
11364 {
11365     glu::RenderContext &renderContext = m_context.getRenderContext();
11366     const Functions &gl               = renderContext.getFunctions();
11367 
11368     gl.linkProgram(program_object_id);
11369     GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram");
11370 
11371     // Check if link opearation was successful.
11372     GLint program_link_status = GL_FALSE;
11373     gl.getProgramiv(program_object_id, GL_LINK_STATUS, &program_link_status);
11374     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv");
11375     if (GL_FALSE == program_link_status)
11376     {
11377         m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
11378 
11379         // Retrieve program info log in case of failed linking.
11380         GLint info_log_length = 0;
11381         gl.getProgramiv(program_object_id, GL_INFO_LOG_LENGTH, &info_log_length);
11382         if (info_log_length != 0)
11383         {
11384             std::vector<char> log(info_log_length + 1, 0);
11385             gl.getProgramInfoLog(program_object_id, info_log_length, NULL, &log[0]);
11386             m_testCtx.getLog() << tcu::TestLog::Message << "Program info log = [" << &log[0] << "]"
11387                                << tcu::TestLog::EndMessage;
11388         }
11389 
11390         return false;
11391     }
11392 
11393     return true;
11394 }
11395 
11396 /** Retrieve locations of uniforms (source and destination texture samples)
11397  * and store them in derefs.
11398  *
11399  * @param program_object_id                             ID of a program object for which uniform locations are to be retrieved.
11400  * @param source_2D_texture_uniform_location_ptr        Deref used to store uniform location for a 2D source texture.
11401  *                                                      Cannot be NULL.
11402  * @param source_2DArray_texture_uniform_location_ptr   Deref used to store uniform location for a 2DArray source texture.
11403  *                                                      Cannot be NULL.
11404  * @param source_3D_texture_uniform_location_ptr        Deref used to store uniform location for a 3D source texture.
11405  *                                                      Cannot be NULL.
11406  * @param source_Cube_texture_uniform_location_ptr      Deref used to store uniform location for a Cube source texture.
11407  *                                                      Cannot be NULL.
11408  * @param destination_2D_texture_uniform_location_ptr   Deref used to store uniform location for a 2D destination texture.
11409  *                                                      Cannot be NULL.
11410  * @param destination_Cube_texture_uniform_location_ptr Deref used to store uniform location for a Cube destination texture.
11411  *                                                      Cannot be NULL.
11412  * @param channels_to_compare_uniform_location_ptr      Deref used to store uniform location for a channels_to_compare.
11413  *                                                      Cannot be NULL.
11414  * @param samplers_to_use_uniform_location_ptr          Deref used to store uniform location for a samplers_to_use.
11415  *                                                      Cannot be NULL.
11416  *
11417  * @return true if the operation succeeded (no error was generated and valid uniform locations were returned),
11418  *         false otherwise.
11419  */
getUniformLocations(GLuint program_object_id,GLint * source_2D_texture_uniform_location_ptr,GLint * source_2DArray_texture_uniform_location_ptr,GLint * source_3D_texture_uniform_location_ptr,GLint * source_Cube_texture_uniform_location_ptr,GLint * destination_2D_texture_uniform_location_ptr,GLint * destination_Cube_texture_uniform_location_ptr,GLint * channels_to_compare_uniform_location_ptr,GLint * samplers_to_use_uniform_location_ptr)11420 bool RequiredCase::getUniformLocations(GLuint program_object_id, GLint *source_2D_texture_uniform_location_ptr,
11421                                        GLint *source_2DArray_texture_uniform_location_ptr,
11422                                        GLint *source_3D_texture_uniform_location_ptr,
11423                                        GLint *source_Cube_texture_uniform_location_ptr,
11424                                        GLint *destination_2D_texture_uniform_location_ptr,
11425                                        GLint *destination_Cube_texture_uniform_location_ptr,
11426                                        GLint *channels_to_compare_uniform_location_ptr,
11427                                        GLint *samplers_to_use_uniform_location_ptr)
11428 {
11429     if (source_2D_texture_uniform_location_ptr == NULL || source_2DArray_texture_uniform_location_ptr == NULL ||
11430         source_3D_texture_uniform_location_ptr == NULL || source_Cube_texture_uniform_location_ptr == NULL ||
11431         destination_2D_texture_uniform_location_ptr == NULL || destination_Cube_texture_uniform_location_ptr == NULL ||
11432         channels_to_compare_uniform_location_ptr == NULL || samplers_to_use_uniform_location_ptr == NULL)
11433     {
11434         m_testCtx.getLog() << tcu::TestLog::Message << "NULL pointers passed." << tcu::TestLog::EndMessage;
11435         return false;
11436     }
11437 
11438     glu::RenderContext &renderContext = m_context.getRenderContext();
11439     const Functions &gl               = renderContext.getFunctions();
11440 
11441     // Set active program object.
11442     gl.useProgram(program_object_id);
11443     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
11444 
11445     GLint destination_2D_texture_uniform_location = -1;
11446     destination_2D_texture_uniform_location       = gl.getUniformLocation(program_object_id, "dst_texture2D");
11447     if (destination_2D_texture_uniform_location == -1)
11448         return false;
11449 
11450     GLint destination_Cube_texture_uniform_location = -1;
11451     destination_Cube_texture_uniform_location       = gl.getUniformLocation(program_object_id, "dst_textureCube");
11452     if (destination_Cube_texture_uniform_location == -1)
11453         return false;
11454 
11455     GLint source_2D_texture_uniform_location = -1;
11456     source_2D_texture_uniform_location       = gl.getUniformLocation(program_object_id, "src_texture2D");
11457     if (source_2D_texture_uniform_location == -1)
11458         return false;
11459 
11460     GLint source_2DArray_texture_uniform_location = -1;
11461     source_2DArray_texture_uniform_location       = gl.getUniformLocation(program_object_id, "src_texture2DArray");
11462     if (source_2DArray_texture_uniform_location == -1)
11463         return false;
11464 
11465     GLint source_3D_texture_uniform_location = -1;
11466     source_3D_texture_uniform_location       = gl.getUniformLocation(program_object_id, "src_texture3D");
11467     if (source_3D_texture_uniform_location == -1)
11468         return false;
11469 
11470     GLint source_Cube_texture_uniform_location = -1;
11471     source_Cube_texture_uniform_location       = gl.getUniformLocation(program_object_id, "src_textureCube");
11472     if (source_Cube_texture_uniform_location == -1)
11473         return false;
11474 
11475     GLint channels_to_compare_uniform_location = -1;
11476     channels_to_compare_uniform_location       = gl.getUniformLocation(program_object_id, "channels_to_compare");
11477     if (channels_to_compare_uniform_location == -1)
11478         return false;
11479 
11480     GLint samplers_to_use_uniform_location = -1;
11481     samplers_to_use_uniform_location       = gl.getUniformLocation(program_object_id, "samplers_to_use");
11482     if (samplers_to_use_uniform_location == -1)
11483         return false;
11484 
11485     // We are now ready to store retrieved locations.
11486     *source_2D_texture_uniform_location_ptr        = source_2D_texture_uniform_location;
11487     *source_2DArray_texture_uniform_location_ptr   = source_2DArray_texture_uniform_location;
11488     *source_3D_texture_uniform_location_ptr        = source_3D_texture_uniform_location;
11489     *source_Cube_texture_uniform_location_ptr      = source_Cube_texture_uniform_location;
11490     *destination_2D_texture_uniform_location_ptr   = destination_2D_texture_uniform_location;
11491     *destination_Cube_texture_uniform_location_ptr = destination_Cube_texture_uniform_location;
11492     *channels_to_compare_uniform_location_ptr      = channels_to_compare_uniform_location;
11493     *samplers_to_use_uniform_location_ptr          = samplers_to_use_uniform_location;
11494 
11495     // Restore default settings.
11496     gl.useProgram(0);
11497     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
11498 
11499     return true;
11500 }
11501 
11502 /** Display error message with detailed information.
11503  *  The function should be issued only when pixel comparison failed.
11504  *
11505  * @param src_attachment_type      Source attachment type.
11506  * @param dst_attachment_type      Destination attachment type.
11507  * @param source_pixel_r           R channel source pixel value.
11508  * @param source_pixel_g           G channel source pixel value.
11509  * @param source_pixel_b           B channel source pixel value.
11510  * @param source_pixel_a           A channel source pixel value.
11511  * @param source_internalformat    Source internalformat.
11512  * @param source_type              Source type.
11513  * @param reference_pixel_r        R channel reference pixel value.
11514  * @param reference_pixel_g        G channel reference pixel value.
11515  * @param reference_pixel_b        B channel reference pixel value.
11516  * @param reference_pixel_a        A channel reference pixel value.
11517  * @param reference_internalformat Reference internalformat.
11518  * @param reference_type           Reference type.
11519  * @param result_pixel_r           R channel result pixel value.
11520  * @param result_pixel_g           G channel result pixel value.
11521  * @param result_pixel_b           B channel result pixel value.
11522  * @param result_pixel_a           A channel result pixel value.
11523  * @param result_internalformat    Result internalformat.
11524  * @param result_type              Type internalformat.
11525  * @param max_epsilon_r            Maximum value for an epsilon used for comparison R channel pixel values.
11526  * @param max_epsilon_g            Maximum value for an epsilon used for comparison G channel pixel values.
11527  * @param max_epsilon_b            Maximum value for an epsilon used for comparison B channel pixel values.
11528  * @param max_epsilon_a            Maximum value for an epsilon used for comparison A channel pixel values.
11529  */
displayPixelComparisonFailureMessage(GLint source_pixel_r,GLint source_pixel_g,GLint source_pixel_b,GLint source_pixel_a,GLenum source_internalformat,GLenum source_type,GLint reference_pixel_r,GLint reference_pixel_g,GLint reference_pixel_b,GLint reference_pixel_a,GLenum reference_internalformat,GLenum reference_type,GLint result_pixel_r,GLint result_pixel_g,GLint result_pixel_b,GLint result_pixel_a,GLenum result_internalformat,GLenum result_type,GLint max_epsilon_r,GLint max_epsilon_g,GLint max_epsilon_b,GLint max_epsilon_a)11530 void RequiredCase::displayPixelComparisonFailureMessage(
11531     GLint source_pixel_r, GLint source_pixel_g, GLint source_pixel_b, GLint source_pixel_a,
11532     GLenum source_internalformat, GLenum source_type, GLint reference_pixel_r, GLint reference_pixel_g,
11533     GLint reference_pixel_b, GLint reference_pixel_a, GLenum reference_internalformat, GLenum reference_type,
11534     GLint result_pixel_r, GLint result_pixel_g, GLint result_pixel_b, GLint result_pixel_a,
11535     GLenum result_internalformat, GLenum result_type, GLint max_epsilon_r, GLint max_epsilon_g, GLint max_epsilon_b,
11536     GLint max_epsilon_a)
11537 {
11538     m_testCtx.getLog() << tcu::TestLog::Message << "Conversion failed for source  ["
11539                        << getTargetName(m_source_attachment_type) << "] and destination ["
11540                        << getTargetName(m_destination_attachment_type) << "FBO attachment types."
11541                        << "\nSource pixel:  [" << source_pixel_r << ", " << source_pixel_g << ", " << source_pixel_b
11542                        << ", " << source_pixel_a << "]\nSource internalformat: ["
11543                        << getInternalformatString(source_internalformat) << "]\nSource type:   ["
11544                        << glu::getTypeStr(source_type).toString() << "]\nReference pixel:   [" << reference_pixel_r
11545                        << ", " << reference_pixel_g << ", " << reference_pixel_b << ", " << reference_pixel_a
11546                        << "]\nReference internalformat:  [" << getInternalformatString(reference_internalformat)
11547                        << "]\nReference type:    [" << glu::getTypeStr(reference_type).toString()
11548                        << "]\nResult pixel:  [" << result_pixel_r << ", " << result_pixel_g << ", " << result_pixel_b
11549                        << ", " << result_pixel_a << "]\nResult internalformat: ["
11550                        << getInternalformatString(result_internalformat) << "]\nType used for glReadPixels(): ["
11551                        << glu::getTypeStr(result_type).toString() << "]\nMaximum epsilon:   [" << max_epsilon_r << ", "
11552                        << max_epsilon_g << ", " << max_epsilon_b << ", " << max_epsilon_a << "]"
11553                        << tcu::TestLog::EndMessage;
11554 }
11555 
11556 /** Returns sampler type (float/integer/unsigned integer) that should be used for
11557  *  sampling a texture using data stored in specific internalformat.
11558  *
11559  * @param internalformat Internalformat to use for the query.
11560  *
11561  * @return Sampler type to9 be used..
11562  */
getDataSamplerTypeForInternalformat(GLenum internalformat)11563 DataSamplerType RequiredCase::getDataSamplerTypeForInternalformat(GLenum internalformat)
11564 {
11565     if (isInternalFormatCompatibleWithFPSampler(internalformat))
11566         return DATA_SAMPLER_FLOAT;
11567     else if (isInternalFormatCompatibleWithIntegerSampler(internalformat))
11568         return DATA_SAMPLER_INTEGER;
11569     else if (isInternalFormatCompatibleWithUnsignedIntegerSampler(internalformat))
11570         return DATA_SAMPLER_UNSIGNED_INTEGER;
11571     else
11572     {
11573         // Unrecognized internal format
11574         DE_ASSERT(0);
11575     }
11576 
11577     return DATA_SAMPLER_FLOAT;
11578 }
11579 
11580 /** Tells whether internal format @param internalformat is compatible with a floating-point
11581  *  texture sampling function.
11582  *
11583  *  @param internalformat GLES internal format to consider.
11584  *
11585  *  @return true if yes, false otherwise.
11586  **/
isInternalFormatCompatibleWithFPSampler(GLenum internalformat)11587 bool RequiredCase::isInternalFormatCompatibleWithFPSampler(GLenum internalformat)
11588 {
11589     switch (internalformat)
11590     {
11591     // FP texture() GLSL function should be used for sampling textures using
11592     // the following internalformats
11593     case GL_ALPHA:
11594     case GL_ALPHA8_OES:
11595     case GL_DEPTH_COMPONENT16:
11596     case GL_DEPTH_COMPONENT24:
11597     case GL_DEPTH24_STENCIL8:
11598     case GL_LUMINANCE:
11599     case GL_LUMINANCE8_OES:
11600     case GL_LUMINANCE_ALPHA:
11601     case GL_LUMINANCE8_ALPHA8_OES:
11602     case GL_R8:
11603     case GL_R8_SNORM:
11604     case GL_RG8:
11605     case GL_RG8_SNORM:
11606     case GL_RGB:
11607     case GL_RGB5_A1:
11608     case GL_RGB10_A2:
11609     case GL_RGB565:
11610     case GL_RGB8:
11611     case GL_RGB8_SNORM:
11612     case GL_RGBA:
11613     case GL_RGBA4:
11614     case GL_RGBA8:
11615     case GL_RGBA8_SNORM:
11616     case GL_SRGB8:
11617     case GL_SRGB8_ALPHA8:
11618 
11619     // These are strictly floating-point internal formats
11620     case GL_DEPTH_COMPONENT32F:
11621     case GL_DEPTH32F_STENCIL8:
11622     case GL_R11F_G11F_B10F:
11623     case GL_R16F:
11624     case GL_R32F:
11625     case GL_RG16F:
11626     case GL_RG32F:
11627     case GL_RGB16F:
11628     case GL_RGB32F:
11629     case GL_RGB9_E5:
11630     case GL_RGBA16F:
11631     case GL_RGBA32F:
11632         return true;
11633     }
11634 
11635     return false;
11636 }
11637 
11638 /** Tells whether internal format @param internalformat is compatible with integer
11639  *  texture sampling function.
11640  *
11641  *  @param internalformat GLES internal format to consider.
11642  *
11643  *  @return true if yes, false otherwise.
11644  **/
isInternalFormatCompatibleWithIntegerSampler(GLenum internalformat)11645 bool RequiredCase::isInternalFormatCompatibleWithIntegerSampler(GLenum internalformat)
11646 {
11647     switch (internalformat)
11648     {
11649     case GL_R16I:
11650     case GL_R32I:
11651     case GL_R8I:
11652     case GL_RG16I:
11653     case GL_RG32I:
11654     case GL_RG8I:
11655     case GL_RGB16I:
11656     case GL_RGB32I:
11657     case GL_RGB8I:
11658     case GL_RGBA16I:
11659     case GL_RGBA32I:
11660     case GL_RGBA8I:
11661         return true;
11662     }
11663 
11664     return false;
11665 }
11666 
11667 /** Tells whether internal format @param internalformat is compatible with unsigned integer
11668  *  texture sampling function.
11669  *
11670  *  @param internalformat GLES internal format to consider.
11671  *
11672  *  @return true if yes, false otherwise.
11673  **/
isInternalFormatCompatibleWithUnsignedIntegerSampler(GLenum internalformat)11674 bool RequiredCase::isInternalFormatCompatibleWithUnsignedIntegerSampler(GLenum internalformat)
11675 {
11676     switch (internalformat)
11677     {
11678     case GL_R16UI:
11679     case GL_R32UI:
11680     case GL_R8UI:
11681     case GL_RG16UI:
11682     case GL_RG32UI:
11683     case GL_RG8UI:
11684     case GL_RGB10_A2UI:
11685     case GL_RGB16UI:
11686     case GL_RGB32UI:
11687     case GL_RGB8UI:
11688     case GL_RGBA16UI:
11689     case GL_RGBA32UI:
11690     case GL_RGBA8UI:
11691         return true;
11692     }
11693 
11694     return false;
11695 }
11696 
11697 /** Deletes all objects which were created to support non-renderable texture internalformats.
11698  *
11699  * @param objects Reference to generated object.
11700  */
destroyObjectsSupportingNonRenderableInternalformats(NonRenderableInternalformatSupportObjects & objects)11701 void RequiredCase::destroyObjectsSupportingNonRenderableInternalformats(
11702     NonRenderableInternalformatSupportObjects &objects)
11703 {
11704     unbindAndDestroyBufferObject(objects.comparison_result_buffer_object_id);
11705     unbindAndDestroyBufferObject(objects.src_texture_pixels_buffer_object_id);
11706     unbindAndDestroyBufferObject(objects.dst_texture_pixels_buffer_object_id);
11707     unbindAndDestroyBufferObject(objects.src_texture_coordinates_buffer_object_id);
11708     unbindAndDestroyBufferObject(objects.dst_texture_coordinates_buffer_object_id);
11709     destroyTransformFeedbackObject(objects.transform_feedback_object_id);
11710     destroyProgramAndShaderObjects(objects.program_object_id, objects.fragment_shader_object_id,
11711                                    objects.vertex_shader_object_id);
11712 
11713     objects.comparison_result_buffer_object_id       = 0;
11714     objects.dst_texture_pixels_buffer_object_id      = 0;
11715     objects.dst_2D_texture_uniform_location          = -1;
11716     objects.dst_Cube_texture_uniform_location        = -1;
11717     objects.fragment_shader_object_id                = 0;
11718     objects.transform_feedback_object_id             = 0;
11719     objects.program_object_id                        = 0;
11720     objects.src_2D_texture_uniform_location          = -1;
11721     objects.src_2DArray_texture_uniform_location     = -1;
11722     objects.src_3D_texture_uniform_location          = -1;
11723     objects.src_Cube_texture_uniform_location        = -1;
11724     objects.src_texture_pixels_buffer_object_id      = 0;
11725     objects.vertex_shader_object_id                  = 0;
11726     objects.channels_to_compare_uniform_location     = -1;
11727     objects.samplers_to_use_uniform_location         = -1;
11728     objects.src_texture_coordinates_buffer_object_id = 0;
11729     objects.dst_texture_coordinates_buffer_object_id = 0;
11730 }
11731 
11732 /** Unbind and destroy buffer object which was created for transform feedback purposes.
11733  *
11734  * @param bo_id ID of a buffer object (which was created for transform feedback purposes) to be deleted.
11735  *              If not zero, it is assumed that the value corresponds to valid buffer object ID.
11736  */
unbindAndDestroyBufferObject(GLuint bo_id)11737 void RequiredCase::unbindAndDestroyBufferObject(GLuint bo_id)
11738 {
11739     glu::RenderContext &renderContext = m_context.getRenderContext();
11740     const Functions &gl               = renderContext.getFunctions();
11741 
11742     // Set zero buffer object to be used for GL_TRANSFORM_FEEDBACK_BUFFER.
11743     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, COMPARISON_RESULT_BUFFER_OBJECT_INDEX, 0);
11744     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, SOURCE_TEXTURE_PIXELS_BUFFER_OBJECT_INDEX, 0);
11745     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, DESTINATION_TEXTURE_PIXELS_BUFFER_OBJECT_INDEX, 0);
11746     gl.bindBuffer(GL_ARRAY_BUFFER, 0);
11747 
11748     if (bo_id != 0)
11749     {
11750         gl.deleteBuffers(1, &bo_id);
11751         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
11752     }
11753 }
11754 
11755 /** Unbind and destroy transform feedback object.
11756  *
11757  * @param transform_feedback_object_id ID of a transform feedback object to be deleted.
11758  *                                     If not zero, it is assumed that the value corresponds
11759  *                                     to valid transform feedback object ID.
11760  */
destroyTransformFeedbackObject(GLuint transform_feedback_object_id)11761 void RequiredCase::destroyTransformFeedbackObject(GLuint transform_feedback_object_id)
11762 {
11763     glu::RenderContext &renderContext = m_context.getRenderContext();
11764     const Functions &gl               = renderContext.getFunctions();
11765 
11766     // Set zero transform feedback object to be used.
11767     gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
11768 
11769     if (transform_feedback_object_id != 0)
11770     {
11771         gl.deleteTransformFeedbacks(1, &transform_feedback_object_id);
11772         GLU_EXPECT_NO_ERROR(gl.getError(), "glDestroyTransformFeedbackObject");
11773     }
11774 }
11775 
11776 /** Destroy program and shader objects.
11777  *
11778  * @param program_object_id  ID of a program object to be deleted.
11779  *                           If not zero, it is assumed that the value corresponds to valid program object ID.
11780  * @param fragment_shader_id ID of a fragment shader object to be deleted.
11781  *                           If not zero, it is assumed that the value corresponds to valid shader object ID.
11782  * @param vertex_shader_id   ID of a vertex shader object to be deleted.
11783  *                           If not zero, it is assumed that the value corresponds to valid shader object ID.
11784  */
destroyProgramAndShaderObjects(GLuint program_object_id,GLuint fragment_shader_id,GLuint vertex_shader_id)11785 void RequiredCase::destroyProgramAndShaderObjects(GLuint program_object_id, GLuint fragment_shader_id,
11786                                                   GLuint vertex_shader_id)
11787 {
11788     glu::RenderContext &renderContext = m_context.getRenderContext();
11789     const Functions &gl               = renderContext.getFunctions();
11790 
11791     // Use zero program object.
11792     gl.useProgram(0);
11793 
11794     // Try to destroy fragment shader object.
11795     if (fragment_shader_id != 0)
11796     {
11797         gl.deleteShader(fragment_shader_id);
11798         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader");
11799     }
11800 
11801     // Try to destroy vertex shader object.
11802     if (vertex_shader_id != 0)
11803     {
11804         gl.deleteShader(vertex_shader_id);
11805         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader");
11806     }
11807 
11808     // Try to destroy program object.
11809     if (program_object_id != 0)
11810     {
11811         gl.deleteProgram(program_object_id);
11812         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram");
11813     }
11814 }
11815 
unbindColorAttachments()11816 void RequiredCase::unbindColorAttachments()
11817 {
11818     glu::RenderContext &renderContext = m_context.getRenderContext();
11819     const Functions &gl               = renderContext.getFunctions();
11820 
11821     switch (m_source_attachment_type)
11822     {
11823     case GL_RENDERBUFFER:
11824         gl.framebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
11825         break;
11826     case GL_TEXTURE_2D_ARRAY:
11827     case GL_TEXTURE_3D:
11828         gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, 0);
11829         break;
11830     default:
11831         gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_source_attachment_type, 0, 0);
11832         break;
11833     }
11834 
11835     if (gl.getError() != GL_NO_ERROR)
11836     {
11837         m_testCtx.getLog() << tcu::TestLog::Message << "Could not unbind texture objects from read/draw framebuffers"
11838                            << tcu::TestLog::EndMessage;
11839     }
11840 }
11841 
restoreBindings(GLenum src_attachment_point,GLenum dst_attachment_point,GLint bound_draw_fbo_id,GLint bound_read_fbo_id)11842 void RequiredCase::restoreBindings(GLenum src_attachment_point, GLenum dst_attachment_point, GLint bound_draw_fbo_id,
11843                                    GLint bound_read_fbo_id)
11844 {
11845     glu::RenderContext &renderContext = m_context.getRenderContext();
11846     const Functions &gl               = renderContext.getFunctions();
11847 
11848     gl.disableVertexAttribArray(SRC_TEXTURE_COORDS_ATTRIB_INDEX);
11849     gl.disableVertexAttribArray(DST_TEXTURE_COORDS_ATTRIB_INDEX);
11850 
11851     gl.activeTexture(src_attachment_point);
11852     gl.bindTexture(getGeneralTargetForDetailedTarget(m_source_attachment_type), 0);
11853     gl.activeTexture(dst_attachment_point);
11854     gl.bindTexture(getGeneralTargetForDetailedTarget(m_destination_attachment_type), 0);
11855     gl.activeTexture(GL_TEXTURE0);
11856 
11857     // Restore previous framebuffer bindings.
11858     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, bound_draw_fbo_id);
11859     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, bound_read_fbo_id);
11860 }
11861 
11862 /* SPECIFICATION:
11863  *
11864  * This conformance test verifies that glCopyTexImage2D() implementation does NOT
11865  * accept internalformats that are incompatible with effective internalformat of
11866  * current read buffer.
11867  *
11868  * The test starts from creating a framebuffer object, which is then bound to
11869  * GL_READ_FRAMEBUFFER target. It then enters two-level loop:
11870  *
11871  * a) First level determines source attachment type: this could either be a 2D texture/cube-map
11872  *    face mip-map, a specific mip-map of a slice coming from a 2D texture array OR a 3D texture,
11873  *    or finally a render-buffer. All of these can be bound to an attachment point that is
11874  *    later pointed to by read buffer configuration.
11875  * b) Second level configures attachment type of destination. Since glCopyTexImage2D()
11876  *    specification limits accepted targets, only 2D texture or cube-map face targets are
11877  *    accepted.
11878  *
11879  * For each viable source/destination configuration, the test then enters another two-level loop:
11880  *
11881  * I)  First sub-level determines what internal format should be used for the source attachment.
11882  *     All texture formats required from a conformant GLES3.0 implementation are iterated over.
11883  * II) Second sub-level determines internal format that should be passed as a parameter to
11884  *     a glCopyTexImage2D() call.
11885  *
11886  * For each internal format pair, the test creates and configures a corresponding GL object and
11887  * attaches it to the read framebuffer. The test also uses a pre-generated texture object that
11888  * should be re-configured with each glCopyTexImage2D) call.
11889  *
11890  * The test then loops over all supported format+type combinations for the internal-format considered
11891  * and feeds them into actual glCopyTexImage2D() call. Since we're dealing with a negative test, these
11892  * calls are only made if a source/destination internalformat combination is spec-wise invalid and
11893  * should result in an error. If the implementation accepts a pair that would require indirect
11894  * conversions outside scope of the specification, the test should fail.
11895  */
11896 class ForbiddenCase : public TestBase
11897 {
11898 public:
11899     ForbiddenCase(deqp::Context &context, GLenum source_attachment_types, GLenum destination_attachment_types);
11900     virtual ~ForbiddenCase();
11901 
11902     virtual tcu::TestNode::IterateResult iterate(void);
11903 
11904 protected:
11905     bool execute(GLenum src_internal_format, GLenum dst_internal_format, GLuint src_object_id, GLuint dst_object_id);
11906 };
11907 
ForbiddenCase(deqp::Context & context,GLenum source_attachment_types,GLenum destination_attachment_types)11908 ForbiddenCase::ForbiddenCase(deqp::Context &context, GLenum source_attachment_types,
11909                              GLenum destination_attachment_types)
11910     : TestBase(context, source_attachment_types, destination_attachment_types)
11911 {
11912 }
11913 
~ForbiddenCase()11914 ForbiddenCase::~ForbiddenCase()
11915 {
11916 }
11917 
iterate(void)11918 tcu::TestNode::IterateResult ForbiddenCase::iterate(void)
11919 {
11920     glu::RenderContext &renderContext = m_context.getRenderContext();
11921     const Functions &gl               = renderContext.getFunctions();
11922 
11923     // Create a FBO we will be using throughout the test
11924     GLuint fbo_id = 0;
11925     gl.genFramebuffers(1, &fbo_id);
11926 
11927     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo_id);
11928 
11929     // We will be reading from zeroth color attachment
11930     gl.readBuffer(GL_COLOR_ATTACHMENT0);
11931 
11932     // Make sure the pixel storage is configured accordingly to our data sets
11933     gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
11934     GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei");
11935 
11936     // Quick checks
11937     DE_ASSERT(m_destination_attachment_type == GL_TEXTURE_2D ||
11938               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
11939               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
11940               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
11941               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
11942               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
11943               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
11944 
11945     // Determine general attachment type
11946     GLenum general_attachment_type = getGeneralTargetForDetailedTarget(m_source_attachment_type);
11947     if (general_attachment_type == GL_NONE)
11948     {
11949         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
11950         return STOP;
11951     }
11952 
11953     // Set up source object
11954     GLuint src_object_id = generateGLObject(m_source_attachment_type);
11955     if (src_object_id == 0)
11956     {
11957         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
11958         return STOP;
11959     }
11960 
11961     // Set up destination object
11962     GLuint dst_object_id = generateGLObject(m_destination_attachment_type);
11963     if (dst_object_id == 0)
11964     {
11965         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
11966         return STOP;
11967     }
11968 
11969     // Run through all FBO internal formats
11970     bool result                       = true;
11971     int dstInternalFormatsCount       = DE_LENGTH_OF_ARRAY(copyTexImage2DInternalFormatOrdering);
11972     const int fboInternalFormatsCount = DE_LENGTH_OF_ARRAY(fboEffectiveInternalFormatOrdering);
11973     for (int fboInternalFormatIndex = 0; fboInternalFormatIndex < fboInternalFormatsCount; ++fboInternalFormatIndex)
11974     {
11975         GLenum fboInternalIormat = fboEffectiveInternalFormatOrdering[fboInternalFormatIndex];
11976 
11977         // Run through all destination internal formats
11978         for (int dstInternalFormatUndex = 0; dstInternalFormatUndex < dstInternalFormatsCount; ++dstInternalFormatUndex)
11979         {
11980             GLenum dstInternalFormat = copyTexImage2DInternalFormatOrdering[dstInternalFormatUndex];
11981 
11982             if (!execute(fboInternalIormat, dstInternalFormat, src_object_id, dst_object_id))
11983             {
11984                 // At least one conversion was invalid or failed. Test should
11985                 // fail, but let's continue iterating over internalformats.
11986                 result = false;
11987             }
11988         }
11989     }
11990 
11991     // Release GL objects before we continue
11992     if (dst_object_id != 0)
11993         destroyGLObject(m_destination_attachment_type, dst_object_id);
11994 
11995     if (src_object_id != 0)
11996         destroyGLObject(m_source_attachment_type, src_object_id);
11997 
11998     if (result)
11999         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
12000     else
12001         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
12002 
12003     return STOP;
12004 }
12005 
12006 /** This function verifies if glCopyTexImage2D() implementation forbids conversions that
12007  *  are considered forbidden by GLES3.0.3 spec. For more detailed description, please
12008  *  consult specification of copy_tex_image_conversions_forbidden conformance test.
12009  *
12010  *  @param src_internalformat          GLES internalformat that read buffer should use.
12011  *  @param src_object_id               ID of the source GL object of @param source_attachment_type
12012  *                                     type.
12013  *  @param dst_internalformat          GLES internalformat that should be used for gl.readPixels() call.
12014  *                                     This should NOT be the expected effective internalformat!
12015  *  @param dst_object_id               ID of the destination GL object of
12016  *                                     @param destination_attachment_type type.
12017  *
12018  *  @return true if successful, false otherwise.
12019  */
execute(GLenum src_internal_format,GLenum dst_internal_format,GLuint src_object_id,GLuint dst_object_id)12020 bool ForbiddenCase::execute(GLenum src_internal_format, GLenum dst_internal_format, GLuint src_object_id,
12021                             GLuint dst_object_id)
12022 {
12023     // Allocate the max possible size for the texture data (4 compoenents of 4 bytes each)
12024     static char fbo_data[TEXTURE_WIDTH * TEXTURE_HEIGHT * 4 * 4];
12025     GLenum fbo_format                          = GL_NONE;
12026     GLenum fbo_type                            = GL_NONE;
12027     GLenum general_destination_attachment_type = getGeneralTargetForDetailedTarget(m_destination_attachment_type);
12028     int n_src_pair                             = 0;
12029     bool result                                = true;
12030 
12031     // Quick checks
12032     DE_ASSERT(m_destination_attachment_type == GL_TEXTURE_2D ||
12033               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
12034               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
12035               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
12036               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
12037               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
12038               m_destination_attachment_type == GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
12039 
12040     // Skip the internalformat if it's non-renderable and we're trying to set up a renderbuffer source.
12041     if (m_source_attachment_type == GL_RENDERBUFFER && !isValidRBOInternalFormat(src_internal_format))
12042         return true;
12043 
12044     // Try using all compatible format+type pairs for
12045     const Functions &gl = m_context.getRenderContext().getFunctions();
12046     while (getFormatAndTypeCompatibleWithInternalformat(src_internal_format, n_src_pair, &fbo_format, &fbo_type))
12047     {
12048         // Do not test internal formats that are not deemed renderable by GLES implementation we're testing
12049         if (!isColorRenderableInternalFormat(src_internal_format))
12050             break;
12051 
12052         // Set up data to be used for source. Note we don't really care much about the data anyway because we want to run
12053         // negative tests, but in case the conversion is incorrectly allowed, we do not want this fact to be covered by
12054         // missing source attachment data
12055         if (!configureGLObject(1, m_source_attachment_type, src_object_id, src_internal_format, fbo_format, fbo_type,
12056                                fbo_data))
12057             return false;
12058 
12059         // Good. Check if the conversion is forbidden - if so, we can run a negative test! */
12060         if (!isFBOEffectiveInternalFormatCompatibleWithDestinationInternalFormat(src_internal_format,
12061                                                                                  dst_internal_format))
12062         {
12063 #if 0
12064                 m_testCtx.getLog() << tcu::TestLog::Message
12065                                    << "Testing conversion [" << getInternalformatString(src_internal_format)
12066                                    << "]=>[" << getInternalformatString(dst_internal_format)
12067                                    << "] for source target [" << GetTargetName(m_source_attachment_type)
12068                                    << "] and destination target [" << GetTargetName(m_destination_attachment_type) << "]",
12069                                    << tcu::TestLog::EndMessage;
12070 #endif
12071 
12072             // Ask the implementation to perform the conversion!
12073             gl.bindTexture(general_destination_attachment_type, dst_object_id);
12074             gl.copyTexImage2D(m_destination_attachment_type, 0, dst_internal_format, 0 /* x */, 0 /* y */,
12075                               TEXTURE_WIDTH, TEXTURE_HEIGHT, 0 /* border */);
12076             gl.bindTexture(general_destination_attachment_type, 0);
12077 
12078             // Has the conversion failed as expected?
12079             GLenum error_code = gl.getError();
12080             if (error_code == GL_NO_ERROR)
12081             {
12082                 m_testCtx.getLog() << tcu::TestLog::Message << "[" << getInternalformatString(src_internal_format)
12083                                    << "]=>[" << getInternalformatString(dst_internal_format)
12084                                    << "] conversion [src target=" << getTargetName(m_source_attachment_type)
12085                                    << ", dst target=" << getTargetName(m_destination_attachment_type)
12086                                    << "] supported contrary to GLES3.0 spec." << tcu::TestLog::EndMessage;
12087                 // This test is now considered failed
12088                 result = false;
12089             }
12090             else if (error_code != GL_INVALID_OPERATION)
12091             {
12092                 m_testCtx.getLog() << tcu::TestLog::Message << "[" << getInternalformatString(src_internal_format)
12093                                    << "]=>[" << getInternalformatString(dst_internal_format)
12094                                    << "] conversion [src target=" << getTargetName(m_source_attachment_type)
12095                                    << ", dst target=" << getTargetName(m_destination_attachment_type) << "] caused ["
12096                                    << error_code << "] error instead of GL_INVALID_OPERATION."
12097                                    << tcu::TestLog::EndMessage;
12098                 // This test is now considered failed
12099                 result = false;
12100             }
12101         }
12102 
12103         n_src_pair++;
12104 
12105         // If we're copying from a renderbuffer, we don't really care about compatible format+type pairs, as
12106         // the effective internalformat is explicitly configured by gl.renderbufferStorage() call.
12107         if (m_source_attachment_type == GL_RENDERBUFFER)
12108             break;
12109     } // for (all compatible format+type pairs)
12110 
12111     return result;
12112 }
12113 
CopyTexImageConversionsTests(deqp::Context & context)12114 CopyTexImageConversionsTests::CopyTexImageConversionsTests(deqp::Context &context)
12115     : TestCaseGroup(context, "copy_tex_image_conversions", "")
12116 {
12117 }
12118 
init()12119 void CopyTexImageConversionsTests::init()
12120 {
12121     // Types of objects that can be used as source attachments for conversion process
12122     const GLenum sourceAttachmentTypes[] = {GL_TEXTURE_2D,
12123                                             GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
12124                                             GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
12125                                             GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
12126                                             GL_TEXTURE_CUBE_MAP_POSITIVE_X,
12127                                             GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
12128                                             GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
12129                                             GL_TEXTURE_2D_ARRAY,
12130                                             GL_TEXTURE_3D,
12131                                             GL_RENDERBUFFER};
12132 
12133     // Types of objects that can be used as destination attachments for conversion process
12134     const GLenum destinationAttachmentTypes[] = {
12135         GL_TEXTURE_2D,
12136         GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
12137         GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
12138         GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
12139         GL_TEXTURE_CUBE_MAP_POSITIVE_X,
12140         GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
12141         GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
12142     };
12143 
12144     // Set up conversion database
12145     de::SharedPtr<ConversionDatabase> conversionDatabase(new ConversionDatabase());
12146 
12147     TestCaseGroup *requiredGroup  = new deqp::TestCaseGroup(m_context, "required", "");
12148     TestCaseGroup *forbiddenGroup = new deqp::TestCaseGroup(m_context, "forbidden", "");
12149     for (int srcAttachmentIndex = 0; srcAttachmentIndex < DE_LENGTH_OF_ARRAY(sourceAttachmentTypes);
12150          ++srcAttachmentIndex)
12151     {
12152         GLenum srcAttachmentType = sourceAttachmentTypes[srcAttachmentIndex];
12153         for (int dstAttachmentIndex = 0; dstAttachmentIndex < DE_LENGTH_OF_ARRAY(destinationAttachmentTypes);
12154              ++dstAttachmentIndex)
12155         {
12156             GLenum dstAttachmentType = destinationAttachmentTypes[dstAttachmentIndex];
12157             requiredGroup->addChild(
12158                 new RequiredCase(m_context, conversionDatabase, srcAttachmentType, dstAttachmentType));
12159             forbiddenGroup->addChild(new ForbiddenCase(m_context, srcAttachmentType, dstAttachmentType));
12160         }
12161     }
12162 
12163     addChild(forbiddenGroup);
12164     addChild(requiredGroup);
12165 }
12166 
12167 } // namespace es3cts
12168