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