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