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