• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &copyFboId);
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, &copyFboId);
1017 		if (copyFboColorTextureId)
1018 			gl.deleteTextures(1, &copyFboColorTextureId);
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