Fix invalid parameter for GLES 2.0
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcInternalformatTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2017 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  InternalformatTests.cpp
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23
24 #include "glcInternalformatTests.hpp"
25 #include "deMath.h"
26 #include "gluContextInfo.hpp"
27 #include "gluDefs.hpp"
28 #include "gluDrawUtil.hpp"
29 #include "gluPixelTransfer.hpp"
30 #include "gluShaderProgram.hpp"
31 #include "gluStrUtil.hpp"
32 #include "gluTexture.hpp"
33 #include "gluTextureUtil.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 #include "tcuImageCompare.hpp"
37 #include "tcuRenderTarget.hpp"
38 #include "tcuStringTemplate.hpp"
39 #include "tcuSurface.hpp"
40 #include "tcuTestLog.hpp"
41 #include "tcuTextureUtil.hpp"
42
43 #include <algorithm>
44 #include <map>
45
46 using namespace glw;
47
48 namespace glcts
49 {
50
51 // all extension names required by the tests
52 static const char* EXT_texture_type_2_10_10_10_REV = "GL_EXT_texture_type_2_10_10_10_REV";
53 static const char* EXT_texture_shared_exponent   = "GL_EXT_texture_shared_exponent";
54 static const char* EXT_texture_integer                     = "GL_EXT_texture_integer";
55 static const char* ARB_texture_rgb10_a2ui                  = "GL_ARB_texture_rgb10_a2ui";
56 static const char* ARB_depth_texture                       = "GL_ARB_depth_texture";
57 static const char* ARB_texture_float                       = "GL_ARB_texture_float";
58 static const char* OES_texture_float                       = "GL_OES_texture_float";
59 static const char* OES_texture_float_linear                = "GL_OES_texture_float_linear";
60 static const char* OES_texture_half_float                  = "GL_OES_texture_half_float";
61 static const char* OES_texture_half_float_linear   = "GL_OES_texture_half_float_linear";
62 static const char* OES_rgb8_rgba8                                  = "GL_OES_rgb8_rgba8";
63 static const char* OES_depth_texture                       = "GL_OES_depth_texture";
64 static const char* OES_depth24                                     = "GL_OES_depth24";
65 static const char* OES_depth32                                     = "GL_OES_depth32";
66 static const char* OES_packed_depth_stencil                = "GL_OES_packed_depth_stencil";
67 static const char* OES_stencil1                                    = "GL_OES_stencil1";
68 static const char* OES_stencil4                                    = "GL_OES_stencil4";
69 static const char* OES_stencil8                                    = "GL_OES_stencil8";
70 static const char* OES_required_internalformat   = "GL_OES_required_internalformat";
71
72 struct TextureFormat
73 {
74         GLenum          format;
75         GLenum          type;
76         GLint           internalFormat;
77         const char* requiredExtension;
78         const char* secondReqiredExtension;
79         GLint           minFilter;
80         GLint           magFilter;
81
82         TextureFormat()
83         {
84         }
85
86         TextureFormat(GLenum aFormat, GLenum aType, GLint aInternalFormat, const char* aRequiredExtension = DE_NULL,
87                                   const char* aSecondReqiredExtension = DE_NULL, GLint aMinFilter = GL_NEAREST,
88                                   GLint aMagFilter = GL_NEAREST)
89                 : format(aFormat)
90                 , type(aType)
91                 , internalFormat(aInternalFormat)
92                 , requiredExtension(aRequiredExtension)
93                 , secondReqiredExtension(aSecondReqiredExtension)
94                 , minFilter(aMinFilter)
95                 , magFilter(aMagFilter)
96         {
97         }
98 };
99
100 struct CopyTexImageFormat
101 {
102         GLint           internalFormat;
103         const char* requiredExtension;
104         const char* secondReqiredExtension;
105         GLint           minFilter;
106         GLint           magFilter;
107
108         CopyTexImageFormat(GLenum aInternalFormat, const char* aRequiredExtension = DE_NULL,
109                                            const char* aSecondReqiredExtension = DE_NULL, GLint aMinFilter = GL_NEAREST,
110                                            GLint aMagFilter = GL_NEAREST)
111                 : internalFormat(aInternalFormat)
112                 , requiredExtension(aRequiredExtension)
113                 , secondReqiredExtension(aSecondReqiredExtension)
114                 , minFilter(aMinFilter)
115                 , magFilter(aMagFilter)
116         {
117         }
118 };
119
120 enum RenderBufferType
121 {
122         RENDERBUFFER_COLOR,
123         RENDERBUFFER_STENCIL,
124         RENDERBUFFER_DEPTH,
125         RENDERBUFFER_DEPTH_STENCIL
126 };
127
128 struct RenderbufferFormat
129 {
130         GLenum                   format;
131         RenderBufferType type;
132         const char*              requiredExtension;
133         const char*              secondReqiredExtension;
134
135         RenderbufferFormat(GLenum aFormat, RenderBufferType aType, const char* aRequiredExtension = DE_NULL,
136                                            const char* aSecondReqiredExtension = DE_NULL)
137                 : format(aFormat)
138                 , type(aType)
139                 , requiredExtension(aRequiredExtension)
140                 , secondReqiredExtension(aSecondReqiredExtension)
141         {
142         }
143 };
144
145 class InternalformatCaseBase : public deqp::TestCase
146 {
147 public:
148         InternalformatCaseBase(deqp::Context& context, const std::string& name);
149         virtual ~InternalformatCaseBase()
150         {
151         }
152
153 protected:
154         bool requiredExtensionsSupported(const char* extension1, const char* extension2);
155         GLuint createTexture(GLint internalFormat, GLenum format, GLenum type, GLint minFilter, GLint magFilter,
156                                                  bool generateData = true) const;
157         glu::ProgramSources prepareTexturingProgramSources(GLint internalFormat, GLenum format, GLenum type) const;
158         void renderTexturedQuad(GLuint programId) const;
159         GLenum getUnsizedFormatFromInternalFormat(GLint internalFormat) const;
160         GLenum getTypeFromInternalFormat(GLint internalFormat) const;
161
162 private:
163         void generateTextureData(GLuint width, GLuint height, GLenum type, unsigned int pixelSize, unsigned int components,
164                                                          std::vector<unsigned char>& result) const;
165
166         // color converting methods
167         static void convertByte(tcu::Vec4 inColor, unsigned char* dst, int components);
168         static void convertUByte(tcu::Vec4 inColor, unsigned char* dst, int components);
169         static void convertHFloat(tcu::Vec4 inColor, unsigned char* dst, int components);
170         static void convertFloat(tcu::Vec4 inColor, unsigned char* dst, int components);
171         static void convertShort(tcu::Vec4 inColor, unsigned char* dst, int components);
172         static void convertUShort(tcu::Vec4 inColor, unsigned char* dst, int components);
173         static void convertInt(tcu::Vec4 inColor, unsigned char* dst, int components);
174         static void convertUInt(tcu::Vec4 inColor, unsigned char* dst, int components);
175         static void convertUInt_24_8(tcu::Vec4 inColor, unsigned char* dst, int components);
176         static void convertUShort_4_4_4_4(tcu::Vec4 inColor, unsigned char* dst, int);
177         static void convertUShort_5_5_5_1(tcu::Vec4 inColor, unsigned char* dst, int);
178         static void convertUShort_5_6_5(tcu::Vec4 inColor, unsigned char* dst, int);
179         static void convertUInt_2_10_10_10_rev(tcu::Vec4 inColor, unsigned char* dst, int);
180
181         static GLhalf floatToHalf(float f);
182
183 protected:
184         GLsizei m_renderWidth;
185         GLsizei m_renderHeight;
186 };
187
188 InternalformatCaseBase::InternalformatCaseBase(deqp::Context& context, const std::string& name)
189         : deqp::TestCase(context, name.c_str(), ""), m_renderWidth(64), m_renderHeight(64)
190 {
191 }
192
193 bool InternalformatCaseBase::requiredExtensionsSupported(const char* extension1, const char* extension2)
194 {
195         const glu::ContextInfo& contextInfo = m_context.getContextInfo();
196         if (extension1)
197         {
198                 if (extension2)
199                 {
200                         if (!contextInfo.isExtensionSupported(extension1) || !contextInfo.isExtensionSupported(extension2))
201                         {
202                                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "One of required extensions is not supported");
203                                 return false;
204                         }
205                 }
206                 else if (!contextInfo.isExtensionSupported(extension1))
207                 {
208                         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Required extension is not supported");
209                         return false;
210                 }
211         }
212         return true;
213 }
214
215 GLuint InternalformatCaseBase::createTexture(GLint internalFormat, GLenum format, GLenum type, GLint minFilter,
216                                                                                          GLint magFilter, bool generateData) const
217 {
218         const Functions&                   gl = m_context.getRenderContext().getFunctions();
219         GLuint                                     textureName;
220         std::vector<unsigned char> textureData;
221         GLvoid*                                    textureDataPtr = DE_NULL;
222
223         if (generateData)
224         {
225                 tcu::TextureFormat tcuTextureFormat = glu::mapGLTransferFormat(format, type);
226                 unsigned int       components           = tcu::getNumUsedChannels(tcuTextureFormat.order);
227                 unsigned int       pixelSize            = 4;
228
229                 // note: getPixelSize hits assertion for GL_UNSIGNED_INT_2_10_10_10_REV when format is RGB
230                 if (type != GL_UNSIGNED_INT_2_10_10_10_REV)
231                         pixelSize = tcu::getPixelSize(tcuTextureFormat);
232
233                 generateTextureData(m_renderWidth, m_renderHeight, type, pixelSize, components, textureData);
234                 textureDataPtr = &textureData[0];
235         }
236
237         gl.genTextures(1, &textureName);
238         gl.bindTexture(GL_TEXTURE_2D, textureName);
239         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
240
241         gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, m_renderWidth, m_renderHeight, 0, format, type, textureDataPtr);
242         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D");
243
244         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
245         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
246         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
247         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
248         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
249         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
250
251         return textureName;
252 }
253
254 glu::ProgramSources InternalformatCaseBase::prepareTexturingProgramSources(GLint internalFormat, GLenum format,
255                                                                                                                                                    GLenum type) const
256 {
257         glu::RenderContext& renderContext = m_context.getRenderContext();
258         glu::ContextType        contextType   = renderContext.getType();
259         glu::GLSLVersion        glslVersion   = glu::getContextTypeGLSLVersion(contextType);
260
261         std::string vs;
262         std::string fs;
263
264         std::map<std::string, std::string> specializationMap;
265         specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion);
266
267         if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)) || glu::isContextTypeGLCore(contextType))
268         {
269                 vs = "${VERSION}\n"
270                          "precision highp float;\n"
271                          "in vec2 position;\n"
272                          "in vec2 inTexcoord;\n"
273                          "out vec2 texcoord;\n"
274                          "void main()\n"
275                          "{\n"
276                          "  texcoord = inTexcoord;\n"
277                          "  gl_Position = vec4(position, 0.0, 1.0);\n"
278                          "}\n";
279                 fs = "${VERSION}\n"
280                          "precision highp float;\n"
281                          "uniform ${SAMPLER} sampler;\n"
282                          "in vec2 texcoord;\n"
283                          "out highp vec4 color;\n"
284                          "void main()\n"
285                          "{\n"
286                          "  ${SAMPLED_TYPE} v = texture(sampler, texcoord);\n"
287                          "  color = ${CALCULATE_COLOR};\n"
288                          "  ${PROCESS_COLOR}\n"
289                          "}\n";
290
291                 specializationMap["PROCESS_COLOR"] = "";
292                 if ((format == GL_RGB_INTEGER) || (format == GL_RGBA_INTEGER))
293                 {
294                         specializationMap["SAMPLED_TYPE"] = "uvec4";
295                         specializationMap["SAMPLER"]      = "usampler2D";
296                         if (type == GL_BYTE)
297                         {
298                                 specializationMap["SAMPLED_TYPE"]       = "ivec4";
299                                 specializationMap["SAMPLER"]             = "isampler2D";
300                                 specializationMap["CALCULATE_COLOR"] = "vec4(v) / 127.0";
301                         }
302                         else if (type == GL_UNSIGNED_BYTE)
303                         {
304                                 specializationMap["CALCULATE_COLOR"] = "vec4(v) / 255.0";
305                         }
306                         else if (type == GL_SHORT)
307                         {
308                                 specializationMap["SAMPLED_TYPE"]       = "ivec4";
309                                 specializationMap["SAMPLER"]             = "isampler2D";
310                                 specializationMap["CALCULATE_COLOR"] = "vec4(v / 128) / 256.0";
311                         }
312                         else if (type == GL_UNSIGNED_SHORT)
313                         {
314                                 specializationMap["CALCULATE_COLOR"] = "vec4(v / 256) / 256.0";
315                         }
316                         else if (type == GL_INT)
317                         {
318                                 specializationMap["SAMPLED_TYPE"]       = "ivec4";
319                                 specializationMap["SAMPLER"]             = "isampler2D";
320                                 specializationMap["CALCULATE_COLOR"] = "vec4(v / 2097152u) / 1024.0";
321                         }
322                         else // GL_UNSIGNED_INT
323                         {
324                                 if (internalFormat == GL_RGB10_A2UI)
325                                         specializationMap["CALCULATE_COLOR"] = "vec4(vec3(v.rgb) / 1023.0, float(v.a) / 3.0)";
326                                 else
327                                         specializationMap["CALCULATE_COLOR"] = "vec4(v / 4194304u) / 1024.0";
328                         }
329
330                         if (format == GL_RGB_INTEGER)
331                                 specializationMap["PROCESS_COLOR"] = "color.a = 1.0;\n";
332                 }
333                 else
334                 {
335                         specializationMap["SAMPLED_TYPE"]       = "vec4";
336                         specializationMap["SAMPLER"]             = "sampler2D";
337                         if (format == GL_DEPTH_STENCIL)
338                                 specializationMap["CALCULATE_COLOR"] = "vec4(v.r, 0.0, 0.0, 1.0)";
339                         else
340                                 specializationMap["CALCULATE_COLOR"] = "v";
341                 }
342         }
343         else
344         {
345                 vs = "${VERSION}\n"
346                          "attribute highp vec2 position;\n"
347                          "attribute highp vec2 inTexcoord;\n"
348                          "varying highp vec2 texcoord;\n"
349                          "void main()\n"
350                          "{\n"
351                          "  texcoord = inTexcoord;\n"
352                          "  gl_Position = vec4(position, 0.0, 1.0);\n"
353                          "}\n";
354                 fs = "${VERSION}\n"
355                          "uniform highp sampler2D sampler;\n"
356                          "varying highp vec2 texcoord;\n"
357                          "void main()\n"
358                          "{\n"
359                          "  highp vec4 color = texture2D(sampler, texcoord);\n"
360                          "  gl_FragColor = ${CALCULATE_COLOR};\n"
361                          "}\n";
362
363                 if ((internalFormat == GL_DEPTH_COMPONENT) || (internalFormat == GL_DEPTH_STENCIL))
364                         specializationMap["CALCULATE_COLOR"] = "vec4(color.r, 0.0, 0.0, 1.0)";
365                 else
366                         specializationMap["CALCULATE_COLOR"] = "color";
367         }
368
369         vs = tcu::StringTemplate(vs).specialize(specializationMap);
370         fs = tcu::StringTemplate(fs).specialize(specializationMap);
371         return glu::makeVtxFragSources(vs.c_str(), fs.c_str());
372 }
373
374 void InternalformatCaseBase::renderTexturedQuad(GLuint programId) const
375 {
376         // Prepare data for rendering
377         static const deUint16                            quadIndices[]  = { 0, 1, 2, 2, 1, 3 };
378         static const float                                       position[]             = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
379         static const float                                       texCoord[]             = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
380         static const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, position),
381                                                                                                                         glu::va::Float("inTexcoord", 2, 4, 0, texCoord) };
382
383         glu::draw(m_context.getRenderContext(), programId, DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
384                           glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
385 }
386
387 GLenum InternalformatCaseBase::getUnsizedFormatFromInternalFormat(GLint internalFormat) const
388 {
389         switch (internalFormat)
390         {
391         case GL_RGBA:
392         case GL_RGBA4:
393         case GL_RGB5_A1:
394         case GL_RGBA8:
395         case GL_RGB10_A2:
396                 return GL_RGBA;
397         case GL_RGB10_A2UI:
398         case GL_RGBA8UI: //remove this
399                 return GL_RGBA_INTEGER;
400         case GL_RGB:
401         case GL_RGB565:
402         case GL_RGB8:
403         case GL_RGB10:
404         case GL_RGB9_E5:
405                 return GL_RGB;
406         case GL_LUMINANCE_ALPHA:
407         case GL_LUMINANCE4_ALPHA4_OES:
408         case GL_LUMINANCE8_ALPHA8_OES:
409                 return GL_LUMINANCE_ALPHA;
410         case GL_LUMINANCE:
411         case GL_LUMINANCE8_OES:
412                 return GL_LUMINANCE;
413         case GL_ALPHA:
414         case GL_ALPHA8_OES:
415                 return GL_ALPHA;
416         case GL_DEPTH_COMPONENT16:
417         case GL_DEPTH_COMPONENT24:
418         case GL_DEPTH_COMPONENT32:
419                 return GL_DEPTH_COMPONENT;
420         case GL_DEPTH24_STENCIL8:
421                 return GL_DEPTH_STENCIL;
422         case GL_STENCIL_INDEX8:
423                 return GL_STENCIL_INDEX;
424         default:
425                 TCU_FAIL("Unrecognized internal format");
426         }
427         return GL_NONE;
428 }
429
430 GLenum InternalformatCaseBase::getTypeFromInternalFormat(GLint internalFormat) const
431 {
432         switch (internalFormat)
433         {
434         case GL_RGB10:
435         case GL_RGB10_A2:
436         case GL_RGB10_A2UI:
437                 return GL_UNSIGNED_INT_2_10_10_10_REV;
438         case GL_DEPTH_COMPONENT16:
439         case GL_DEPTH_COMPONENT24:
440                 return GL_UNSIGNED_SHORT;
441         case GL_DEPTH_COMPONENT32:
442                 return GL_UNSIGNED_INT;
443         }
444
445         return GL_UNSIGNED_BYTE;
446 }
447
448 void InternalformatCaseBase::generateTextureData(GLuint width, GLuint height, GLenum type, unsigned int pixelSize,
449                                                                                                  unsigned int components, std::vector<unsigned char>& result) const
450 {
451         // colors are the 4 corner colors specified ( lower left, lower right, upper left, upper right )
452         static tcu::Vec4 colors[4] = { tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
453                                                                    tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f) };
454
455         typedef void (*ColorConversionFunc)(tcu::Vec4, unsigned char*, int);
456         typedef std::map<GLenum, ColorConversionFunc> ColorConversionMap;
457         static ColorConversionMap colorConversionMap;
458         if (colorConversionMap.empty())
459         {
460                 colorConversionMap[GL_BYTE]                                                = &convertByte;
461                 colorConversionMap[GL_UNSIGNED_BYTE]                       = &convertUByte;
462                 colorConversionMap[GL_HALF_FLOAT]                                  = &convertHFloat;
463                 colorConversionMap[GL_FLOAT]                                       = &convertFloat;
464                 colorConversionMap[GL_SHORT]                                       = &convertShort;
465                 colorConversionMap[GL_UNSIGNED_SHORT]                      = &convertUShort;
466                 colorConversionMap[GL_INT]                                                 = &convertInt;
467                 colorConversionMap[GL_UNSIGNED_INT]                                = &convertUInt;
468                 colorConversionMap[GL_UNSIGNED_INT_24_8]                   = &convertUInt_24_8;
469                 colorConversionMap[GL_UNSIGNED_SHORT_4_4_4_4]     = &convertUShort_4_4_4_4;
470                 colorConversionMap[GL_UNSIGNED_SHORT_5_5_5_1]     = &convertUShort_5_5_5_1;
471                 colorConversionMap[GL_UNSIGNED_SHORT_5_6_5]                = &convertUShort_5_6_5;
472                 colorConversionMap[GL_UNSIGNED_INT_2_10_10_10_REV] = &convertUInt_2_10_10_10_rev;
473         }
474
475         ColorConversionFunc convertColor = colorConversionMap.at(type);
476
477         float lwidth  = static_cast<float>(width - 1);
478         float lheight = static_cast<float>(height - 1);
479
480         result.resize(width * height * pixelSize);
481         unsigned char* dataPtr = &result[0];
482
483         for (GLuint y = 0; y < height; ++y)
484         {
485                 for (GLuint x = 0; x < width; ++x)
486                 {
487                         float    posX  = (lwidth - static_cast<float>(x)) / lwidth;
488                         float    posY  = (lheight - static_cast<float>(y)) / lheight;
489                         float    rposX = 1.f - posX;
490                         float    rposY = 1.f - posY;
491                         tcu::Vec4 c             = colors[0] * (posX * posY) + colors[1] * (rposX * posY) + colors[2] * (posX * rposY);
492
493                         // Hard-code the alpha as small floating point instability results in large differences for some formats
494                         c[3] = 1.f;
495                         convertColor(c, dataPtr, static_cast<int>(components));
496                         dataPtr += pixelSize;
497                 }
498         }
499 }
500
501 void InternalformatCaseBase::convertByte(tcu::Vec4 inColor, unsigned char* dst, int components)
502 {
503         char* dstChar = reinterpret_cast<char*>(dst);
504         for (int i       = 0; i < components; ++i)
505                 dstChar[i] = static_cast<char>(inColor[i] * 127.0f);
506 }
507
508 void InternalformatCaseBase::convertUByte(tcu::Vec4 inColor, unsigned char* dst, int components)
509 {
510         for (int i = 0; i < components; ++i)
511                 dst[i] = static_cast<unsigned char>(inColor[i] * 255.f);
512 }
513
514 void InternalformatCaseBase::convertHFloat(tcu::Vec4 inColor, unsigned char* dst, int components)
515 {
516         GLhalf* dstHalf = reinterpret_cast<GLhalf*>(dst);
517         for (int i       = 0; i < components; ++i)
518                 dstHalf[i] = floatToHalf(inColor[i]);
519 }
520
521 void InternalformatCaseBase::convertFloat(tcu::Vec4 inColor, unsigned char* dst, int components)
522 {
523         float* dstFloat = reinterpret_cast<float*>(dst);
524         for (int i              = 0; i < components; ++i)
525                 dstFloat[i] = inColor[i];
526 }
527
528 void InternalformatCaseBase::convertShort(tcu::Vec4 inColor, unsigned char* dst, int components)
529 {
530         short* dstUShort = reinterpret_cast<short*>(dst);
531         for (int i = 0; i < components; ++i)
532         {
533                 double c         = static_cast<double>(inColor[i]);
534                 dstUShort[i] = static_cast<short>(c * 32768 - 1);
535         }
536 }
537
538 void InternalformatCaseBase::convertUShort(tcu::Vec4 inColor, unsigned char* dst, int components)
539 {
540         unsigned short* dstUShort = reinterpret_cast<unsigned short*>(dst);
541         for (int i = 0; i < components; ++i)
542         {
543                 double c         = static_cast<double>(inColor[i]);
544                 dstUShort[i] = static_cast<unsigned short>(c * 65535u);
545         }
546 }
547
548 void InternalformatCaseBase::convertInt(tcu::Vec4 inColor, unsigned char* dst, int components)
549 {
550         int* dstUInt = reinterpret_cast<int*>(dst);
551         for (int i       = 0; i < components; ++i)
552                 dstUInt[i] = static_cast<int>(inColor[i] * 2147483648u - 1);
553 }
554
555 void InternalformatCaseBase::convertUInt(tcu::Vec4 inColor, unsigned char* dst, int components)
556 {
557         unsigned int* dstUInt = reinterpret_cast<unsigned int*>(dst);
558         for (int i = 0; i < components; ++i)
559         {
560                 double c   = static_cast<double>(inColor[i]);
561                 dstUInt[i] = static_cast<unsigned int>(c * 4294967295u);
562         }
563 }
564
565 void InternalformatCaseBase::convertUInt_24_8(tcu::Vec4 inColor, unsigned char* dst, int)
566 {
567         unsigned int* dstUint = reinterpret_cast<unsigned int*>(dst);
568
569         unsigned int d = static_cast<unsigned int>(inColor[0] * 16777215u) << 8;
570         unsigned int s = static_cast<unsigned int>(inColor[1] * 255u);
571
572         dstUint[0] = (d & 0xFFFFFF00) | (s & 0xFF);
573 }
574
575 void InternalformatCaseBase::convertUShort_4_4_4_4(tcu::Vec4 inColor, unsigned char* dst, int)
576 {
577         unsigned short* dstUShort = reinterpret_cast<unsigned short*>(dst);
578
579         unsigned int r = static_cast<unsigned int>(inColor[0] * 15) << 12;
580         unsigned int g = static_cast<unsigned int>(inColor[1] * 15) << 8;
581         unsigned int b = static_cast<unsigned int>(inColor[2] * 15) << 4;
582         unsigned int a = static_cast<unsigned int>(inColor[3] * 15) << 0;
583
584         dstUShort[0] = (r & 0xF000) | (g & 0x0F00) | (b & 0x00F0) | (a & 0x000F);
585 }
586
587 void InternalformatCaseBase::convertUShort_5_5_5_1(tcu::Vec4 inColor, unsigned char* dst, int)
588 {
589         unsigned short* dstUShort = reinterpret_cast<unsigned short*>(dst);
590
591         unsigned int r = static_cast<unsigned int>(inColor[0] * 31) << 11;
592         unsigned int g = static_cast<unsigned int>(inColor[1] * 31) << 6;
593         unsigned int b = static_cast<unsigned int>(inColor[2] * 31) << 1;
594         unsigned int a = static_cast<unsigned int>(inColor[3] * 1) << 0;
595
596         dstUShort[0] = (r & 0xF800) | (g & 0x07c0) | (b & 0x003e) | (a & 0x0001);
597 }
598
599 void InternalformatCaseBase::convertUShort_5_6_5(tcu::Vec4 inColor, unsigned char* dst, int)
600 {
601         unsigned short* dstUShort = reinterpret_cast<unsigned short*>(dst);
602
603         unsigned int r = static_cast<unsigned int>(inColor[0] * 31) << 11;
604         unsigned int g = static_cast<unsigned int>(inColor[1] * 63) << 5;
605         unsigned int b = static_cast<unsigned int>(inColor[2] * 31) << 0;
606
607         dstUShort[0] = (r & 0xF800) | (g & 0x07e0) | (b & 0x001f);
608 }
609
610 void InternalformatCaseBase::convertUInt_2_10_10_10_rev(tcu::Vec4 inColor, unsigned char* dst, int)
611 {
612         unsigned int* dstUint = reinterpret_cast<unsigned int*>(dst);
613
614         // Alpha value is rounded to eliminate small precision errors that
615         // may result in big errors after converting value to just 4 bits
616         unsigned int a = static_cast<unsigned int>(deFloatRound(inColor[3] * 3)) << 30;
617         unsigned int b = static_cast<unsigned int>(inColor[2] * 1023) << 20;
618         unsigned int g = static_cast<unsigned int>(inColor[1] * 1023) << 10;
619         unsigned int r = static_cast<unsigned int>(inColor[0] * 1023) << 0;
620
621         dstUint[0] = (a & 0xC0000000) | (b & 0x3FF00000) | (g & 0x000FFC00) | (r & 0x000003FF);
622 }
623
624 GLhalf InternalformatCaseBase::floatToHalf(float f)
625 {
626         const unsigned int HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP = 0x38000000;
627         // Max exponent value in single precision that will be converted
628         // to Inf or Nan when stored as a half-float
629         const unsigned int HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP = 0x47800000;
630         // 255 is the max exponent biased value
631         const unsigned int FLOAT_MAX_BIASED_EXP          = (0xFF << 23);
632         const unsigned int HALF_FLOAT_MAX_BIASED_EXP = (0x1F << 10);
633
634         char*            c      = reinterpret_cast<char*>(&f);
635         unsigned int x  = *reinterpret_cast<unsigned int*>(c);
636         unsigned int sign = static_cast<GLhalf>(x >> 31);
637
638         // Get mantissa
639         unsigned int mantissa = x & ((1 << 23) - 1);
640         // Get exponent bits
641         unsigned int exp = x & FLOAT_MAX_BIASED_EXP;
642
643         if (exp >= HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP)
644         {
645                 // Check if the original single precision float number is a NaN
646                 if (mantissa && (exp == FLOAT_MAX_BIASED_EXP))
647                 {
648                         // We have a single precision NaN
649                         mantissa = (1 << 23) - 1;
650                 }
651                 else
652                 {
653                         // 16-bit half-float representation stores number as Inf
654                         mantissa = 0;
655                 }
656                 return (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)(HALF_FLOAT_MAX_BIASED_EXP) | (GLhalf)(mantissa >> 13));
657         }
658         // Check if exponent is <= -15
659         else if (exp <= HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP)
660         {
661                 // Store a denorm half-float value or zero
662                 exp = (HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP - exp) >> 23;
663                 mantissa |= (1 << 23);
664                 mantissa >>= (14 + exp);
665                 return (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)(mantissa));
666         }
667
668         return (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)((exp - HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP) >> 13) |
669                                         (GLhalf)(mantissa >> 13));
670 }
671
672 class Texture2DCase : public InternalformatCaseBase
673 {
674 public:
675         Texture2DCase(deqp::Context& context, const std::string& name, const TextureFormat& textureFormat);
676         virtual ~Texture2DCase()
677         {
678         }
679
680         virtual tcu::TestNode::IterateResult iterate(void);
681
682 private:
683         TextureFormat m_testFormat;
684 };
685
686 Texture2DCase::Texture2DCase(deqp::Context& context, const std::string& name, const TextureFormat& testFormat)
687         : InternalformatCaseBase(context, name.c_str()), m_testFormat(testFormat)
688 {
689 }
690
691 tcu::TestNode::IterateResult Texture2DCase::iterate(void)
692 {
693         if (!requiredExtensionsSupported(m_testFormat.requiredExtension, m_testFormat.secondReqiredExtension))
694                 return STOP;
695
696         typedef std::map<GLenum, TextureFormat> ReferenceFormatMap;
697         static ReferenceFormatMap formatMap;
698         if (formatMap.empty())
699         {
700                 formatMap[GL_RED]                         = TextureFormat(GL_RED, GL_UNSIGNED_BYTE, GL_RED);
701                 formatMap[GL_RG]                          = TextureFormat(GL_RG, GL_UNSIGNED_BYTE, GL_RG);
702                 formatMap[GL_RGB]                         = TextureFormat(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB);
703                 formatMap[GL_RGBA]                        = TextureFormat(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB);
704                 formatMap[GL_RGBA_INTEGER]      = TextureFormat(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB);
705                 formatMap[GL_RGB_INTEGER]        = TextureFormat(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB);
706                 formatMap[GL_ALPHA]                       = TextureFormat(GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA);
707                 formatMap[GL_LUMINANCE]           = TextureFormat(GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE);
708                 formatMap[GL_LUMINANCE_ALPHA] = TextureFormat(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE_ALPHA);
709                 formatMap[GL_DEPTH_COMPONENT] = TextureFormat(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT);
710                 formatMap[GL_DEPTH_STENCIL] = TextureFormat(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL);
711
712                 if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 0)))
713                 {
714                         formatMap[GL_DEPTH_STENCIL] = TextureFormat(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8_OES);
715                 }
716         }
717
718         ReferenceFormatMap::iterator formatIterator = formatMap.find(m_testFormat.format);
719         if (formatIterator == formatMap.end())
720         {
721                 m_testCtx.getLog() << tcu::TestLog::Message << "Error: Unknown 2D texture format "
722                                                    << glu::getTextureFormatStr(m_testFormat.format).toString() << tcu::TestLog::EndMessage;
723                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
724                 return STOP;
725         }
726
727         const TextureFormat& referenceFormat = formatIterator->second;
728         glu::RenderContext&  renderContext   = m_context.getRenderContext();
729         const Functions&         gl                              = renderContext.getFunctions();
730
731         if (m_renderWidth > m_context.getRenderTarget().getWidth())
732                 m_renderWidth = m_context.getRenderTarget().getWidth();
733         if (m_renderHeight > m_context.getRenderTarget().getHeight())
734                 m_renderHeight = m_context.getRenderTarget().getHeight();
735
736         // Setup viewport
737         gl.viewport(0, 0, m_renderWidth, m_renderHeight);
738         gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
739
740         // Create test and reference texture
741         GLuint testTextureName = createTexture(m_testFormat.internalFormat, m_testFormat.format, m_testFormat.type,
742                                                                                    m_testFormat.minFilter, m_testFormat.magFilter);
743         GLuint referenceTextureName = createTexture(referenceFormat.internalFormat, referenceFormat.format,
744                                                                                                 referenceFormat.type, m_testFormat.minFilter, m_testFormat.magFilter);
745
746         // Create program that will render tested texture to screen
747         glu::ShaderProgram testProgram(
748                 renderContext,
749                 prepareTexturingProgramSources(m_testFormat.internalFormat, m_testFormat.format, m_testFormat.type));
750         if (!testProgram.isOk())
751         {
752                 m_testCtx.getLog() << testProgram;
753                 TCU_FAIL("Compile failed");
754         }
755         gl.useProgram(testProgram.getProgram());
756         gl.uniform1i(gl.getUniformLocation(testProgram.getProgram(), "sampler"), 0);
757
758         // Render textured quad with tested texture
759         gl.bindTexture(GL_TEXTURE_2D, testTextureName);
760         renderTexturedQuad(testProgram.getProgram());
761         tcu::Surface testSurface(m_renderWidth, m_renderHeight);
762         glu::readPixels(renderContext, 0, 0, testSurface.getAccess());
763
764         // Create program that will render reference texture to screen
765         glu::ProgramSources referenceSources =
766                 prepareTexturingProgramSources(referenceFormat.internalFormat, referenceFormat.format, referenceFormat.type);
767         glu::ShaderProgram referenceProgram(renderContext, referenceSources);
768         if (!referenceProgram.isOk())
769         {
770                 m_testCtx.getLog() << referenceProgram;
771                 TCU_FAIL("Compile failed");
772         }
773         gl.useProgram(referenceProgram.getProgram());
774         gl.uniform1i(gl.getUniformLocation(referenceProgram.getProgram(), "sampler"), 0);
775
776         // Render textured quad with reference texture
777         gl.bindTexture(GL_TEXTURE_2D, referenceTextureName);
778         renderTexturedQuad(referenceProgram.getProgram());
779         tcu::Surface referenceSurface(m_renderWidth, m_renderHeight);
780         glu::readPixels(renderContext, 0, 0, referenceSurface.getAccess());
781
782         // Compare surfaces
783         if (tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", referenceSurface, testSurface, 0.05f,
784                                                   tcu::COMPARE_LOG_RESULT))
785                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
786         else
787                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
788
789         gl.deleteTextures(1, &testTextureName);
790         gl.deleteTextures(1, &referenceTextureName);
791
792         return STOP;
793 }
794
795 class CopyTexImageCase : public InternalformatCaseBase
796 {
797 public:
798         CopyTexImageCase(deqp::Context& context, const std::string& name, const CopyTexImageFormat& copyTexImageFormat);
799         virtual ~CopyTexImageCase()
800         {
801         }
802
803         virtual tcu::TestNode::IterateResult iterate(void);
804
805 private:
806         CopyTexImageFormat m_testFormat;
807 };
808
809 CopyTexImageCase::CopyTexImageCase(deqp::Context& context, const std::string& name,
810                                                                    const CopyTexImageFormat& copyTexImageFormat)
811         : InternalformatCaseBase(context, name.c_str()), m_testFormat(copyTexImageFormat)
812 {
813 }
814
815 tcu::TestNode::IterateResult CopyTexImageCase::iterate(void)
816 {
817         if (!requiredExtensionsSupported(m_testFormat.requiredExtension, m_testFormat.secondReqiredExtension))
818                 return STOP;
819
820         glu::RenderContext& renderContext = m_context.getRenderContext();
821         const Functions&        gl                        = renderContext.getFunctions();
822
823         // Determine texture format and type
824         GLint  textureInternalFormat = m_testFormat.internalFormat;
825         GLuint textureType                       = getTypeFromInternalFormat(textureInternalFormat);
826         GLuint textureFormat             = getUnsizedFormatFromInternalFormat(textureInternalFormat);
827
828         // Create program that will render texture to screen
829         glu::ShaderProgram program(renderContext,
830                                                            prepareTexturingProgramSources(textureInternalFormat, textureFormat, textureType));
831         if (!program.isOk())
832         {
833                 m_testCtx.getLog() << program;
834                 TCU_FAIL("Compile failed");
835         }
836         gl.useProgram(program.getProgram());
837         gl.uniform1i(gl.getUniformLocation(program.getProgram(), "sampler"), 0);
838         gl.viewport(0, 0, m_renderWidth, m_renderHeight);
839
840         // Create required textures
841         GLuint referenceTextureId = createTexture(textureInternalFormat, textureFormat, textureType, m_testFormat.minFilter,
842                                                                                           m_testFormat.magFilter);
843         GLuint copiedTextureId = createTexture(textureInternalFormat, textureFormat, textureType, m_testFormat.minFilter,
844                                                                                    m_testFormat.magFilter, false);
845
846         // Create main RGBA framebuffer - this is needed because some default framebuffer may be RGB
847         GLuint mainFboId = 0;
848         gl.genFramebuffers(1, &mainFboId);
849         gl.bindFramebuffer(GL_FRAMEBUFFER, mainFboId);
850         GLuint mainFboColorTextureId = createTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, false);
851         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mainFboColorTextureId, 0);
852
853         // Render reference texture to main FBO and grab it
854         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
855         gl.bindTexture(GL_TEXTURE_2D, referenceTextureId);
856         renderTexturedQuad(program.getProgram());
857         tcu::Surface referenceSurface(m_renderWidth, m_renderHeight);
858         glu::readPixels(renderContext, 0, 0, referenceSurface.getAccess());
859
860         GLuint copyFboId                                  = 0;
861         GLuint copyFboColorTextureId      = 0;
862
863         // When possible use separate FBO for copy operation; create copy FBO and
864         // attach reference texture to color or depth attachment
865         gl.genFramebuffers(1, &copyFboId);
866         gl.bindFramebuffer(GL_FRAMEBUFFER, copyFboId);
867
868         if (textureFormat == GL_DEPTH_COMPONENT)
869         {
870                 copyFboColorTextureId = createTexture(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, false);
871                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyFboColorTextureId, 0);
872                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
873                 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, referenceTextureId, 0);
874                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
875         }
876         else
877         {
878                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, referenceTextureId, 0);
879                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
880         }
881
882         // If FBO is complete, then go back to use default FBO
883         GLenum bufferStatus = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
884         if (bufferStatus != GL_FRAMEBUFFER_COMPLETE)
885         {
886                 // Bind back to main FBO
887                 gl.bindFramebuffer(GL_FRAMEBUFFER, mainFboId);
888                 gl.deleteFramebuffers(1, &copyFboId);
889                 if (copyFboColorTextureId)
890                         gl.deleteTextures(1, &copyFboColorTextureId);
891                 // Check the bits of each channel first, because according the GLES3.2 spec, the component sizes of internalformat
892                 // must exactly match the corresponding component sizes of the source buffer's effective internal format.
893                 if (glu::isContextTypeES(renderContext.getType()) && getTypeFromInternalFormat(textureInternalFormat) != GL_UNSIGNED_BYTE)
894                 {
895                         m_testCtx.getLog() << tcu::TestLog::Message << "Not supported: The component sizes of internalformat do not exactly "
896                         << "match the corresponding component sizes of the source buffer's effective internal format." << tcu::TestLog::EndMessage;
897                         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "The test format isn't renderable, and the component sizes of "
898                         "internalformat do not exactly match the corresponding component sizes of the source buffer's effective internal format.");
899                         gl.deleteFramebuffers(1, &mainFboId);
900                         gl.deleteTextures(1, &mainFboColorTextureId);
901                         gl.deleteTextures(1, &copiedTextureId);
902                         gl.deleteTextures(1, &referenceTextureId);
903                         return STOP;
904                 }
905         }
906
907         // Copy attachment from copy FBO to tested texture (if copy FBO couldn't be created
908         // then copying will be done from main FBO color attachment)
909         gl.bindTexture(GL_TEXTURE_2D, copiedTextureId);
910         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
911         gl.copyTexImage2D(GL_TEXTURE_2D, 0, textureInternalFormat, 0, 0, m_renderWidth, m_renderHeight, 0);
912         GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyTexImage2D");
913
914         // Make sure that main FBO is bound
915         gl.bindFramebuffer(GL_FRAMEBUFFER, mainFboId);
916
917         // Render and grab tested texture
918         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
919         gl.bindTexture(GL_TEXTURE_2D, copiedTextureId);
920         renderTexturedQuad(program.getProgram());
921         tcu::Surface resultSurface(m_renderWidth, m_renderHeight);
922         glu::readPixels(renderContext, 0, 0, resultSurface.getAccess());
923
924         // Compare surfaces
925         if (tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", referenceSurface, resultSurface,
926                                                   0.05f, tcu::COMPARE_LOG_RESULT))
927                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
928         else
929                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
930
931         // Cleanup
932         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
933         gl.deleteFramebuffers(1, &mainFboId);
934         gl.deleteTextures(1, &mainFboColorTextureId);
935         gl.deleteTextures(1, &copiedTextureId);
936         gl.deleteTextures(1, &referenceTextureId);
937
938         return STOP;
939 }
940
941 class RenderbufferCase : public InternalformatCaseBase
942 {
943 public:
944         RenderbufferCase(deqp::Context& context, const std::string& name, const RenderbufferFormat& renderbufferFormat);
945         virtual ~RenderbufferCase();
946
947         virtual tcu::TestNode::IterateResult iterate(void);
948
949 private:
950         void constructOrthoProjMatrix(GLfloat* mat4, GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n,
951                                                                   GLfloat f) const;
952         bool   createFramebuffer();
953         void   deleteFramebuffer();
954         GLuint createAndAttachRenderBuffer(GLenum rbFormat, GLenum fbAttachment);
955         void renderColoredQuad(GLuint programId, const float* positions) const;
956         glu::ProgramSources prepareColoringProgramSources(GLenum format, GLenum type) const;
957         void convertUInt(const tcu::PixelBufferAccess &src, const tcu::PixelBufferAccess &dst);
958         void convertUInt_2_10_10_10_rev(const tcu::PixelBufferAccess &src, const tcu::PixelBufferAccess &dst);
959
960 private:
961         GLuint                     m_fbo;
962         GLuint                     m_rbColor;
963         GLuint                     m_rbDepth;
964         GLuint                     m_rbStencil;
965         RenderbufferFormat m_testFormat;
966 };
967
968 RenderbufferCase::RenderbufferCase(deqp::Context& context, const std::string& name,
969                                                                    const RenderbufferFormat& renderbufferFormat)
970         : InternalformatCaseBase(context, name.c_str())
971         , m_fbo(0)
972         , m_rbColor(0)
973         , m_rbDepth(0)
974         , m_rbStencil(0)
975         , m_testFormat(renderbufferFormat)
976 {
977 }
978
979 RenderbufferCase::~RenderbufferCase()
980 {
981 }
982
983 tcu::TestNode::IterateResult RenderbufferCase::iterate(void)
984 {
985         if (!requiredExtensionsSupported(m_testFormat.requiredExtension, m_testFormat.secondReqiredExtension))
986                 return STOP;
987
988         glu::RenderContext& renderContext = m_context.getRenderContext();
989         const Functions&        gl                        = renderContext.getFunctions();
990
991         int maxRenderbufferSize;
992         gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &maxRenderbufferSize);
993         int windowWidth  = m_context.getRenderTarget().getWidth();
994         int windowHeight = m_context.getRenderTarget().getHeight();
995         m_renderWidth   = (windowWidth > maxRenderbufferSize) ? maxRenderbufferSize : windowWidth;
996         m_renderHeight   = (windowHeight > maxRenderbufferSize) ? maxRenderbufferSize : windowHeight;
997
998         float                      w                                       = static_cast<float>(m_renderWidth);
999         float                      h                                       = static_cast<float>(m_renderHeight);
1000         static const float bigQuadPositionsSet[]   = { 0, 0, 0, w, 0, 0, 0, h, 0, w, h, 0 };
1001         static const float smallQuadPositionsSet[] = { 5.0f, 5.0f,  0.5f, w / 2, 5.0f,  0.5f,
1002                                                                                                    5.0f, h / 2, 0.5f, w / 2, h / 2, 0.5f };
1003
1004         bool stencilRenderbufferAvailable =
1005                 (m_testFormat.type == RENDERBUFFER_STENCIL) || (m_testFormat.type == RENDERBUFFER_DEPTH_STENCIL);
1006
1007         GLenum  testFormat = getUnsizedFormatFromInternalFormat(m_testFormat.format);
1008         GLenum  testType = getTypeFromInternalFormat(m_testFormat.format);
1009
1010         // We need surfaces for depth testing and stencil testing, and also for
1011         // storing the reference and the values for the format under testing
1012         tcu::Surface testSurface[2][2];
1013         for (GLuint loop1 = 0; loop1 < 2; loop1++)
1014         for (GLuint loop2 = 0; loop2 < 2; loop2++)
1015                 testSurface[loop1][loop2].setSize(m_renderWidth, m_renderHeight);
1016
1017         GLint defaultFramebufferDepthBits   = 0;
1018         GLint defaultFramebufferStencilBits = 0;
1019         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
1020         {
1021                 gl.getIntegerv(GL_DEPTH_BITS, &defaultFramebufferDepthBits);
1022                 gl.getIntegerv(GL_STENCIL_BITS, &defaultFramebufferStencilBits);
1023         }
1024         else
1025         {
1026                 GLint hasDepthBuffer    = 0;
1027                 GLint hasStencilBuffer  = 0;
1028
1029                 gl.getNamedFramebufferAttachmentParameteriv(0, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
1030                                                                                                         &hasDepthBuffer);
1031                 gl.getNamedFramebufferAttachmentParameteriv(0, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
1032                                                                                                         &hasStencilBuffer);
1033
1034                 if (hasDepthBuffer != GL_NONE)
1035                         gl.getNamedFramebufferAttachmentParameteriv(0, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
1036                                                                                                                 &defaultFramebufferDepthBits);
1037
1038                 if (hasStencilBuffer != GL_NONE)
1039                         gl.getNamedFramebufferAttachmentParameteriv(0, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
1040                                                                                                                 &defaultFramebufferStencilBits);
1041         }
1042
1043         // Create two programs for rendering, one for rendering into default FB, and
1044         // a second one to render in our created FB
1045
1046         glu::ShaderProgram program0(renderContext, prepareColoringProgramSources(GL_RGBA, GL_UNSIGNED_BYTE));
1047         glu::ShaderProgram program1(renderContext, prepareColoringProgramSources(testFormat, testType));
1048
1049         std::vector<glu::ShaderProgram*> programs;
1050         programs.push_back(&program0);
1051         programs.push_back(&program1);
1052
1053         bool testNonStencil = (m_testFormat.type != RENDERBUFFER_STENCIL);
1054         bool testStencil = defaultFramebufferStencilBits && stencilRenderbufferAvailable;
1055
1056         for (GLuint loop = 0; loop < 2; loop++)
1057         {
1058                 if (!programs[loop]->isOk())
1059                 {
1060                         m_testCtx.getLog() << *programs[loop];
1061                         TCU_FAIL("Compile failed");
1062                 }
1063
1064                 gl.useProgram(programs[loop]->getProgram());
1065                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1066
1067                 float mvpMatrix[16];
1068                 constructOrthoProjMatrix(mvpMatrix, 0.0, m_renderWidth, 0.0f, m_renderHeight, 1.0f, -1.0f);
1069                 GLint mvpUniformLocation = gl.getUniformLocation(programs[loop]->getProgram(), "mvpMatrix");
1070                 gl.uniformMatrix4fv(mvpUniformLocation, 1, 0, mvpMatrix);
1071
1072                 gl.bindTexture(GL_TEXTURE_2D, 0);
1073                 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1074                 gl.viewport(0, 0, m_renderWidth, m_renderHeight);
1075
1076                 if (testNonStencil)
1077                 {
1078                         if (loop && !createFramebuffer())
1079                                 return STOP;
1080
1081                         if (defaultFramebufferDepthBits)
1082                         {
1083                                 gl.enable(GL_DEPTH_TEST);
1084                                 gl.depthFunc(GL_LESS);
1085                         }
1086
1087                         gl.bindFramebuffer(GL_FRAMEBUFFER, loop ? m_fbo : m_context.getRenderContext().getDefaultFramebuffer());
1088                         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1089
1090                         if (defaultFramebufferDepthBits)
1091                         {
1092                                 // Draw a small quad just in the z buffer
1093                                 gl.colorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1094                                 renderColoredQuad(programs[loop]->getProgram(), smallQuadPositionsSet);
1095
1096                                 // Large quad should be drawn on top small one to verify that the depth test is working
1097                                 gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1098                         }
1099
1100                         // Draws large quad
1101                         renderColoredQuad(programs[loop]->getProgram(), bigQuadPositionsSet);
1102
1103                         if (loop && testFormat == GL_RGBA_INTEGER)
1104                         {
1105                                 de::ArrayBuffer<deUint32> pixels;
1106                                 pixels.setStorage(4 * m_renderWidth * m_renderHeight);
1107                                 tcu::PixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
1108                                                                                                    m_renderWidth, m_renderHeight, 1, pixels.getPtr());
1109                                 glu::readPixels(renderContext, 0, 0, pixelBuffer);
1110                                 if (testType == GL_UNSIGNED_INT_2_10_10_10_REV)
1111                                         convertUInt_2_10_10_10_rev(pixelBuffer, testSurface[0][loop].getAccess());
1112                                 else
1113                                         convertUInt(pixelBuffer, testSurface[0][loop].getAccess());
1114                         }
1115                         else
1116                         {
1117                                 glu::readPixels(renderContext, 0, 0, testSurface[0][loop].getAccess());
1118                         }
1119                 }
1120
1121                 if (loop)
1122                         deleteFramebuffer();
1123
1124                 if (defaultFramebufferStencilBits && stencilRenderbufferAvailable)
1125                 {
1126                         gl.disable(GL_DEPTH_TEST);
1127                         gl.enable(GL_STENCIL_TEST);
1128
1129                         if (loop && !createFramebuffer())
1130                                 return STOP;
1131
1132                         gl.bindFramebuffer(GL_FRAMEBUFFER, loop ? m_fbo : m_context.getRenderContext().getDefaultFramebuffer());
1133                         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1134
1135                         // Draw a rect scissored to half the screen height, incrementing the stencil buffer.
1136                         gl.enable(GL_SCISSOR_TEST);
1137                         gl.scissor(0, 0, m_renderWidth, m_renderHeight / 2);
1138                         gl.stencilFunc(GL_ALWAYS, 0x0, 0xFF);
1139                         gl.stencilOp(GL_ZERO, GL_INCR, GL_INCR);
1140                         GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp");
1141                         renderColoredQuad(programs[loop]->getProgram(), bigQuadPositionsSet);
1142                         gl.disable(GL_SCISSOR_TEST);
1143
1144                         // Only draw where stencil is equal to 1
1145                         gl.stencilFunc(GL_EQUAL, 0x01, 0xFF);
1146                         gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1147                         gl.clear(GL_COLOR_BUFFER_BIT);
1148                         renderColoredQuad(programs[loop]->getProgram(), bigQuadPositionsSet);
1149
1150                         glu::readPixels(renderContext, 0, 0, testSurface[1][loop].getAccess());
1151
1152                         gl.disable(GL_STENCIL_TEST);
1153
1154                         if (loop)
1155                                 deleteFramebuffer();
1156                 }
1157         }
1158
1159         // Compare surfaces for non-stencil
1160         if (testNonStencil && !tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result",
1161                                                                                          testSurface[0][0], testSurface[0][1],
1162                                                                                          0.05f, tcu::COMPARE_LOG_RESULT))
1163         {
1164                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Depth subtest failed");
1165                 return STOP;
1166         }
1167
1168         // Compare surfaces for stencil
1169         if (testStencil && !tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result",
1170                                                                                   testSurface[1][0], testSurface[1][1],
1171                                                                                   0.05f, tcu::COMPARE_LOG_RESULT))
1172         {
1173                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Stencil subtest failed");
1174                 return STOP;
1175         }
1176
1177         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1178         return STOP;
1179 }
1180
1181 void RenderbufferCase::constructOrthoProjMatrix(GLfloat* mat4, GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n,
1182                                                                                                 GLfloat f) const
1183 {
1184         GLfloat inv_width  = 1.0f / (r - l);
1185         GLfloat inv_height = 1.0f / (t - b);
1186         GLfloat inv_depth  = 1.0f / (f - n);
1187
1188         memset(mat4, 0, sizeof(GLfloat) * 16);
1189         /*
1190         0    4    8    12
1191         1    5    9    13
1192         2    6    10    14
1193         3    7    11    15
1194     */
1195
1196         mat4[0]  = 2.0f * inv_width;
1197         mat4[5]  = 2.0f * inv_height;
1198         mat4[10] = 2.0f * inv_depth;
1199
1200         mat4[12] = -(r + l) * inv_width;
1201         mat4[13] = -(t + b) * inv_height;
1202         mat4[14] = -(f + n) * inv_depth;
1203         mat4[15] = 1.0f;
1204 }
1205
1206 bool RenderbufferCase::createFramebuffer()
1207 {
1208         glu::RenderContext& renderContext = m_context.getRenderContext();
1209         const Functions&        gl                        = renderContext.getFunctions();
1210
1211         gl.genFramebuffers(1, &m_fbo);
1212         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
1213
1214         if (m_testFormat.type == RENDERBUFFER_COLOR)
1215         {
1216                 m_rbColor = createAndAttachRenderBuffer(m_testFormat.format, GL_COLOR_ATTACHMENT0);
1217                 m_rbDepth = createAndAttachRenderBuffer(GL_DEPTH_COMPONENT16, GL_DEPTH_ATTACHMENT);
1218         }
1219         else
1220         {
1221                 m_rbColor = createAndAttachRenderBuffer(GL_RGBA8, GL_COLOR_ATTACHMENT0);
1222                 if (m_testFormat.type == RENDERBUFFER_DEPTH)
1223                         m_rbDepth = createAndAttachRenderBuffer(m_testFormat.format, GL_DEPTH_ATTACHMENT);
1224                 else if (m_testFormat.type == RENDERBUFFER_STENCIL)
1225                         m_rbStencil = createAndAttachRenderBuffer(m_testFormat.format, GL_STENCIL_ATTACHMENT);
1226                 else if (m_testFormat.type == RENDERBUFFER_DEPTH_STENCIL)
1227                 {
1228                         if (glu::contextSupports(renderContext.getType(), glu::ApiType::es(2, 0)))
1229                         {
1230                                 m_rbDepth = createAndAttachRenderBuffer(m_testFormat.format, GL_DEPTH_ATTACHMENT);
1231                                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbDepth);
1232                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer");
1233                         }
1234                         else
1235                                 m_rbDepth = createAndAttachRenderBuffer(m_testFormat.format, GL_DEPTH_STENCIL_ATTACHMENT);
1236                 }
1237         }
1238
1239         GLenum bufferStatus = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1240         if (bufferStatus == GL_FRAMEBUFFER_UNSUPPORTED)
1241         {
1242                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Unsuported framebuffer");
1243                 return false;
1244         }
1245         else if (bufferStatus != GL_FRAMEBUFFER_COMPLETE)
1246         {
1247                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Framebuffer not complete");
1248                 return false;
1249         }
1250
1251         return true;
1252 }
1253
1254 void RenderbufferCase::deleteFramebuffer()
1255 {
1256         const Functions& gl = m_context.getRenderContext().getFunctions();
1257
1258         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1259         if (m_fbo)
1260                 gl.deleteFramebuffers(1, &m_fbo);
1261         if (m_rbColor)
1262                 gl.deleteRenderbuffers(1, &m_rbColor);
1263         if (m_rbDepth)
1264                 gl.deleteRenderbuffers(1, &m_rbDepth);
1265         if (m_rbStencil)
1266                 gl.deleteRenderbuffers(1, &m_rbStencil);
1267 }
1268
1269 GLuint RenderbufferCase::createAndAttachRenderBuffer(GLenum rbFormat, GLenum fbAttachment)
1270 {
1271         const Functions& gl = m_context.getRenderContext().getFunctions();
1272
1273         GLuint rbName;
1274
1275         gl.genRenderbuffers(1, &rbName);
1276         gl.bindRenderbuffer(GL_RENDERBUFFER, rbName);
1277         gl.renderbufferStorage(GL_RENDERBUFFER, rbFormat, m_renderWidth, m_renderHeight);
1278         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage");
1279         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, fbAttachment, GL_RENDERBUFFER, rbName);
1280         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer");
1281
1282         return rbName;
1283 }
1284
1285 void RenderbufferCase::renderColoredQuad(GLuint programId, const float* positions) const
1286 {
1287         // Prepare data for rendering
1288         static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
1289         static const float      colors[]                = {
1290                 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1291         };
1292         const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 3, 4, 0, positions),
1293                                                                                                          glu::va::Float("color", 4, 4, 0, colors) };
1294
1295         glu::draw(m_context.getRenderContext(), programId, DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
1296                           glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
1297 }
1298
1299 glu::ProgramSources RenderbufferCase::prepareColoringProgramSources(GLenum format, GLenum type) const
1300 {
1301         glu::RenderContext& renderContext         = m_context.getRenderContext();
1302         glu::ContextType        contextType                = renderContext.getType();
1303         glu::GLSLVersion        glslVersion                = glu::getContextTypeGLSLVersion(contextType);
1304         std::string                     versionDeclaration = glu::getGLSLVersionDeclaration(glslVersion);
1305
1306         std::map<std::string, std::string>      specializationMap;
1307
1308         versionDeclaration += "\n";
1309         std::string vs = versionDeclaration;
1310         std::string fs = versionDeclaration;
1311         if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)) || glu::isContextTypeGLCore(contextType))
1312         {
1313                 vs += "in highp vec3 position;\n"
1314                           "in highp vec4 color;\n"
1315                           "out highp vec4 fColor;\n"
1316                           "uniform mat4 mvpMatrix;\n"
1317                           "void main()\n"
1318                           "{\n"
1319                           "  fColor = color;\n"
1320                           "  gl_Position = mvpMatrix * vec4(position, 1.0);\n"
1321                           "}\n";
1322                 fs += "in highp vec4 fColor;\n"
1323                           "out ${COLOR_DATA} color;\n"
1324                           "void main()\n"
1325                           "{\n"
1326                           "  color = ${COMPUTE_COLOR};\n"
1327                           "}\n";
1328         }
1329         else
1330         {
1331                 vs += "attribute highp vec3 position;\n"
1332                           "attribute highp vec4 color;\n"
1333                           "varying highp vec4 fColor;\n"
1334                           "uniform mat4 mvpMatrix;\n"
1335                           "void main()\n"
1336                           "{\n"
1337                           "  fColor = color;\n"
1338                           "  gl_Position = mvpMatrix * vec4(position, 1.0);\n"
1339                           "}\n";
1340                 fs += "varying highp vec4 fColor;\n"
1341                           "void main()\n"
1342                           "{\n"
1343                           "  gl_FragColor = fColor;\n"
1344                           "}\n";
1345         }
1346
1347         if (format == GL_RGBA_INTEGER)
1348         {
1349                 std::string compute_color = "${COLOR_DATA}("
1350                         "${MAX_RED} * fColor.r, "
1351                         "${MAX_GREEN} * fColor.g, "
1352                         "${MAX_BLUE} * fColor.b, "
1353                         "${MAX_ALPHA} * fColor.a)";
1354
1355                 if (type == GL_UNSIGNED_INT_2_10_10_10_REV)
1356                 {
1357                         specializationMap["MAX_RED"] = "1023";
1358                         specializationMap["MAX_GREEN"] = "1023";
1359                         specializationMap["MAX_BLUE"] = "1023";
1360                         specializationMap["MAX_ALPHA"] = "3";
1361                 }
1362                 else
1363                 {
1364                         specializationMap["MAX_RED"] = "255";
1365                         specializationMap["MAX_GREEN"] = "255";
1366                         specializationMap["MAX_BLUE"] = "255";
1367                         specializationMap["MAX_ALPHA"] = "255";
1368                 }
1369                 specializationMap["COLOR_DATA"] = "uvec4";
1370                 specializationMap["COMPUTE_COLOR"] = tcu::StringTemplate(compute_color).specialize(specializationMap);
1371         }
1372         else
1373         {
1374                 specializationMap["COLOR_DATA"] = "highp vec4";
1375                 specializationMap["COMPUTE_COLOR"] = "fColor";
1376         }
1377
1378         vs = tcu::StringTemplate(vs).specialize(specializationMap);
1379         fs = tcu::StringTemplate(fs).specialize(specializationMap);
1380         return glu::makeVtxFragSources(vs.c_str(), fs.c_str());
1381 }
1382
1383 typedef TextureFormat     TF;
1384 typedef CopyTexImageFormat CF;
1385 typedef RenderbufferFormat RF;
1386
1387 struct TestData
1388 {
1389         std::vector<TextureFormat>              texture2DFormats;
1390         std::vector<CopyTexImageFormat> copyTexImageFormats;
1391         std::vector<RenderbufferFormat> renderbufferFormats;
1392 };
1393
1394 /** Constructor.
1395  *
1396  *  @param context Rendering context.
1397  */
1398 InternalformatTests::InternalformatTests(deqp::Context& context)
1399         : TestCaseGroup(context, "internalformat", "Texture internalformat tests")
1400 {
1401 }
1402
1403 template <typename Data, unsigned int Size>
1404 void InternalformatTests::append(std::vector<Data>& dataVector, const Data (&dataArray)[Size])
1405 {
1406         dataVector.insert(dataVector.end(), dataArray, dataArray + Size);
1407 }
1408
1409 void InternalformatTests::getESTestData(TestData& testData, glu::ContextType& contextType)
1410 {
1411         TextureFormat commonTexture2DFormats[] = {
1412                 TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA),
1413                 TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB),
1414                 TF(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA),
1415                 TF(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE_ALPHA),
1416                 TF(GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE),
1417                 TF(GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA),
1418                 TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGBA, EXT_texture_type_2_10_10_10_REV),
1419                 TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2, EXT_texture_type_2_10_10_10_REV),
1420                 TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB5_A1, EXT_texture_type_2_10_10_10_REV),
1421                 TF(GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB, EXT_texture_type_2_10_10_10_REV),
1422                 TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT, OES_depth_texture),
1423                 TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT, OES_depth_texture),
1424                 TF(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL, OES_packed_depth_stencil, OES_depth_texture),
1425                 TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F, OES_texture_half_float),
1426                 TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, OES_texture_half_float),
1427                 TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
1428                 TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
1429                 TF(GL_RGB, GL_FLOAT, GL_RGB32F, OES_texture_float),
1430                 TF(GL_RGBA, GL_FLOAT, GL_RGBA32F, OES_texture_float),
1431                 TF(GL_RGB, GL_FLOAT, GL_RGB32F, OES_texture_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
1432                 TF(GL_RGBA, GL_FLOAT, GL_RGBA32F, OES_texture_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
1433         };
1434
1435         CopyTexImageFormat commonCopyTexImageFormats[] = {
1436                 CF(GL_RGB),
1437                 CF(GL_RGBA),
1438                 CF(GL_ALPHA),
1439                 CF(GL_LUMINANCE),
1440                 CF(GL_LUMINANCE_ALPHA),
1441         };
1442
1443         RenderbufferFormat commonRenderbufferFormats[] = {
1444                 RF(GL_RGBA8, RENDERBUFFER_COLOR, OES_rgb8_rgba8),
1445                 RF(GL_RGB8, RENDERBUFFER_COLOR, OES_rgb8_rgba8),
1446         };
1447
1448         append(testData.texture2DFormats, commonTexture2DFormats);
1449         append(testData.copyTexImageFormats, commonCopyTexImageFormats);
1450         append(testData.renderbufferFormats, commonRenderbufferFormats);
1451
1452         if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)))
1453         {
1454                 TextureFormat es3Texture2DFormats[] = {
1455                         TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA4),
1456                         TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB5_A1),
1457                         TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB565),
1458                         TF(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4),
1459                         TF(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA),
1460                         TF(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1),
1461                         TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB),
1462                         TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565),
1463                         TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8),
1464                         TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8),
1465                         TF(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8),
1466                 };
1467
1468                 CopyTexImageFormat es3CopyTexImageFormats[] = {
1469                         CF(GL_RGBA4),
1470                         CF(GL_RGB5_A1),
1471                         CF(GL_RGB565),
1472                         CF(GL_RGBA8),
1473                         CF(GL_RGB8),
1474                 };
1475
1476                 RenderbufferFormat es3RenderbufferFormats[] = {
1477                         RF(GL_RGB5_A1, RENDERBUFFER_COLOR),
1478                 };
1479
1480                 append(testData.texture2DFormats, es3Texture2DFormats);
1481                 append(testData.copyTexImageFormats, es3CopyTexImageFormats);
1482                 append(testData.renderbufferFormats, es3RenderbufferFormats);
1483         }
1484         else if (glu::contextSupports(contextType, glu::ApiType::es(2, 0)))
1485         {
1486                 TextureFormat es2Texture2DFormats[] = {
1487                         TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB5_A1, OES_required_internalformat),
1488                         TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA4, OES_required_internalformat),
1489                         TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB565, OES_required_internalformat),
1490                         TF(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, OES_required_internalformat),
1491                         TF(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA, OES_required_internalformat),
1492                         TF(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, OES_required_internalformat),
1493                         TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, OES_required_internalformat),
1494                         TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565, OES_required_internalformat),
1495                         TF(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_OES, OES_required_internalformat),
1496                         TF(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE4_ALPHA4_OES, OES_required_internalformat),
1497                         TF(GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_OES, OES_required_internalformat),
1498                         TF(GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_OES, OES_required_internalformat),
1499                         TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT16, OES_required_internalformat,
1500                            OES_depth_texture),
1501                         TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16, OES_required_internalformat,
1502                            OES_depth_texture),
1503                         TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT24, OES_required_internalformat, OES_depth24),
1504                         TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32, OES_required_internalformat, OES_depth32),
1505                 };
1506
1507                 CopyTexImageFormat es2CopyTexImageFormats[] = {
1508                         CF(GL_RGB5_A1, OES_required_internalformat),
1509                         CF(GL_RGB565, OES_required_internalformat),
1510                         CF(GL_RGBA4, OES_required_internalformat),
1511                         CF(GL_LUMINANCE4_ALPHA4_OES, OES_required_internalformat),
1512                         CF(GL_LUMINANCE8_ALPHA8_OES, OES_required_internalformat),
1513                         CF(GL_LUMINANCE8_OES, OES_required_internalformat),
1514                         CF(GL_ALPHA8_OES, OES_required_internalformat),
1515                         CF(GL_RGB10_A2, EXT_texture_type_2_10_10_10_REV, OES_required_internalformat),
1516                         CF(GL_RGB10, EXT_texture_type_2_10_10_10_REV, OES_required_internalformat)
1517                 };
1518
1519                 RenderbufferFormat es2RenderbufferFormats[] = {
1520                         RF(GL_STENCIL_INDEX1, RENDERBUFFER_STENCIL, OES_stencil1),
1521                         RF(GL_STENCIL_INDEX4, RENDERBUFFER_STENCIL, OES_stencil4),
1522                         RF(GL_STENCIL_INDEX8, RENDERBUFFER_STENCIL, OES_stencil8),
1523                         RF(GL_DEPTH_COMPONENT16, RENDERBUFFER_DEPTH, OES_depth_texture),
1524                         RF(GL_DEPTH_COMPONENT24, RENDERBUFFER_DEPTH, OES_depth24),
1525                         RF(GL_DEPTH_COMPONENT32, RENDERBUFFER_DEPTH, OES_depth32),
1526                         RF(GL_DEPTH24_STENCIL8, RENDERBUFFER_DEPTH_STENCIL, OES_packed_depth_stencil),
1527                         RF(GL_RGB5_A1, RENDERBUFFER_COLOR, OES_required_internalformat),
1528                 };
1529
1530                 append(testData.texture2DFormats, es2Texture2DFormats);
1531                 append(testData.copyTexImageFormats, es2CopyTexImageFormats);
1532                 append(testData.renderbufferFormats, es2RenderbufferFormats);
1533         }
1534 }
1535
1536 void InternalformatTests::getGLTestData(TestData& testData, glu::ContextType&)
1537 {
1538         TextureFormat commonTexture2DFormats[] = {
1539                 TF(GL_RED, GL_BYTE, GL_R8_SNORM),
1540                 TF(GL_RED, GL_SHORT, GL_R16_SNORM),
1541                 TF(GL_RG, GL_BYTE, GL_RG8_SNORM),
1542                 TF(GL_RG, GL_SHORT, GL_RG16_SNORM),
1543                 TF(GL_RGB, GL_BYTE, GL_RGB8_SNORM),
1544                 TF(GL_RGB, GL_SHORT, GL_RGB16_SNORM),
1545                 TF(GL_RGBA, GL_BYTE, GL_RGBA8_SNORM),
1546                 TF(GL_RGBA, GL_SHORT, GL_RGBA16_SNORM),
1547                 TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGBA),
1548                 TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2),
1549                 TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB5_A1),
1550                 TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT, ARB_depth_texture),
1551                 TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16, ARB_depth_texture),
1552                 TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT, ARB_depth_texture),
1553                 TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT24, ARB_depth_texture),
1554                 TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32, ARB_depth_texture),
1555                 TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT16, ARB_depth_texture),
1556                 TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB9_E5, EXT_texture_shared_exponent),
1557                 TF(GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI, ARB_texture_rgb10_a2ui),
1558                 TF(GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI, EXT_texture_integer),
1559                 TF(GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI, EXT_texture_integer),
1560                 TF(GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI, EXT_texture_integer),
1561                 TF(GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI, EXT_texture_integer),
1562                 TF(GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI, EXT_texture_integer),
1563                 TF(GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI, EXT_texture_integer),
1564                 TF(GL_RGBA_INTEGER, GL_INT, GL_RGBA32I, EXT_texture_integer),
1565                 TF(GL_RGB_INTEGER, GL_INT, GL_RGB32I, EXT_texture_integer),
1566                 TF(GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I, EXT_texture_integer),
1567                 TF(GL_RGB_INTEGER, GL_SHORT, GL_RGB16I, EXT_texture_integer),
1568                 TF(GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I, EXT_texture_integer),
1569                 TF(GL_RGB_INTEGER, GL_BYTE, GL_RGB8I, EXT_texture_integer),
1570                 TF(GL_RED, GL_HALF_FLOAT, GL_R16F, ARB_texture_float),
1571                 TF(GL_RG, GL_HALF_FLOAT, GL_RG16F, ARB_texture_float),
1572                 TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F, ARB_texture_float),
1573                 TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, ARB_texture_float),
1574                 TF(GL_RED, GL_FLOAT, GL_R32F, ARB_texture_float),
1575                 TF(GL_RG, GL_FLOAT, GL_RG32F, ARB_texture_float),
1576                 TF(GL_RGB, GL_FLOAT, GL_RGB32F, ARB_texture_float),
1577                 TF(GL_RGBA, GL_FLOAT, GL_RGBA32F, ARB_texture_float),
1578         };
1579
1580         CopyTexImageFormat commonCopyTexImageFormats[] = {
1581                 CF(GL_DEPTH_COMPONENT16, ARB_depth_texture),
1582                 CF(GL_DEPTH_COMPONENT24, ARB_depth_texture),
1583                 CF(GL_DEPTH_COMPONENT32, ARB_depth_texture),
1584                 CF(GL_RGB9_E5, EXT_texture_shared_exponent),
1585                 CF(GL_RGB10_A2UI, ARB_texture_rgb10_a2ui),
1586                 CF(GL_RGB10_A2),
1587         };
1588
1589         RenderbufferFormat commonRenderbufferFormats[] = {
1590                 RF(GL_RGBA8, RENDERBUFFER_COLOR),
1591                 RF(GL_RGB9_E5, RENDERBUFFER_COLOR, EXT_texture_shared_exponent),
1592                 RF(GL_RGB10_A2UI, RENDERBUFFER_COLOR, ARB_texture_rgb10_a2ui),
1593                 RF(GL_DEPTH24_STENCIL8, RENDERBUFFER_DEPTH_STENCIL),
1594                 RF(GL_DEPTH_COMPONENT16, RENDERBUFFER_DEPTH, ARB_depth_texture),
1595                 RF(GL_DEPTH_COMPONENT24, RENDERBUFFER_DEPTH, ARB_depth_texture),
1596                 RF(GL_DEPTH_COMPONENT32, RENDERBUFFER_DEPTH, ARB_depth_texture),
1597         };
1598
1599         append(testData.texture2DFormats, commonTexture2DFormats);
1600         append(testData.copyTexImageFormats, commonCopyTexImageFormats);
1601         append(testData.renderbufferFormats, commonRenderbufferFormats);
1602 }
1603
1604 std::string formatToString(GLenum format)
1605 {
1606         // this function extends glu::getTextureFormatStr by formats used in thise tests
1607
1608         typedef std::map<GLenum, std::string> FormatMap;
1609         static FormatMap formatMap;
1610         if (formatMap.empty())
1611         {
1612                 // store in map formats that are not supported by glu::getTextureFormatStr
1613                 formatMap[GL_LUMINANCE8_ALPHA8_OES] = "luminance8_alpha8_oes";
1614                 formatMap[GL_LUMINANCE4_ALPHA4_OES] = "luminance4_alpha4_oes";
1615                 formatMap[GL_STENCIL_INDEX1_OES]        = "stencil_index1_oes";
1616                 formatMap[GL_STENCIL_INDEX4_OES]        = "stencil_index4_oes";
1617                 formatMap[GL_LUMINANCE8_OES]            = "luminance8_oes";
1618                 formatMap[GL_ALPHA8_OES]                        = "alpha8_oes";
1619         }
1620
1621         FormatMap::iterator it = formatMap.find(format);
1622         if (it == formatMap.end())
1623         {
1624                 // if format is not in map try glu function
1625                 std::string formatString = glu::getTextureFormatStr(format).toString();
1626
1627                 // cut out "GL_" from string
1628                 formatString = formatString.substr(3, formatString.length());
1629
1630                 // make lower case
1631                 std::transform(formatString.begin(), formatString.end(), formatString.begin(), tolower);
1632
1633                 return formatString;
1634         }
1635         return it->second;
1636 }
1637
1638 /** Initializes the test group contents. */
1639 void InternalformatTests::init()
1640 {
1641         // Determine which data sets should be used for tests
1642         TestData                 testData;
1643         glu::ContextType contextType = m_context.getRenderContext().getType();
1644         if (glu::isContextTypeGLCore(contextType))
1645                 getGLTestData(testData, contextType);
1646         else
1647                 getESTestData(testData, contextType);
1648
1649         // Construct texture2d tests
1650         TestCaseGroup* texture2DGroup = new deqp::TestCaseGroup(m_context, "texture2d", "");
1651         for (unsigned int i = 0; i < testData.texture2DFormats.size(); i++)
1652         {
1653                 const TextureFormat& tf                         = testData.texture2DFormats[i];
1654                 std::string                      format                 = formatToString(tf.format);
1655                 std::string                      type                   = glu::getTypeStr(tf.type).toString();
1656                 std::string                      internalFormat = formatToString(tf.internalFormat);
1657
1658                 // cut out "GL_" from type and make it lowercase
1659                 type = type.substr(3, type.length());
1660                 std::transform(type.begin(), type.end(), type.begin(), tolower);
1661
1662                 std::string name = format + "_" + type + "_" + internalFormat;
1663                 if (tf.minFilter == GL_LINEAR)
1664                         name += "_linear";
1665
1666                 texture2DGroup->addChild(new Texture2DCase(m_context, name, tf));
1667         }
1668         addChild(texture2DGroup);
1669
1670         // Construct copy_text_image tests
1671         TestCaseGroup* copyTexImageGroup = new deqp::TestCaseGroup(m_context, "copy_tex_image", "");
1672         for (unsigned int i = 0; i < testData.copyTexImageFormats.size(); i++)
1673         {
1674                 const CopyTexImageFormat& ctif = testData.copyTexImageFormats[i];
1675                 std::string                               name = formatToString(ctif.internalFormat);
1676                 copyTexImageGroup->addChild(new CopyTexImageCase(m_context, name, ctif));
1677         }
1678         addChild(copyTexImageGroup);
1679
1680         // Construct renderbuffer tests
1681         TestCaseGroup* renderbufferGroup = new deqp::TestCaseGroup(m_context, "renderbuffer", "");
1682         for (unsigned int i = 0; i < testData.renderbufferFormats.size(); i++)
1683         {
1684                 const RenderbufferFormat& rbf  = testData.renderbufferFormats[i];
1685                 std::string                               name = formatToString(rbf.format);
1686                 renderbufferGroup->addChild(new RenderbufferCase(m_context, name, rbf));
1687         }
1688         addChild(renderbufferGroup);
1689 }
1690
1691 void RenderbufferCase::convertUInt(const tcu::PixelBufferAccess &src, const tcu::PixelBufferAccess &dst)
1692 {
1693         for (int z = 0; z < dst.getDepth(); ++z)
1694         for (int y = 0; y < dst.getHeight(); ++y)
1695         for (int x = 0; x < dst.getWidth(); ++x)
1696         {
1697                 tcu::UVec4 srcPixel = src.getPixelUint(x, y, z);
1698                 tcu::Vec4 dstPixel(srcPixel.x() / 255.0f, srcPixel.y() / 255.0f, srcPixel.z() / 255.0f, srcPixel.w() / 255.0f);
1699                 dst.setPixel(dstPixel, x, y, z);
1700         }
1701 }
1702
1703 void RenderbufferCase::convertUInt_2_10_10_10_rev(const tcu::PixelBufferAccess &src, const tcu::PixelBufferAccess &dst)
1704 {
1705         for (int z = 0; z < dst.getDepth(); ++z)
1706         for (int y = 0; y < dst.getHeight(); ++y)
1707         for (int x = 0; x < dst.getWidth(); ++x)
1708         {
1709                 tcu::UVec4 srcPixel = src.getPixelUint(x, y, z);
1710                 tcu::Vec4 dstPixel(srcPixel.x() / 1023.0f, srcPixel.y() / 1023.0f, srcPixel.z() / 1023.0f, srcPixel.w() / 3.0f);
1711                 dst.setPixel(dstPixel, x, y, z);
1712         }
1713 }
1714 } /* glcts namespace */