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 ©TexImageFormat);
~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 ©TexImageFormat)
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, ©FboId);
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, ©FboId);
1020 if (copyFboColorTextureId)
1021 gl.deleteTextures(1, ©FboColorTextureId);
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