• 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 <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, &copyFboId);
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, &copyFboId);
884 		if (copyFboColorTextureId)
885 			gl.deleteTextures(1, &copyFboColorTextureId);
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