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