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