• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2020 The Khronos Group Inc.
6 * Copyright (c) 2020 Intel Corporation
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */ /*!
21 * \file  glcPixelStorageModesTests.cpp
22 * \brief Conformance tests for usage of pixel storage modes.
23 */ /*-------------------------------------------------------------------*/
24 
25 #include "stdlib.h"
26 #include "tcuRenderTarget.hpp"
27 #include "tcuSurface.hpp"
28 #include "tcuTextureUtil.hpp"
29 #include "tcuTestCase.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuDefs.hpp"
32 #include "tcuFloat.hpp"
33 #include "tcuStringTemplate.hpp"
34 #include "gluRenderContext.hpp"
35 #include "gluShaderProgram.hpp"
36 #include "gluShaderUtil.hpp"
37 #include "gluContextInfo.hpp"
38 #include "gluObjectWrapper.hpp"
39 #include "gluCallLogWrapper.hpp"
40 #include "gluPixelTransfer.hpp"
41 #include "gluTexture.hpp"
42 #include "gluTextureUtil.hpp"
43 #include "gluDrawUtil.hpp"
44 #include "gluDefs.hpp"
45 #include "sglrGLContext.hpp"
46 #include "sglrContextWrapper.hpp"
47 #include "sglrContextUtil.hpp"
48 #include "glwFunctions.hpp"
49 #include "glwEnums.hpp"
50 #include "deStringUtil.hpp"
51 #include "deUniquePtr.hpp"
52 #include "glsTextureTestUtil.hpp"
53 #include "glcPixelStorageModesTests.hpp"
54 
55 #include <algorithm>
56 
57 namespace glcts
58 {
59 
60 static const char* const vs_template_src =
61 	"${GLSL_VERSION}\n"
62 	"in highp vec4 pos;\n"
63 	"out highp ${TEXCOORDS_TYPE} texcoords;\n"
64 	"${LAYER}\n"
65 	"void main (void)\n"
66 	"{\n"
67 	"	 texcoords = ${TEXCOORDS};\n"
68 	"	 gl_Position = pos;\n"
69 	"}\n";
70 
71 static const char* const fs_template_src =
72 	"${GLSL_VERSION}\n"
73 	"precision highp float;\n"
74 	"precision highp int;\n"
75 	"out vec4 fragColour;\n"
76 	"in ${TEXCOORDS_TYPE} texcoords;\n"
77 	"uniform highp ${SAMPLER_TYPE} sampler;\n"
78 	"uniform ${COL_TYPE} refcolour;\n"
79 	"void main (void)\n"
80 	"{\n"
81 	"	 ${COL_TYPE} colour = texelFetch(sampler, i${TEXCOORDS_TYPE}(texcoords), 0);\n"
82 	"	 if (${CONDITION})\n"
83 	"		 fragColour = vec4(0.0, 1.0, 0.0, 1.0);\n"
84 	"	 else\n"
85 	"		 fragColour = vec4(colour);\n"
86 	"}\n";
87 
getEps(deUint32 internalFormat)88 double getEps(deUint32 internalFormat)
89 {
90 	double eps = 0.0;
91 	switch (internalFormat)
92 	{
93 	case GL_RGBA4:
94 		eps = 1.0 / (double)(1 << 4);
95 		break;
96 	case GL_RGB565:
97 	case GL_RGB5_A1:
98 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
99 		eps = 1.0 / (double)(1 << 5);
100 		break;
101 	case GL_R8:
102 	case GL_R8_SNORM:
103 	case GL_RG8:
104 	case GL_RG8_SNORM:
105 	case GL_RGB8:
106 	case GL_SRGB8:
107 	case GL_RGB8_SNORM:
108 	case GL_RGBA8:
109 	case GL_SRGB8_ALPHA8:
110 	case GL_RGBA8_SNORM:
111 		eps = 1.0 / (double)(1 << 8);
112 		break;
113 	case GL_RGB9_E5:
114 		eps = 1.0 / (double)(1 << 9);
115 		break;
116 	case GL_R11F_G11F_B10F:
117 	case GL_RGB10_A2:
118 		eps = 1.0 / (double)(1 << 10);
119 		break;
120 	case GL_R16F:
121 	case GL_RG16F:
122 	case GL_RGB16F:
123 	case GL_RGBA16F:
124 	case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
125 		eps = 1.0 / (double)(1 << 16);
126 		break;
127 	case GL_R32F:
128 	case GL_RG32F:
129 	case GL_RGB32F:
130 	case GL_RGBA32F:
131 		eps = 1.0 / (double)(1 << 31);
132 		break;
133 	default:
134 		TCU_FAIL("Invalid internal format");
135 	}
136 
137 	return std::max(0.01, eps);
138 }
139 
inrange(int x,int left,int right)140 bool inrange(int x, int left, int right)
141 {
142 	return (x >= left && x < right);
143 }
144 
145 class TexImageUtils
146 {
147 public:
148 	TexImageUtils(deUint32 internalFormat,
149 				  int cuboid_w, int cuboid_h, int cuboid_d,
150 				  int subcuboid_x0, int subcuboid_y0, int subcuboid_z0,
151 				  int subcuboid_w, int subcuboid_h, int subcuboid_d,
152 				  glu::GLSLVersion glsl_version);
153 	~TexImageUtils (void);
154 protected:
155 	void writePixel(glw::GLubyte *p, glw::GLdouble col);
156 	void writeChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
157 	template <typename T>
158 	void writeToUnsignedChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
159 	template <typename T>
160 	void writeToSignedChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
161 	void writeToFloatChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
162 	void writeToHalfFloatChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
163 	template <typename T,
164 				 unsigned int size_1, unsigned int size_2, unsigned int size_3,
165 				 unsigned int off_1, unsigned int off_2, unsigned int off_3>
166 	void write3Channel(glw::GLubyte *p, int channel, glw::GLdouble col);
167 	template <typename T,
168 				 unsigned int size_1, unsigned int size_2,
169 				 unsigned int size_3, unsigned int size_4,
170 				 unsigned int off_1, unsigned int off_2,
171 				 unsigned int off_3, unsigned int off_4>
172 	void write4Channel(glw::GLubyte *p, int channel, glw::GLdouble col);
173 	void write11F_11F_10F_Channel(glw::GLubyte *p, int channel, glw::GLdouble col);
174 	void setRefcolour (glu::CallLogWrapper gl, glw::GLdouble col);
175 	template <typename T>
176 	void setUnsignedRefcolour(glu::CallLogWrapper gl, glw::GLdouble col);
177 	template <typename T>
178 	void setSignedRefcolour(glu::CallLogWrapper gl, glw::GLdouble col);
179 	void setRGB10A2Refcolour (glu::CallLogWrapper gl, glw::GLdouble col);
180 	bool verify(tcu::Surface dst, tcu::Surface *errMask);
181 
182 	glw::GLubyte *m_src_data;
183 	deUint32 tex;
184 	glu::ShaderProgram* prog;
185 
186 	deUint32 m_internalFormat;
187 	deUint32 m_format;
188 	deUint32 m_type;
189 	int m_pixelsize;
190 	int m_num_channels;
191 	int m_cuboid_w;
192 	int m_cuboid_h;
193 	int m_cuboid_d;
194 	int m_subcuboid_x0;
195 	int m_subcuboid_y0;
196 	int m_subcuboid_z0;
197 	int m_subcuboid_w;
198 	int m_subcuboid_h;
199 	int m_subcuboid_d;
200 
201 	glu::GLSLVersion m_glsl_version;
202 };
203 
TexImageUtils(deUint32 internalFormat,int cuboid_w,int cuboid_h,int cuboid_d,int subcuboid_x0,int subcuboid_y0,int subcuboid_z0,int subcuboid_w,int subcuboid_h,int subcuboid_d,glu::GLSLVersion glsl_version)204 TexImageUtils::TexImageUtils (deUint32 internalFormat,
205 							  int cuboid_w,
206 							  int cuboid_h,
207 							  int cuboid_d,
208 							  int subcuboid_x0,
209 							  int subcuboid_y0,
210 							  int subcuboid_z0,
211 							  int subcuboid_w,
212 							  int subcuboid_h,
213 							  int subcuboid_d,
214 							  glu::GLSLVersion glsl_version)
215 	: m_src_data(0)
216 	, tex(0)
217 	, prog(0)
218 	, m_internalFormat(internalFormat)
219 	, m_format(glu::getTransferFormat(glu::mapGLInternalFormat(internalFormat)).format)
220 	, m_type(glu::getTransferFormat(glu::mapGLInternalFormat(internalFormat)).dataType)
221 	, m_pixelsize(tcu::getPixelSize(glu::mapGLInternalFormat(internalFormat)))
222 	, m_num_channels(tcu::getNumUsedChannels(glu::mapGLInternalFormat(internalFormat).order))
223 	, m_cuboid_w(cuboid_w)
224 	, m_cuboid_h(cuboid_h)
225 	, m_cuboid_d(cuboid_d)
226 	, m_subcuboid_x0(subcuboid_x0)
227 	, m_subcuboid_y0(subcuboid_y0)
228 	, m_subcuboid_z0(subcuboid_z0)
229 	, m_subcuboid_w(subcuboid_w)
230 	, m_subcuboid_h(subcuboid_h)
231 	, m_subcuboid_d(subcuboid_d)
232 	, m_glsl_version(glsl_version)
233 {
234 }
235 
~TexImageUtils(void)236 TexImageUtils::~TexImageUtils (void)
237 {
238 }
239 
writePixel(glw::GLubyte * p,glw::GLdouble col)240 void TexImageUtils::writePixel(glw::GLubyte *p, glw::GLdouble col)
241 {
242 	for (int ch = 0; ch < m_num_channels; ch++)
243 		writeChannel(p, ch, (ch == 3) ? 1.0 : col);
244 }
245 
writeChannel(glw::GLubyte * p,int channel,glw::GLdouble col)246 void TexImageUtils::writeChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
247 {
248 	switch (m_type)
249 	{
250 	case GL_UNSIGNED_BYTE:
251 		writeToUnsignedChannel<glw::GLubyte>(p, channel, col);
252 		break;
253 	case GL_BYTE:
254 		writeToSignedChannel<glw::GLbyte>(p, channel, col);
255 		break;
256 	case GL_UNSIGNED_SHORT:
257 		writeToUnsignedChannel<glw::GLushort>(p, channel, col);
258 		break;
259 	case GL_UNSIGNED_SHORT_5_6_5:
260 		write3Channel<glw::GLushort, 5, 6, 5, 11, 5, 0>(p, channel, col);
261 		break;
262 	case GL_SHORT:
263 		writeToSignedChannel<glw::GLshort>(p, channel, col);
264 		break;
265 	case GL_UNSIGNED_INT:
266 		writeToUnsignedChannel<glw::GLuint>(p, channel, col);
267 		break;
268 	case GL_UNSIGNED_INT_2_10_10_10_REV:
269 		write4Channel<glw::GLuint, 2, 10, 10, 10, 30, 20, 10, 0>(p, 3 - channel, col);
270 		break;
271 	case GL_UNSIGNED_INT_10F_11F_11F_REV:
272 		write11F_11F_10F_Channel(p, channel, col);
273 		break;
274 	case GL_UNSIGNED_SHORT_4_4_4_4:
275 		write4Channel<glw::GLushort, 4, 4, 4, 4, 12, 8, 4, 0>(p, channel, col);
276 		break;
277 	case GL_UNSIGNED_SHORT_5_5_5_1:
278 		write4Channel<glw::GLushort, 5, 5, 5, 1, 11, 6, 1, 0>(p, channel, col);
279 		break;
280 	case GL_INT:
281 		writeToSignedChannel<glw::GLint>(p, channel, col);
282 		break;
283 	case GL_HALF_FLOAT:
284 		writeToHalfFloatChannel(p, channel, col);
285 		break;
286 	case GL_FLOAT:
287 		writeToFloatChannel(p, channel, col);
288 		break;
289 	default:
290 		TCU_FAIL("Invalid type");
291 	}
292 }
293 
294 template <typename T>
writeToUnsignedChannel(glw::GLubyte * p,int channel,glw::GLdouble col)295 void TexImageUtils::writeToUnsignedChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
296 {
297 	static const T max = -1;
298 
299 	const glw::GLdouble d_max = (glw::GLdouble)max;
300 	const glw::GLdouble d_value = col * d_max;
301 	const T t_value = (T)d_value;
302 
303 	T* ptr = (T*)p;
304 
305 	ptr[channel] = t_value;
306 }
307 
308 template <typename T>
writeToSignedChannel(glw::GLubyte * p,int channel,glw::GLdouble col)309 void TexImageUtils::writeToSignedChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
310 {
311 	static const T max = (T)((1u << (sizeof(T) * 8u - 1u)) - 1u);
312 
313 	const glw::GLdouble d_max = (glw::GLdouble)max;
314 	const glw::GLdouble d_value = col * d_max;
315 	const T t_value = (T)d_value;
316 
317 	T* ptr = (T*)p;
318 
319 	ptr[channel] = t_value;
320 }
321 
writeToFloatChannel(glw::GLubyte * p,int channel,glw::GLdouble col)322 void TexImageUtils::writeToFloatChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
323 {
324 	const glw::GLfloat t_value = (glw::GLfloat)col;
325 
326 	glw::GLfloat *ptr = (glw::GLfloat*)p;
327 
328 	ptr[channel] = t_value;
329 }
330 
writeToHalfFloatChannel(glw::GLubyte * p,int channel,glw::GLdouble col)331 void TexImageUtils::writeToHalfFloatChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
332 {
333 	deUint16* ptr = (deUint16*)p;
334 
335 	tcu::Float16 val(col);
336 
337 	ptr[channel] = val.bits();
338 }
339 
340 template <typename T,
341 			 unsigned int size_1, unsigned int size_2, unsigned int size_3,
342 			 unsigned int off_1, unsigned int off_2, unsigned int off_3>
write3Channel(glw::GLubyte * p,int channel,glw::GLdouble col)343 void TexImageUtils::write3Channel(glw::GLubyte *p, int channel, glw::GLdouble col)
344 {
345 	T mask = 0;
346 	T max = 0;
347 	T off = 0;
348 	T* ptr = (T*)p;
349 	T result = 0;
350 
351 	const T max_1 = (1 << size_1) - 1;
352 	const T max_2 = (1 << size_2) - 1;
353 	const T max_3 = (1 << size_3) - 1;
354 
355 	switch (channel)
356 	{
357 	case 0:
358 		mask = max_1;
359 		max  = max_1;
360 		off  = off_1;
361 		break;
362 	case 1:
363 		mask = max_2;
364 		max  = max_2;
365 		off  = off_2;
366 		break;
367 	case 2:
368 		mask = max_3;
369 		max  = max_3;
370 		off  = off_3;
371 		break;
372 	default:
373 		TCU_FAIL("Invalid channel");
374 		break;
375 	}
376 
377 	const glw::GLdouble d_max	 = (glw::GLdouble)max;
378 	const glw::GLdouble d_value  = col * d_max;
379 	const T t_value = (T)d_value;
380 
381 	result = (T)((t_value & mask) << off);
382 
383 	*ptr |= result;
384 }
385 
386 template <typename T,
387 			 unsigned int size_1, unsigned int size_2,
388 			 unsigned int size_3, unsigned int size_4,
389 			 unsigned int off_1, unsigned int off_2,
390 			 unsigned int off_3, unsigned int off_4>
write4Channel(glw::GLubyte * p,int channel,glw::GLdouble col)391 void TexImageUtils::write4Channel(glw::GLubyte *p, int channel, glw::GLdouble col)
392 {
393 	T mask	 = 0;
394 	T max	 = 0;
395 	T off	 = 0;
396 	T* ptr	 = (T*)p;
397 	T result = 0;
398 
399 	T max_1 = (1 << size_1) - 1;
400 	T max_2 = (1 << size_2) - 1;
401 	T max_3 = (1 << size_3) - 1;
402 	T max_4 = (1 << size_4) - 1;
403 
404 	switch (channel)
405 	{
406 	case 0:
407 		mask = max_1;
408 		max  = max_1;
409 		off  = off_1;
410 		break;
411 	case 1:
412 		mask = max_2;
413 		max  = max_2;
414 		off  = off_2;
415 		break;
416 	case 2:
417 		mask = max_3;
418 		max  = max_3;
419 		off  = off_3;
420 		break;
421 	case 3:
422 		mask = max_4;
423 		max  = max_4;
424 		off  = off_4;
425 		break;
426 	default:
427 		TCU_FAIL("Invalid channel");
428 		break;
429 	}
430 
431 	const glw::GLdouble d_max	 = (glw::GLdouble)max;
432 	const glw::GLdouble d_value  = col * d_max;
433 	const T t_value = (T)d_value;
434 
435 	result = (T)((t_value & mask) << off);
436 
437 	*ptr |= result;
438 }
439 
write11F_11F_10F_Channel(glw::GLubyte * p,int channel,glw::GLdouble col)440 void TexImageUtils::write11F_11F_10F_Channel(glw::GLubyte *p, int channel, glw::GLdouble col)
441 {
442 	deUint32* ptr = (deUint32*)p;
443 
444 	switch (channel)
445 	{
446 	case 0:
447 	{
448 		tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> val(col);
449 		deUint32 bits = val.bits();
450 
451 		*ptr |= bits;
452 	}
453 	break;
454 	case 1:
455 	{
456 		tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> val(col);
457 		deUint32 bits = val.bits();
458 
459 		*ptr |= (bits << 11);
460 	}
461 	break;
462 	case 2:
463 	{
464 		tcu::Float<deUint32, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> val(col);
465 		deUint32 bits = val.bits();
466 
467 		*ptr |= (bits << 22);
468 	}
469 	break;
470 	default:
471 		TCU_FAIL("Invalid channel");
472 	}
473 }
474 
setRefcolour(glu::CallLogWrapper gl,glw::GLdouble col)475 void TexImageUtils::setRefcolour (glu::CallLogWrapper gl, glw::GLdouble col)
476 {
477 	switch (m_format)
478 	{
479 	case GL_RED:
480 	case GL_RG:
481 	case GL_RGB:
482 	case GL_RGBA:
483 		gl.glUniform4f(gl.glGetUniformLocation(prog->getProgram(), "refcolour"),
484 					   m_num_channels > 0 ? col : 0.0f,
485 					   m_num_channels > 1 ? col : 0.0f,
486 					   m_num_channels > 2 ? col : 0.0f,
487 					   1.0f);
488 		break;
489 	default:
490 		switch (m_type)
491 		{
492 		case GL_UNSIGNED_BYTE:
493 			setUnsignedRefcolour<glw::GLubyte>(gl, col);
494 			break;
495 		case GL_BYTE:
496 			setSignedRefcolour<glw::GLubyte>(gl, col);
497 			break;
498 		case GL_UNSIGNED_SHORT:
499 		case GL_UNSIGNED_SHORT_5_6_5:
500 		case GL_UNSIGNED_SHORT_4_4_4_4:
501 		case GL_UNSIGNED_SHORT_5_5_5_1:
502 			setUnsignedRefcolour<glw::GLushort>(gl, col);
503 			break;
504 		case GL_SHORT:
505 			setSignedRefcolour<glw::GLushort>(gl, col);
506 			break;
507 		case GL_UNSIGNED_INT:
508 			setUnsignedRefcolour<glw::GLuint>(gl, col);
509 			break;
510 		case GL_UNSIGNED_INT_2_10_10_10_REV:
511 			setRGB10A2Refcolour(gl, col);
512 			break;
513 		case GL_INT:
514 			setSignedRefcolour<glw::GLuint>(gl, col);
515 			break;
516 		default:
517 			TCU_FAIL("Invalid type");
518 		}
519 	}
520 }
521 
522 template <typename T>
setUnsignedRefcolour(glu::CallLogWrapper gl,glw::GLdouble col)523 void TexImageUtils::setUnsignedRefcolour (glu::CallLogWrapper gl, glw::GLdouble col)
524 {
525 	static const T max = -1;
526 	const glw::GLdouble d_max   = (glw::GLdouble)max;
527 	const glw::GLdouble d_value = d_max * col;
528 	const T t_value = (T)d_value;
529 
530 	unsigned int refcol[4] =
531 	{
532 		m_num_channels > 0 ? t_value : 0u,
533 		m_num_channels > 1 ? t_value : 0u,
534 		m_num_channels > 2 ? t_value : 0u,
535 		255u,
536 	};
537 
538 	gl.glUniform4uiv(gl.glGetUniformLocation(prog->getProgram(), "refcolour"), 1,
539 					 refcol);
540 }
541 
542 template <typename T>
setSignedRefcolour(glu::CallLogWrapper gl,glw::GLdouble col)543 void TexImageUtils::setSignedRefcolour (glu::CallLogWrapper gl, glw::GLdouble col)
544 {
545 	static const T umax = -1;
546 	static const T max  = umax >> 1;
547 
548 	const glw::GLdouble d_max   = (glw::GLdouble)max;
549 	const glw::GLdouble d_value = d_max * col;
550 	const T t_value = (T)d_value;
551 
552 	int refcol[4] =
553 	{
554 		(m_num_channels > 0 ? (int)t_value : 0),
555 		(m_num_channels > 1 ? (int)t_value : 0),
556 		(m_num_channels > 2 ? (int)t_value : 0),
557 		255,
558 	};
559 
560 	gl.glUniform4iv(gl.glGetUniformLocation(prog->getProgram(), "refcolour"), 1,
561 					refcol);
562 }
563 
setRGB10A2Refcolour(glu::CallLogWrapper gl,glw::GLdouble col)564 void TexImageUtils::setRGB10A2Refcolour (glu::CallLogWrapper gl, glw::GLdouble col)
565 {
566 	unsigned int max_channel_value = 1023u;
567 
568 	const glw::GLdouble d_max_channel_value = (glw::GLdouble)max_channel_value;
569 	const glw::GLdouble d_value = (glw::GLdouble)d_max_channel_value * col;
570 	unsigned int t_value = (unsigned int)d_value;
571 
572 	unsigned int refcol[4] =
573 	{
574 		(m_num_channels > 0 ? t_value : 0u),
575 		(m_num_channels > 1 ? t_value : 0u),
576 		(m_num_channels > 2 ? t_value : 0u),
577 		255u,
578 	};
579 
580 	gl.glUniform4uiv(gl.glGetUniformLocation(prog->getProgram(), "refcolour"), 1,
581 					 refcol);
582 }
583 
verify(tcu::Surface dst,tcu::Surface * errMask)584 bool TexImageUtils::verify(tcu::Surface dst, tcu::Surface *errMask)
585 {
586 	*errMask = tcu::Surface (dst.getWidth(), dst.getHeight());
587 	tcu::clear(errMask->getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
588 	bool pass = true;
589 
590 	for (int y = 0; y < dst.getHeight(); y++)
591 	{
592 		for (int x = 0; x < dst.getWidth(); x++)
593 		{
594 			if (dst.getPixel(x, y) != tcu::RGBA::green())
595 			{
596 				pass = false;
597 				errMask->setPixel(x, y, tcu::RGBA::red());
598 			}
599 		}
600 	}
601 
602 	return pass;
603 }
604 
605 class TexImage2DCase : public deqp::TestCase
606 					 , public sglr::ContextWrapper
607 					 , public TexImageUtils
608 {
609 public:
610 	TexImage2DCase (deqp::Context& context, const char* name, const char* desc,
611 					deUint32 internalFormat,
612 					int rect_w, int rect_h,
613 					int subrect_x0, int subrect_y0,
614 					int subrect_w, int subrect_h,
615 					glu::GLSLVersion glsl_version);
616 	~TexImage2DCase (void);
617 	IterateResult iterate (void);
618 protected:
619 	void generateSrcData();
620 	void createTexture (void);
621 	void createShader (void);
622 	tcu::Surface renderToSurf (void);
623 	void cleanup (void);
624 };
625 
TexImage2DCase(deqp::Context & context,const char * name,const char * desc,deUint32 internalFormat,int rect_w,int rect_h,int subrect_x0,int subrect_y0,int subrect_w,int subrect_h,glu::GLSLVersion glsl_version)626 TexImage2DCase::TexImage2DCase (deqp::Context& context,
627 								const char* name,
628 								const char* desc,
629 								deUint32 internalFormat,
630 								int rect_w,
631 								int rect_h,
632 								int subrect_x0,
633 								int subrect_y0,
634 								int subrect_w,
635 								int subrect_h,
636 								glu::GLSLVersion glsl_version)
637 	: TestCase(context, name, desc)
638 	, TexImageUtils(internalFormat,
639 					rect_w, rect_h, 1,
640 					subrect_x0, subrect_y0, 0,
641 					subrect_w, subrect_h, 1,
642 					glsl_version)
643 {
644 }
645 
~TexImage2DCase(void)646 TexImage2DCase::~TexImage2DCase(void)
647 {
648 }
649 
iterate(void)650 TexImage2DCase::IterateResult TexImage2DCase::iterate(void)
651 {
652 	glu::RenderContext& renderCtx = TestCase::m_context.getRenderContext();
653 	tcu::TestLog& log = m_testCtx.getLog();
654 	tcu::Surface dst, errMask;
655 
656 	bool pass = true;
657 
658 	sglr::GLContext gl_ctx (renderCtx,
659 							log,
660 							sglr::GLCONTEXT_LOG_CALLS,
661 							tcu::IVec4(0, 0, m_subcuboid_w, m_subcuboid_h));
662 
663 	setContext((sglr::Context*)&gl_ctx);
664 
665 	generateSrcData();
666 	createTexture();
667 	createShader();
668 	dst = renderToSurf();
669 
670 	pass = verify(dst, &errMask);
671 
672 	cleanup();
673 
674 	if (pass)
675 	{
676 		m_testCtx.getLog()
677 		<< tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage
678 		<< tcu::TestLog::ImageSet("ImageVerification", "Image verification")
679 		<< tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
680 		<< tcu::TestLog::EndImageSet;
681 	}
682 	else
683 	{
684 		m_testCtx.getLog()
685 		<< tcu::TestLog::Message << "Image is invalid" << tcu::TestLog::EndMessage
686 		<< tcu::TestLog::ImageSet("ErrorVerification", "Image verification")
687 		<< tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
688 		<< tcu::TestLog::Image("ErrorMask", "Error mask", errMask.getAccess())
689 		<< tcu::TestLog::EndImageSet;
690 	}
691 
692 	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
693 							pass ? "Pass" : "Fail");
694 
695 	return STOP;
696 }
697 
generateSrcData()698 void TexImage2DCase::generateSrcData()
699 {
700 	m_src_data = new glw::GLubyte[m_cuboid_w * m_cuboid_h * m_pixelsize]();
701 
702 	glw::GLdouble col = 0.0;
703 
704 	for (int y = 0; y < m_cuboid_h; y++)
705 	{
706 		for (int x = 0; x < m_cuboid_w; x++)
707 		{
708 			if (inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h) &&
709 				inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w))
710 				col = 1.0;
711 			else
712 				col = 0.0;
713 			int offset = y * m_cuboid_w * m_pixelsize +
714 						 x * m_pixelsize;
715 			writePixel(m_src_data + offset, col);
716 		}
717 	}
718 }
719 
createTexture(void)720 void TexImage2DCase::createTexture (void)
721 {
722 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
723 							m_testCtx.getLog());
724 
725 	gl.glGenTextures(1, &tex);
726 	gl.glBindTexture(GL_TEXTURE_2D, tex);
727 	gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
728 	gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
729 
730 	gl.glPixelStorei(GL_UNPACK_ROW_LENGTH,	m_cuboid_w);
731 	gl.glPixelStorei(GL_UNPACK_SKIP_ROWS,   m_subcuboid_y0);
732 	gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_subcuboid_x0);
733 
734 	gl.glTexImage2D(GL_TEXTURE_2D,
735 					0,
736 					m_internalFormat,
737 					m_subcuboid_w,
738 					m_subcuboid_h,
739 					0,
740 					m_format,
741 					m_type,
742 					m_src_data);
743 
744 	gl.glPixelStorei(GL_UNPACK_ROW_LENGTH,	 0);
745 	gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
746 	gl.glPixelStorei(GL_UNPACK_SKIP_ROWS,	 0);
747 }
748 
createShader(void)749 void TexImage2DCase::createShader (void)
750 {
751 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
752 							m_testCtx.getLog());
753 
754 	const tcu::StringTemplate vs_src (vs_template_src);
755 	const tcu::StringTemplate fs_src (fs_template_src);
756 
757 	std::map<std::string,std::string> params;
758 	params["GLSL_VERSION"]	 = getGLSLVersionDeclaration(m_glsl_version);
759 	params["TEXCOORDS_TYPE"] = "vec2";
760 	params["LAYER"]			 = "";
761 	params["TEXCOORDS"]		 = "pos.xy";
762 	params["CONDITION"]		 = "colour.rgb == refcolour.rgb";
763 
764 	switch (m_format)
765 	{
766 	case GL_RED_INTEGER:
767 	case GL_RG_INTEGER:
768 	case GL_RGB_INTEGER:
769 	case GL_RGBA_INTEGER:
770 		switch (m_type)
771 		{
772 		case GL_BYTE:
773 		case GL_SHORT:
774 		case GL_INT:
775 			params["SAMPLER_TYPE"] = "isampler2D";
776 			params["COL_TYPE"]	 = "ivec4";
777 			break;
778 		default:
779 			params["SAMPLER_TYPE"] = "usampler2D";
780 			params["COL_TYPE"]	   = "uvec4";
781 			break;
782 		}
783 		break;
784 	default:
785 		params["SAMPLER_TYPE"] = "sampler2D";
786 		params["COL_TYPE"]	   = "vec4";
787 		break;
788 	}
789 
790 	prog = new glu::ShaderProgram(m_context.getRenderContext(),
791 								  glu::ProgramSources() <<
792 								  glu::VertexSource(vs_src.specialize(params)) <<
793 								  glu::FragmentSource(fs_src.specialize(params)));
794 
795 	if (!prog->isOk())
796 	{
797 		m_testCtx.getLog()
798 			<< tcu::TestLog::Message << ""
799 			<< tcu::TestLog::EndMessage
800 			<< tcu::TestLog::ShaderProgram(false, "")
801 			<< tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
802 									prog->getShaderInfo(glu::SHADERTYPE_VERTEX,
803 														0).source,
804 									false,
805 									prog->getShaderInfo(glu::SHADERTYPE_VERTEX,
806 														0).infoLog)
807 
808 			<< tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
809 									prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT,
810 														0).source,
811 									false,
812 									prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT,
813 														0).infoLog)
814 			<< tcu::TestLog::EndShaderProgram;
815 		TCU_FAIL("Shader creation failed");
816 	}
817 
818 	gl.glUseProgram(prog->getProgram());
819 	gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "sampler"), 0);
820 }
821 
renderToSurf(void)822 tcu::Surface TexImage2DCase::renderToSurf (void)
823 {
824 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
825 							m_testCtx.getLog());
826 	gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
827 	gl.glClear(GL_COLOR_BUFFER_BIT);
828 
829 	static const float vertexPositions[4*3] =
830 	{
831 		-1.0, -1.0, -1.0f,
832 		 1.0, -1.0,  0.0f,
833 		-1.0,  1.0,  0.0f,
834 		 1.0,  1.0,  1.0f,
835 	};
836 
837 	static const deUint16 indices[6] = { 0, 1, 2, 2, 1, 3 };
838 
839 	const glu::VertexArrayBinding attrBindings[] =
840 	{
841 		glu::va::Float("pos", 3, 4, 0, &vertexPositions[0])
842 	};
843 
844 	gl.glViewport(0, 0, m_subcuboid_w, m_subcuboid_h);
845 	setRefcolour(gl, 1.0);
846 	glu::draw(m_context.getRenderContext(),
847 			  prog->getProgram(),
848 			  DE_LENGTH_OF_ARRAY(attrBindings),
849 			  &attrBindings[0],
850 			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
851 
852 	tcu::Surface dst;
853 	dst.setSize(m_subcuboid_w, m_subcuboid_h);
854 
855 	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
856 
857 	return dst;
858 }
859 
cleanup(void)860 void TexImage2DCase::cleanup (void)
861 {
862 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
863 							m_testCtx.getLog());
864 
865 	gl.glDeleteTextures(1, &tex);
866 	delete[] m_src_data;
867 	delete prog;
868 }
869 
870 class TexImage3DCase : public deqp::TestCase
871 					 , public sglr::ContextWrapper
872 					 , public TexImageUtils
873 {
874 public:
875 	TexImage3DCase (deqp::Context& context, const char* name, const char* desc,
876 					deUint32 internalFormat,
877 					int cuboid_w, int cuboid_h, int cuboid_d,
878 					int subcuboid_x0, int subrect_y0, int subcuboid_z0,
879 					int subcuboid_w, int subcuboid_h, int subcuboid_d,
880 					glu::GLSLVersion glsl_version);
881 	~TexImage3DCase (void);
882 	IterateResult iterate (void);
883 protected:
884 	void generateSrcData();
885 	void createTexture (void);
886 	void createShader (void);
887 	tcu::Surface renderToSurf (int layer);
888 	void cleanup (void);
889 };
890 
TexImage3DCase(deqp::Context & context,const char * name,const char * desc,deUint32 internalFormat,int cuboid_w,int cuboid_h,int cuboid_d,int subcuboid_x0,int subcuboid_y0,int subcuboid_z0,int subcuboid_w,int subcuboid_h,int subcuboid_d,glu::GLSLVersion glsl_version)891 TexImage3DCase::TexImage3DCase (deqp::Context& context,
892 								const char* name,
893 								const char* desc,
894 								deUint32 internalFormat,
895 								int cuboid_w,
896 								int cuboid_h,
897 								int cuboid_d,
898 								int subcuboid_x0,
899 								int subcuboid_y0,
900 								int subcuboid_z0,
901 								int subcuboid_w,
902 								int subcuboid_h,
903 								int subcuboid_d,
904 								glu::GLSLVersion glsl_version)
905 	: TestCase(context, name, desc)
906 	, TexImageUtils(internalFormat,
907 					cuboid_w, cuboid_h, cuboid_d,
908 					subcuboid_x0, subcuboid_y0, subcuboid_z0,
909 					subcuboid_w, subcuboid_h, subcuboid_d,
910 					glsl_version)
911 {
912 }
913 
~TexImage3DCase(void)914 TexImage3DCase::~TexImage3DCase(void)
915 {
916 }
917 
iterate(void)918 TexImage3DCase::IterateResult TexImage3DCase::iterate(void)
919 {
920 	glu::RenderContext& renderCtx = TestCase::m_context.getRenderContext();
921 	tcu::TestLog& log = m_testCtx.getLog();
922 	tcu::Surface dst, errMask;
923 
924 	bool pass = true;
925 
926 	sglr::GLContext gl_ctx (renderCtx,
927 							log,
928 							sglr::GLCONTEXT_LOG_CALLS,
929 							tcu::IVec4(0, 0, m_subcuboid_w, m_subcuboid_h));
930 
931 	setContext((sglr::Context*)&gl_ctx);
932 
933 	generateSrcData();
934 	createTexture();
935 	createShader();
936 
937 	for (int z = 0; z < m_subcuboid_d; z++)
938 	{
939 		dst = renderToSurf(z);
940 
941 		bool layer_pass = verify(dst, &errMask);
942 
943 		if (layer_pass)
944 		{
945 			m_testCtx.getLog()
946 				<< tcu::TestLog::Message << "Layer " << z	 << " is valid"
947 				<< tcu::TestLog::EndMessage
948 				<< tcu::TestLog::ImageSet("LayerVerification", "Layer verification")
949 				<< tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
950 				<< tcu::TestLog::EndImageSet;
951 		}
952 		else
953 		{
954 			m_testCtx.getLog()
955 				<< tcu::TestLog::Message << "Layer " << z << " is invalid"
956 				<< tcu::TestLog::EndMessage
957 				<< tcu::TestLog::ImageSet("ErrorVerification", "Layer verification")
958 				<< tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
959 				<< tcu::TestLog::Image("ErrorMask", "Error mask", errMask.getAccess())
960 				<< tcu::TestLog::EndImageSet;
961 		}
962 
963 		pass &= layer_pass;
964 	}
965 
966 	cleanup();
967 
968 	if (pass)
969 	{
970 		m_testCtx.getLog()
971 			<< tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
972 	}
973 	else
974 	{
975 		m_testCtx.getLog()
976 			<< tcu::TestLog::Message << "Image is invalid" << tcu::TestLog::EndMessage;
977 	}
978 
979 	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
980 									pass ? "Pass" : "Fail");
981 
982 	return STOP;
983 }
984 
generateSrcData()985 void TexImage3DCase::generateSrcData()
986 {
987 	m_src_data = new glw::GLubyte[m_cuboid_w *
988 								  m_cuboid_h *
989 								  m_cuboid_d *
990 								  m_pixelsize]();
991 
992 	glw::GLdouble col = 0.0;
993 
994 	for (int z = 0; z < m_cuboid_d; z++)
995 	{
996 		for (int y = 0; y < m_cuboid_h; y++)
997 		{
998 			for (int x = 0; x < m_cuboid_w; x++)
999 			{
1000 				if (inrange(z, m_subcuboid_z0, m_subcuboid_z0 + m_subcuboid_d) &&
1001 					inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h) &&
1002 					inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w))
1003 					col = 0.125 + (z - m_subcuboid_z0) * 0.125; /* [0.125, 0.250..1.0] */
1004 				else
1005 					col = 0.0;
1006 				int offset = z * m_cuboid_h * m_cuboid_w * m_pixelsize +
1007 							 y * m_cuboid_w * m_pixelsize +
1008 							 x * m_pixelsize;
1009 				writePixel(m_src_data + offset, col);
1010 			}
1011 		}
1012 	}
1013 }
1014 
createTexture(void)1015 void TexImage3DCase::createTexture (void)
1016 {
1017 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1018 							m_testCtx.getLog());
1019 
1020 	gl.glGenTextures(1, &tex);
1021 	gl.glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
1022 	gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1023 	gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1024 
1025 	gl.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_cuboid_h);
1026 	gl.glPixelStorei(GL_UNPACK_ROW_LENGTH,	 m_cuboid_w);
1027 	gl.glPixelStorei(GL_UNPACK_SKIP_IMAGES,	 m_subcuboid_z0);
1028 	gl.glPixelStorei(GL_UNPACK_SKIP_ROWS,	 m_subcuboid_y0);
1029 	gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS,	 m_subcuboid_x0);
1030 
1031 	gl.glTexImage3D(GL_TEXTURE_2D_ARRAY,
1032 					0,
1033 					m_internalFormat,
1034 					m_subcuboid_w,
1035 					m_subcuboid_h,
1036 					m_subcuboid_d,
1037 					0,
1038 					m_format,
1039 					m_type,
1040 					m_src_data);
1041 
1042 	gl.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
1043 	gl.glPixelStorei(GL_UNPACK_ROW_LENGTH,	 0);
1044 	gl.glPixelStorei(GL_UNPACK_SKIP_IMAGES,  0);
1045 	gl.glPixelStorei(GL_UNPACK_SKIP_ROWS,	 0);
1046 	gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS,  0);
1047 }
1048 
createShader(void)1049 void TexImage3DCase::createShader (void)
1050 {
1051 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1052 							m_testCtx.getLog());
1053 
1054 	const tcu::StringTemplate vs_src (vs_template_src);
1055 	const tcu::StringTemplate fs_src (fs_template_src);
1056 
1057 	std::map<std::string,std::string> params;
1058 	params["GLSL_VERSION"]	 = getGLSLVersionDeclaration(m_glsl_version);
1059 	params["TEXCOORDS_TYPE"] = "vec3";
1060 	params["LAYER"]			 = "uniform int layer;";
1061 	params["TEXCOORDS"]		 = "vec3(pos.xy, layer)";
1062 
1063 	switch (m_format)
1064 	{
1065 	case GL_RED_INTEGER:
1066 	case GL_RG_INTEGER:
1067 	case GL_RGB_INTEGER:
1068 	case GL_RGBA_INTEGER:
1069 		switch (m_type)
1070 		{
1071 		case GL_BYTE:
1072 		case GL_SHORT:
1073 		case GL_INT:
1074 			params["SAMPLER_TYPE"] = "isampler2DArray";
1075 			params["COL_TYPE"]	 = "ivec4";
1076 			params["CONDITION"]	 = "all(lessThan(uvec4(abs(colour - refcolour)).rgb, uvec3(2u)))";
1077 			break;
1078 		default:
1079 			params["SAMPLER_TYPE"] = "usampler2DArray";
1080 			params["COL_TYPE"]	   = "uvec4";
1081 			params["CONDITION"]	   = "all(lessThan(uvec4(abs(ivec4(colour) - ivec4(refcolour))).rgb, uvec3(2u)))";
1082 			break;
1083 		}
1084 		break;
1085 	default:
1086 		const tcu::StringTemplate fs_condition ("all(lessThan((abs(colour - refcolour)).rgb, vec3(${EPS})))");
1087 		std::map<std::string, std::string> fs_condition_params;
1088 		fs_condition_params["EPS"] = std::to_string(getEps(m_internalFormat));
1089 		params["SAMPLER_TYPE"] = "sampler2DArray";
1090 		params["COL_TYPE"]	  = "vec4";
1091 		params["CONDITION"]	  = fs_condition.specialize(fs_condition_params);
1092 		break;
1093 	}
1094 
1095 	prog = new glu::ShaderProgram(m_context.getRenderContext(),
1096 								  glu::ProgramSources() <<
1097 								  glu::VertexSource(vs_src.specialize(params)) <<
1098 								  glu::FragmentSource(fs_src.specialize(params)));
1099 
1100 	if (!prog->isOk())
1101 	{
1102 		m_testCtx.getLog()
1103 			<< tcu::TestLog::Message << ""
1104 			<< tcu::TestLog::EndMessage
1105 			<< tcu::TestLog::ShaderProgram(false, "")
1106 			<< tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
1107 									prog->getShaderInfo(glu::SHADERTYPE_VERTEX,
1108 														0).source,
1109 									false,
1110 									prog->getShaderInfo(glu::SHADERTYPE_VERTEX,
1111 														0).infoLog)
1112 
1113 			<< tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
1114 									prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT,
1115 														0).source,
1116 									false,
1117 									prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT,
1118 														0).infoLog)
1119 			<< tcu::TestLog::EndShaderProgram;
1120 		TCU_FAIL("Shader creation failed");
1121 	}
1122 
1123 	gl.glUseProgram(prog->getProgram());
1124 	gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "sampler"), 0);
1125 }
1126 
renderToSurf(int layer)1127 tcu::Surface TexImage3DCase::renderToSurf (int layer)
1128 {
1129 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1130 							m_testCtx.getLog());
1131 	gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
1132 	gl.glClear(GL_COLOR_BUFFER_BIT);
1133 
1134 	static const float vertexPositions[4*3] =
1135 	{
1136 		-1.0, -1.0, -1.0f,
1137 		 1.0, -1.0,	 0.0f,
1138 		-1.0,  1.0,	 0.0f,
1139 		1.0,   1.0,	 1.0f,
1140 	};
1141 
1142 	static const deUint16 indices[6] = { 0, 1, 2, 2, 1, 3 };
1143 
1144 	const glu::VertexArrayBinding attrBindings[] =
1145 	{
1146 		glu::va::Float("pos", 3, 4, 0, &vertexPositions[0])
1147 	};
1148 
1149 	gl.glViewport(0, 0, m_subcuboid_w, m_subcuboid_h);
1150 
1151 	gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "layer"), layer);
1152 	glw::GLfloat refcol = 0.125 + layer * 0.125;
1153 	setRefcolour(gl, refcol);
1154 	glu::draw(m_context.getRenderContext(),
1155 			  prog->getProgram(),
1156 			  DE_LENGTH_OF_ARRAY(attrBindings),
1157 			  &attrBindings[0],
1158 			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
1159 
1160 	tcu::Surface dst;
1161 	dst.setSize(m_subcuboid_w, m_subcuboid_h);
1162 
1163 	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1164 
1165 	return dst;
1166 }
1167 
cleanup(void)1168 void TexImage3DCase::cleanup (void)
1169 {
1170 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1171 							m_testCtx.getLog());
1172 
1173 	gl.glDeleteTextures(1, &tex);
1174 	delete[] m_src_data;
1175 	delete prog;
1176 }
1177 
1178 class CompressedTexImageUtils
1179 {
1180 public:
1181 	CompressedTexImageUtils (deUint32 internalFormat,
1182 							 int cuboid_w, int cuboid_h, int cuboid_d,
1183 							 int subcuboid_x0, int subcuboid_y0, int subcuboid_z0,
1184 							 int subcuboid_w, int subcuboid_h, int subcuboid_d,
1185 							 glu::GLSLVersion glsl_version);
1186 	~CompressedTexImageUtils (void);
1187 protected:
1188 	int getImageSize (int width, int height, int depth);
1189 	bool verify(tcu::Surface dst, tcu::Surface *errMask);
1190 
1191 	glw::GLubyte *m_src_data;
1192 	deUint32 tex;
1193 	glu::ShaderProgram *prog;
1194 
1195 	int m_bw;					/* block width */
1196 	int m_bh;					/* block height */
1197 	int m_bd;					/* block depth */
1198 	int m_bs;					/* block size */
1199 
1200 	deUint32 m_internalFormat;
1201 	int m_cuboid_w;
1202 	int m_cuboid_h;
1203 	int m_cuboid_d;
1204 	int m_subcuboid_x0;
1205 	int m_subcuboid_y0;
1206 	int m_subcuboid_z0;
1207 	int m_subcuboid_w;
1208 	int m_subcuboid_h;
1209 	int m_subcuboid_d;
1210 
1211 	glu::GLSLVersion m_glsl_version;
1212 };
1213 
CompressedTexImageUtils(deUint32 internalFormat,int cuboid_w,int cuboid_h,int cuboid_d,int subcuboid_x0,int subcuboid_y0,int subcuboid_z0,int subcuboid_w,int subcuboid_h,int subcuboid_d,glu::GLSLVersion glsl_version)1214 CompressedTexImageUtils::CompressedTexImageUtils (deUint32 internalFormat,
1215 												  int cuboid_w,
1216 												  int cuboid_h,
1217 												  int cuboid_d,
1218 												  int subcuboid_x0,
1219 												  int subcuboid_y0,
1220 												  int subcuboid_z0,
1221 												  int subcuboid_w,
1222 												  int subcuboid_h,
1223 												  int subcuboid_d,
1224 												  glu::GLSLVersion glsl_version)
1225 	: m_internalFormat(internalFormat)
1226 	, m_cuboid_w(cuboid_w)
1227 	, m_cuboid_h(cuboid_h)
1228 	, m_cuboid_d(cuboid_d)
1229 	, m_subcuboid_x0(subcuboid_x0)
1230 	, m_subcuboid_y0(subcuboid_y0)
1231 	, m_subcuboid_z0(subcuboid_z0)
1232 	, m_subcuboid_w(subcuboid_w)
1233 	, m_subcuboid_h(subcuboid_h)
1234 	, m_subcuboid_d(subcuboid_d)
1235 	, m_glsl_version(glsl_version)
1236 {
1237 }
1238 
~CompressedTexImageUtils(void)1239 CompressedTexImageUtils::~CompressedTexImageUtils(void)
1240 {
1241 }
1242 
getImageSize(int width,int height,int depth)1243 int CompressedTexImageUtils::getImageSize (int width, int height, int depth)
1244 {
1245 	return (width / m_bw + (width % m_bw > 0)) *
1246 		   (height / m_bh + (height % m_bh > 0)) *
1247 		   (depth / m_bd + (depth % m_bd > 0)) *
1248 		   m_bs;
1249 }
1250 
verify(tcu::Surface dst,tcu::Surface * errMask)1251 bool CompressedTexImageUtils::verify(tcu::Surface dst, tcu::Surface *errMask)
1252 {
1253 	*errMask = tcu::Surface (dst.getWidth(), dst.getHeight());
1254 	tcu::clear(errMask->getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
1255 	bool pass = true;
1256 
1257 	for (int y = 0; y < dst.getHeight(); y++)
1258 	{
1259 		for (int x = 0; x < dst.getWidth(); x++)
1260 		{
1261 			if (dst.getPixel(x, y) != tcu::RGBA::green())
1262 			{
1263 				pass = false;
1264 				errMask->setPixel(x, y, tcu::RGBA::red());
1265 			}
1266 		}
1267 	}
1268 
1269 	return pass;
1270 }
1271 
1272 class CompressedTexImage2DCase : public deqp::TestCase
1273 							   , public sglr::ContextWrapper
1274 							   , public CompressedTexImageUtils
1275 {
1276 public:
1277 	CompressedTexImage2DCase (deqp::Context& context, const char *name, const char *desc,
1278 							  deUint32 internalFormat,
1279 							  int cuboid_w, int cuboid_h,
1280 							  int subcuboid_x0, int subcuboid_y0,
1281 							  int subcuboid_w, int subcuboid_h,
1282 							  glu::GLSLVersion glsl_version);
1283 	~CompressedTexImage2DCase (void);
1284 	IterateResult iterate (void);
1285 protected:
1286 	void generateSrcData_s3tc (void);
1287 	void generateSrcData_astc (void);
1288 	void createTexture (void);
1289 	void createShader (void);
1290 	tcu::Surface renderToSurf (void);
1291 	void cleanup (void);
1292 };
1293 
CompressedTexImage2DCase(deqp::Context & context,const char * name,const char * desc,deUint32 internalFormat,int cuboid_w,int cuboid_h,int subcuboid_x0,int subcuboid_y0,int subcuboid_w,int subcuboid_h,glu::GLSLVersion glsl_version)1294 CompressedTexImage2DCase::CompressedTexImage2DCase (deqp::Context& context,
1295 													const char *name,
1296 													const char *desc,
1297 													deUint32 internalFormat,
1298 													int cuboid_w,
1299 													int cuboid_h,
1300 													int subcuboid_x0,
1301 													int subcuboid_y0,
1302 													int subcuboid_w,
1303 													int subcuboid_h,
1304 													glu::GLSLVersion glsl_version)
1305 	: TestCase(context, name, desc)
1306 	, CompressedTexImageUtils(internalFormat,
1307 							  cuboid_w,
1308 							  cuboid_h,
1309 							  1,
1310 							  subcuboid_x0,
1311 							  subcuboid_y0,
1312 							  0,
1313 							  subcuboid_w,
1314 							  subcuboid_h,
1315 							  1,
1316 							  glsl_version)
1317 {
1318 }
1319 
~CompressedTexImage2DCase(void)1320 CompressedTexImage2DCase::~CompressedTexImage2DCase (void)
1321 {
1322 }
1323 
iterate(void)1324 CompressedTexImage2DCase::IterateResult CompressedTexImage2DCase::iterate (void)
1325 {
1326 	glu::RenderContext& renderCtx = TestCase::m_context.getRenderContext();
1327 	const glu::ContextInfo& ctxInfo = m_context.getContextInfo();
1328 	tcu::TestLog& log = m_testCtx.getLog();
1329 	tcu::Surface dst, errMask;
1330 
1331 	bool pass = true;
1332 
1333 	sglr::GLContext gl_ctx (renderCtx,
1334 							log,
1335 							sglr::GLCONTEXT_LOG_CALLS,
1336 							tcu::IVec4(0, 0, m_subcuboid_w, m_subcuboid_h));
1337 
1338 	setContext((sglr::Context*)&gl_ctx);
1339 
1340 	if (!glu::contextSupports(renderCtx.getType(), glu::ApiType::core(4, 2)) &&
1341 		!ctxInfo.isExtensionSupported("GL_ARB_compressed_texture_pixel_storage"))
1342 	{
1343 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1344 								"GL_ARB_compressed_texture_pixel_storage extension is not supported");
1345 		return STOP;
1346 	}
1347 
1348 	switch (m_internalFormat)
1349 	{
1350 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1351 		if (!ctxInfo.isExtensionSupported("GL_EXT_texture_compression_s3tc"))
1352 		{
1353 			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1354 									"GL_EXT_texture_compression_s3tc extension is not supported");
1355 			return STOP;
1356 		}
1357 
1358 		m_bw = 4;
1359 		m_bh = 4;
1360 		m_bd = 1;
1361 		m_bs = 8;
1362 
1363 		generateSrcData_s3tc();
1364 		break;
1365 	case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1366 		if (!ctxInfo.isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
1367 		{
1368 			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1369 									"GL_KHR_texture_compression_astc_ldr extension is not supported");
1370 			return STOP;
1371 		}
1372 		m_bw = 8;
1373 		m_bh = 5;
1374 		m_bd = 1;
1375 		m_bs = 16;
1376 
1377 		generateSrcData_astc();
1378 		break;
1379 	default:
1380 		TCU_FAIL("Invalid internal format");
1381 	}
1382 
1383 	createTexture();
1384 	createShader();
1385 
1386 	dst = renderToSurf();
1387 	pass = verify(dst, &errMask);
1388 
1389 	cleanup();
1390 
1391 	if (pass)
1392 	{
1393 		m_testCtx.getLog()
1394 		<< tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage
1395 		<< tcu::TestLog::ImageSet("ImageVerification", "Image verification")
1396 		<< tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
1397 		<< tcu::TestLog::EndImageSet;
1398 	}
1399 	else
1400 	{
1401 		m_testCtx.getLog()
1402 		<< tcu::TestLog::Message << "Image is invalid" << tcu::TestLog::EndMessage
1403 		<< tcu::TestLog::ImageSet("ErrorVerification", "Image verification")
1404 		<< tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
1405 		<< tcu::TestLog::Image("ErrorMask", "Error mask", errMask.getAccess())
1406 		<< tcu::TestLog::EndImageSet;
1407 	}
1408 
1409 	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1410 							pass ? "Pass" : "Fail");
1411 
1412 	return STOP;
1413 }
1414 
generateSrcData_s3tc(void)1415 void CompressedTexImage2DCase::generateSrcData_s3tc (void)
1416 {
1417 	deUint64 *src = new deUint64[m_cuboid_w / m_bw * m_cuboid_h / m_bh];
1418 
1419 	deUint64 col = 0x0;
1420 
1421 	for (int y = 0; y < m_cuboid_h; y += m_bh)
1422 	{
1423 		for (int x = 0; x < m_cuboid_w; x += m_bw)
1424 		{
1425 			if (inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w) &&
1426 				inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h))
1427 			{
1428 				col = 0xffff;
1429 			}
1430 			else
1431 			{
1432 				col = 0x0;
1433 			}
1434 			int index = (y / m_bh) * (m_cuboid_w / m_bw) +
1435 							(x / m_bw);
1436 			src[index] = col;
1437 		}
1438 	}
1439 
1440 	m_src_data = (glw::GLubyte*)src;
1441 }
1442 
generateSrcData_astc(void)1443 void CompressedTexImage2DCase::generateSrcData_astc (void)
1444 {
1445 	deUint64 col = 0x0;
1446 	deUint64 mask = 0xfffffffffffffdfc;
1447 
1448 	int img_size = 2 * (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) *
1449 				   (m_cuboid_h / m_bh + (m_cuboid_h % m_bh > 0));
1450 
1451 	deUint64 *src = new deUint64[img_size];
1452 
1453 	for (int y = 0; y < m_cuboid_h; y += m_bh)
1454 	{
1455 		for (int x = 0; x < m_cuboid_w; x += m_bw)
1456 		{
1457 			if (inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w) &&
1458 				inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h))
1459 			{
1460 				col = 0xffffffffffffffff; /* (1.0, 1.0, 1.0) */
1461 			}
1462 			else
1463 			{
1464 				col = 0x0; /* (0.0, 0.0, 0.0) */
1465 			}
1466 			int index = (y / m_bh) * (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) +
1467 						(x / m_bw);
1468 			src[2 * index] = mask;
1469 			src[2 * index + 1] = col;
1470 		}
1471 	}
1472 
1473 	m_src_data = (glw::GLubyte*)src;
1474 }
1475 
createTexture(void)1476 void CompressedTexImage2DCase::createTexture (void)
1477 {
1478 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1479 							m_testCtx.getLog());
1480 
1481 	gl.glGenTextures(1, &tex);
1482 	gl.glBindTexture(GL_TEXTURE_2D, tex);
1483 	gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1484 	gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1485 
1486 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE,	 m_bs);
1487 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH,	 m_bw);
1488 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, m_bh);
1489 
1490 	gl.glPixelStorei(GL_UNPACK_ROW_LENGTH,	 m_cuboid_w);
1491 	gl.glPixelStorei(GL_UNPACK_SKIP_ROWS,	 m_subcuboid_y0);
1492 	gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_subcuboid_x0);
1493 
1494 	gl.glCompressedTexImage2D(GL_TEXTURE_2D,
1495 							  0,
1496 							  m_internalFormat,
1497 							  m_subcuboid_w,
1498 							  m_subcuboid_h,
1499 							  0,
1500 							  getImageSize(m_subcuboid_w,
1501 										   m_subcuboid_h,
1502 										   m_subcuboid_d),
1503 							  m_src_data);
1504 
1505 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE,	 0);
1506 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH,	 0);
1507 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT,  0);
1508 
1509 	gl.glPixelStorei(GL_UNPACK_ROW_LENGTH,	 0);
1510 	gl.glPixelStorei(GL_UNPACK_SKIP_ROWS,	 0);
1511 	gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS,  0);
1512 }
1513 
createShader(void)1514 void CompressedTexImage2DCase::createShader (void)
1515 {
1516 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1517 							m_testCtx.getLog());
1518 
1519 	const tcu::StringTemplate vs_src (vs_template_src);
1520 	const tcu::StringTemplate fs_src (fs_template_src);
1521 
1522 	std::map<std::string,std::string> params;
1523 	params["GLSL_VERSION"]	 = getGLSLVersionDeclaration(m_glsl_version);
1524 	params["TEXCOORDS_TYPE"] = "vec2";
1525 	params["LAYER"]			 = "";
1526 	params["TEXCOORDS"]		 = "pos.xy";
1527 	params["SAMPLER_TYPE"]	 = "sampler2D";
1528 	params["COL_TYPE"]		 = "vec4";
1529 	params["CONDITION"]		 = "colour.rgb == refcolour.rgb";
1530 
1531 	prog = new glu::ShaderProgram(m_context.getRenderContext(),
1532 								  glu::ProgramSources() <<
1533 								  glu::VertexSource(vs_src.specialize(params)) <<
1534 								  glu::FragmentSource(fs_src.specialize(params)));
1535 
1536 	if (!prog->isOk())
1537 	{
1538 		m_testCtx.getLog()
1539 			<< tcu::TestLog::Message << ""
1540 			<< tcu::TestLog::EndMessage
1541 			<< tcu::TestLog::ShaderProgram(false, "")
1542 			<< tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
1543 									prog->getShaderInfo(glu::SHADERTYPE_VERTEX,
1544 														0).source,
1545 									false,
1546 									prog->getShaderInfo(glu::SHADERTYPE_VERTEX,
1547 														0).infoLog)
1548 
1549 			<< tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
1550 									prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT,
1551 														0).source,
1552 									false,
1553 									prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT,
1554 														0).infoLog)
1555 			<< tcu::TestLog::EndShaderProgram;
1556 		TCU_FAIL("Shader creation failed");
1557 	}
1558 
1559 	gl.glUseProgram(prog->getProgram());
1560 	gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "sampler"), 0);
1561 }
1562 
renderToSurf(void)1563 tcu::Surface CompressedTexImage2DCase::renderToSurf (void)
1564 {
1565 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1566 							m_testCtx.getLog());
1567 
1568 	gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
1569 	gl.glClear(GL_COLOR_BUFFER_BIT);
1570 
1571 	static const float vertexPositions[4*3] =
1572 	{
1573 		-1.0, -1.0, -1.0f,
1574 		 1.0, -1.0,	 0.0f,
1575 		-1.0,  1.0,	 0.0f,
1576 		 1.0,  1.0,	 1.0f,
1577 	};
1578 
1579 	static const deUint16 indices[6] = { 0, 1, 2, 2, 1, 3 };
1580 
1581 	const glu::VertexArrayBinding attrBindings[] =
1582 	{
1583 		glu::va::Float("pos", 3, 4, 0, &vertexPositions[0])
1584 	};
1585 
1586 	gl.glViewport(0, 0, m_subcuboid_w, m_subcuboid_h);
1587 
1588 	glw::GLfloat refcol = 1.0f;
1589 
1590 	gl.glUniform4f(gl.glGetUniformLocation(prog->getProgram(), "refcolour"),
1591 				   refcol, refcol, refcol, 1.0f);
1592 
1593 	glu::draw(m_context.getRenderContext(),
1594 			  prog->getProgram(),
1595 			  DE_LENGTH_OF_ARRAY(attrBindings),
1596 			  &attrBindings[0],
1597 			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
1598 
1599 	tcu::Surface dst;
1600 	dst.setSize(m_subcuboid_w, m_subcuboid_h);
1601 
1602 	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1603 
1604 	return dst;
1605 }
1606 
cleanup(void)1607 void CompressedTexImage2DCase::cleanup (void)
1608 {
1609 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1610 							m_testCtx.getLog());
1611 
1612 	gl.glDeleteTextures(1, &tex);
1613 	delete[] m_src_data;
1614 	delete prog;
1615 }
1616 
1617 class CompressedTexImage3DCase : public deqp::TestCase
1618 							   , public sglr::ContextWrapper
1619 							   , public CompressedTexImageUtils
1620 {
1621 public:
1622 	CompressedTexImage3DCase (deqp::Context& context, const char *name, const char *desc,
1623 							  deUint32 internalFormat,
1624 							  int cuboid_w, int cuboid_h, int cuboid_d,
1625 							  int subcuboid_x0, int subcuboid_y0, int subcuboid_z0,
1626 							  int subcuboid_w, int subcuboid_h, int subcuboid_d,
1627 							  glu::GLSLVersion glsl_version);
1628 	~CompressedTexImage3DCase (void);
1629 	IterateResult iterate (void);
1630 protected:
1631 	void generateSrcData_s3tc (void);
1632 	void generateSrcData_astc (void);
1633 	void createTexture (void);
1634 	void createShader (void);
1635 	tcu::Surface renderToSurf (int layer);
1636 	void cleanup (void);
1637 };
1638 
CompressedTexImage3DCase(deqp::Context & context,const char * name,const char * desc,deUint32 internalFormat,int cuboid_w,int cuboid_h,int cuboid_d,int subcuboid_x0,int subcuboid_y0,int subcuboid_z0,int subcuboid_w,int subcuboid_h,int subcuboid_d,glu::GLSLVersion glsl_version)1639 CompressedTexImage3DCase::CompressedTexImage3DCase (deqp::Context& context,
1640 													const char *name,
1641 													const char *desc,
1642 													deUint32 internalFormat,
1643 													int cuboid_w,
1644 													int cuboid_h,
1645 													int cuboid_d,
1646 													int subcuboid_x0,
1647 													int subcuboid_y0,
1648 													int subcuboid_z0,
1649 													int subcuboid_w,
1650 													int subcuboid_h,
1651 													int subcuboid_d,
1652 													glu::GLSLVersion glsl_version)
1653 	: TestCase(context, name, desc)
1654 	, CompressedTexImageUtils(internalFormat,
1655 							  cuboid_w,
1656 							  cuboid_h,
1657 							  cuboid_d,
1658 							  subcuboid_x0,
1659 							  subcuboid_y0,
1660 							  subcuboid_z0,
1661 							  subcuboid_w,
1662 							  subcuboid_h,
1663 							  subcuboid_d,
1664 							  glsl_version)
1665 {
1666 }
1667 
~CompressedTexImage3DCase(void)1668 CompressedTexImage3DCase::~CompressedTexImage3DCase (void)
1669 {
1670 }
1671 
iterate(void)1672 CompressedTexImage3DCase::IterateResult CompressedTexImage3DCase::iterate (void)
1673 {
1674 	glu::RenderContext& renderCtx = TestCase::m_context.getRenderContext();
1675 	const glu::ContextInfo& ctxInfo = m_context.getContextInfo();
1676 	tcu::TestLog& log = m_testCtx.getLog();
1677 	tcu::Surface dst, errMask;
1678 
1679 	bool pass = true;
1680 
1681 	sglr::GLContext gl_ctx (renderCtx,
1682 							log,
1683 							sglr::GLCONTEXT_LOG_CALLS,
1684 							tcu::IVec4(0, 0, m_subcuboid_w, m_subcuboid_h));
1685 
1686 	setContext((sglr::Context*)&gl_ctx);
1687 
1688 	if (!glu::contextSupports(renderCtx.getType(), glu::ApiType::core(4, 2)) &&
1689 		!ctxInfo.isExtensionSupported("GL_ARB_compressed_texture_pixel_storage"))
1690 	{
1691 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1692 								"GL_ARB_compressed_texture_pixel_storage extension is not supported");
1693 		return STOP;
1694 	}
1695 
1696 	switch (m_internalFormat)
1697 	{
1698 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1699 		if (!ctxInfo.isExtensionSupported("GL_EXT_texture_compression_s3tc"))
1700 		{
1701 			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1702 									"GL_EXT_texture_compression_s3tc extension is not supported");
1703 			return STOP;
1704 		}
1705 
1706 		m_bw = 4;
1707 		m_bh = 4;
1708 		m_bd = 1;
1709 		m_bs = 8;
1710 
1711 		generateSrcData_s3tc();
1712 		break;
1713 	case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1714 		if (!ctxInfo.isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
1715 		{
1716 			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1717 									"GL_KHR_texture_compression_astc_ldr extension is not supported");
1718 			return STOP;
1719 		}
1720 		m_bw = 8;
1721 		m_bh = 5;
1722 		m_bd = 1;
1723 		m_bs = 16;
1724 
1725 		generateSrcData_astc();
1726 		break;
1727 	default:
1728 		TCU_FAIL("Invalid internal format");
1729 	}
1730 
1731 	createTexture();
1732 	createShader();
1733 
1734 	for (int z = 0; z < m_subcuboid_d; z++)
1735 	{
1736 		dst = renderToSurf(z);
1737 
1738 		bool layer_pass = verify(dst, &errMask);
1739 
1740 		if (layer_pass)
1741 		{
1742 			m_testCtx.getLog()
1743 				<< tcu::TestLog::Message << "Layer " << z	 << " is valid"
1744 				<< tcu::TestLog::EndMessage
1745 				<< tcu::TestLog::ImageSet("LayerVerification", "Layer verification")
1746 				<< tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
1747 				<< tcu::TestLog::EndImageSet;
1748 		}
1749 		else
1750 		{
1751 			m_testCtx.getLog()
1752 				<< tcu::TestLog::Message << "Layer " << z << " is invalid"
1753 				<< tcu::TestLog::EndMessage
1754 				<< tcu::TestLog::ImageSet("ErrorVerification", "Layer verification")
1755 				<< tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
1756 				<< tcu::TestLog::Image("ErrorMask", "Error mask", errMask.getAccess())
1757 				<< tcu::TestLog::EndImageSet;
1758 		}
1759 
1760 		pass &= layer_pass;
1761 	}
1762 
1763 	cleanup();
1764 
1765 	if (pass)
1766 	{
1767 		m_testCtx.getLog()
1768 			<< tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
1769 	}
1770 	else
1771 	{
1772 		m_testCtx.getLog()
1773 			<< tcu::TestLog::Message << "Image is invalid" << tcu::TestLog::EndMessage;
1774 	}
1775 
1776 	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1777 							pass ? "Pass" : "Fail");
1778 
1779 	return STOP;
1780 }
1781 
generateSrcData_s3tc()1782 void CompressedTexImage3DCase::generateSrcData_s3tc()
1783 {
1784 	deUint64 *src = new deUint64[m_cuboid_w / m_bw *
1785 								 m_cuboid_h / m_bh *
1786 								 m_cuboid_d / m_bd];
1787 
1788 	deUint64 col_list[] =
1789 	{
1790 		0x18E3,					/* (0.125, 0.125, 0.125) */
1791 		0x39E7,					/* (0.250, 0.250, 0.250) */
1792 		0x5AEB,					/* (0.375, 0.375, 0.375) */
1793 		0x7BEF,					/* (0.500, 0.500, 0.500) */
1794 		0x9CF3,					/* (0.625, 0.625, 0.625) */
1795 		0xBDF7,					/* (0.750, 0.750, 0.750) */
1796 		0xDEFB,					/* (0.875, 0.875, 0.875) */
1797 		0xffff,					/* (1.000, 1.000, 1.000) */
1798 	};
1799 
1800 	deUint64 col = 0x0;
1801 
1802 	for (int z = 0; z < m_cuboid_d; z += m_bd)
1803 	{
1804 		for (int y = 0; y < m_cuboid_h; y += m_bh)
1805 		{
1806 			for (int x = 0; x < m_cuboid_w; x += m_bw)
1807 			{
1808 				if (inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w) &&
1809 					inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h) &&
1810 					inrange(z, m_subcuboid_z0, m_subcuboid_z0 + m_subcuboid_d))
1811 					col = col_list[z % 8];
1812 				else
1813 					col = 0x0;
1814 
1815 				int index = (z / m_bd) * (m_cuboid_h / m_bh) * (m_cuboid_w / m_bw) +
1816 							(y / m_bh) * (m_cuboid_w / m_bw) +
1817 							(x / m_bw);
1818 				src[index] = col;
1819 			}
1820 		}
1821 	}
1822 
1823 	m_src_data = (glw::GLubyte*)src;
1824 }
1825 
generateSrcData_astc(void)1826 void CompressedTexImage3DCase::generateSrcData_astc (void)
1827 {
1828 	deUint64 col_list[] =
1829 	{
1830 		0xffff1fff1fff1fff,		/* (0.125, 0.125, 0.125) */
1831 		0xffff3fff3fff3fff,		/* (0.250, 0.250, 0.250) */
1832 		0xffff5fff5fff5fff,		/* (0.375, 0.375, 0.375) */
1833 		0xffff7fff7fff7fff,		/* (0.500, 0.500, 0.500) */
1834 		0xffff9fff9fff9fff,		/* (0.625, 0.625, 0.625) */
1835 		0xffffbfffbfffbfff,		/* (0.750, 0.750, 0.750) */
1836 		0xffffdfffdfffdfff,		/* (0.875, 0.875, 0.875) */
1837 		0xffffffffffffffff,		/* (1.000, 1.000, 1.000) */
1838 	};
1839 	deUint64 col = 0x0;
1840 	deUint64 mask = 0xFFFFFFFFFFFFFDFC;
1841 
1842 	int img_size = 2 * (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) *
1843 					   (m_cuboid_h / m_bh + (m_cuboid_h % m_bh > 0)) *
1844 					   (m_cuboid_d / m_bd + (m_cuboid_d % m_bd > 0));
1845 
1846 	deUint64 *src = new deUint64[img_size];
1847 
1848 	for (int z = 0; z < m_cuboid_d; z += m_bd)
1849 	{
1850 		for (int y = 0; y < m_cuboid_h; y += m_bh)
1851 		{
1852 			for (int x = 0; x < m_cuboid_w; x += m_bw)
1853 			{
1854 				if (inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w) &&
1855 					inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h) &&
1856 					inrange(z, m_subcuboid_z0, m_subcuboid_z0 + m_subcuboid_d))
1857 					col = col_list[z % 8];
1858 				else
1859 					col = 0x0;
1860 
1861 				int index = (z / m_bd) * (m_cuboid_h / m_bh + (m_cuboid_h % m_bh > 0)) *
1862 										 (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) +
1863 							(y / m_bh) * (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) +
1864 							(x / m_bw);
1865 				src[2 * index] = mask;
1866 				src[2 * index + 1] = col;
1867 			}
1868 		}
1869 	}
1870 
1871 	m_src_data = (glw::GLubyte*)src;
1872 }
1873 
createTexture(void)1874 void CompressedTexImage3DCase::createTexture (void)
1875 {
1876 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1877 							m_testCtx.getLog());
1878 
1879 	gl.glGenTextures(1, &tex);
1880 	gl.glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
1881 	gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1882 	gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1883 
1884 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE,	 m_bs);
1885 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH,	 m_bw);
1886 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT,  m_bh);
1887 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH,	 m_bd);
1888 
1889 	gl.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_cuboid_h);
1890 	gl.glPixelStorei(GL_UNPACK_ROW_LENGTH,	 m_cuboid_w);
1891 	gl.glPixelStorei(GL_UNPACK_SKIP_IMAGES,  m_subcuboid_z0);
1892 	gl.glPixelStorei(GL_UNPACK_SKIP_ROWS,	 m_subcuboid_y0);
1893 	gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS,  m_subcuboid_x0);
1894 
1895 	gl.glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY,
1896 							  0,
1897 							  m_internalFormat,
1898 							  m_subcuboid_w,
1899 							  m_subcuboid_h,
1900 							  m_subcuboid_d,
1901 							  0,
1902 							  getImageSize(m_subcuboid_w,
1903 										   m_subcuboid_h,
1904 										   m_subcuboid_d),
1905 							  m_src_data);
1906 
1907 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE,	 0);
1908 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH,	 0);
1909 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT,  0);
1910 	gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH,	 0);
1911 
1912 	gl.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
1913 	gl.glPixelStorei(GL_UNPACK_ROW_LENGTH,	 0);
1914 	gl.glPixelStorei(GL_UNPACK_SKIP_IMAGES,  0);
1915 	gl.glPixelStorei(GL_UNPACK_SKIP_ROWS,	 0);
1916 	gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS,  0);
1917 }
1918 
createShader(void)1919 void CompressedTexImage3DCase::createShader (void)
1920 {
1921 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1922 							m_testCtx.getLog());
1923 
1924 	const tcu::StringTemplate vs_src (vs_template_src);
1925 	const tcu::StringTemplate fs_src (fs_template_src);
1926 
1927 	std::map<std::string,std::string> params;
1928 	params["GLSL_VERSION"]	 = getGLSLVersionDeclaration(m_glsl_version);
1929 	params["TEXCOORDS_TYPE"] = "vec3";
1930 	params["LAYER"]			 = "uniform int layer;";
1931 	params["TEXCOORDS"]		 = "vec3(pos.xy, layer)";
1932 	params["SAMPLER_TYPE"]	 = "sampler2DArray";
1933 	params["COL_TYPE"]		 = "vec4";
1934 
1935 	const tcu::StringTemplate fs_condition ("all(lessThan((abs(colour - refcolour)).rgb, vec3(${EPS})))");
1936 	std::map<std::string,std::string> fs_condition_params;
1937 	fs_condition_params["EPS"] = std::to_string(getEps(m_internalFormat));
1938 	params["CONDITION"] = fs_condition.specialize(fs_condition_params);
1939 
1940 	prog = new glu::ShaderProgram(m_context.getRenderContext(),
1941 								  glu::ProgramSources() <<
1942 								  glu::VertexSource(vs_src.specialize(params)) <<
1943 								  glu::FragmentSource(fs_src.specialize(params)));
1944 
1945 	if (!prog->isOk())
1946 	{
1947 		m_testCtx.getLog()
1948 			<< tcu::TestLog::Message << ""
1949 			<< tcu::TestLog::EndMessage
1950 			<< tcu::TestLog::ShaderProgram(false, "")
1951 			<< tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
1952 									prog->getShaderInfo(glu::SHADERTYPE_VERTEX,
1953 														0).source,
1954 									false,
1955 									prog->getShaderInfo(glu::SHADERTYPE_VERTEX,
1956 														0).infoLog)
1957 
1958 			<< tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
1959 									prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT,
1960 														0).source,
1961 									false,
1962 									prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT,
1963 														0).infoLog)
1964 			<< tcu::TestLog::EndShaderProgram;
1965 		TCU_FAIL("Shader creation failed");
1966 	}
1967 
1968 	gl.glUseProgram(prog->getProgram());
1969 	gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "sampler"), 0);
1970 }
1971 
renderToSurf(int layer)1972 tcu::Surface CompressedTexImage3DCase::renderToSurf (int layer)
1973 {
1974 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
1975 							m_testCtx.getLog());
1976 
1977 	gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
1978 	gl.glClear(GL_COLOR_BUFFER_BIT);
1979 
1980 	static const float vertexPositions[4*3] =
1981 	{
1982 		-1.0, -1.0, -1.0f,
1983 		 1.0, -1.0,	 0.0f,
1984 		-1.0,  1.0,	 0.0f,
1985 		 1.0,  1.0,	 1.0f,
1986 	};
1987 
1988 	static const deUint16 indices[6] = { 0, 1, 2, 2, 1, 3 };
1989 
1990 	const glu::VertexArrayBinding attrBindings[] =
1991 	{
1992 		glu::va::Float("pos", 3, 4, 0, &vertexPositions[0])
1993 	};
1994 
1995 	gl.glViewport(0, 0, m_subcuboid_w, m_subcuboid_h);
1996 
1997 	gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "layer"), layer);
1998 
1999 	glw::GLfloat refcols[8] = { 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0 };
2000 	glw::GLfloat refcol = refcols[(layer + m_subcuboid_z0 % 8) % 8];
2001 
2002 	gl.glUniform4f(gl.glGetUniformLocation(prog->getProgram(), "refcolour"),
2003 				   refcol, refcol, refcol, 1.0f);
2004 
2005 	glu::draw(m_context.getRenderContext(),
2006 			  prog->getProgram(),
2007 			  DE_LENGTH_OF_ARRAY(attrBindings),
2008 			  &attrBindings[0],
2009 			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
2010 
2011 	tcu::Surface dst;
2012 	dst.setSize(m_subcuboid_w, m_subcuboid_h);
2013 
2014 	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
2015 
2016 	return dst;
2017 }
2018 
cleanup(void)2019 void CompressedTexImage3DCase::cleanup (void)
2020 {
2021 	glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(),
2022 							m_testCtx.getLog());
2023 
2024 	gl.glDeleteTextures(1, &tex);
2025 	delete[] m_src_data;
2026 	delete prog;
2027 }
2028 
PixelStorageModesTests(deqp::Context & context,glu::GLSLVersion glsl_version)2029 PixelStorageModesTests::PixelStorageModesTests (deqp::Context& context,
2030 												glu::GLSLVersion glsl_version)
2031 	: TestCaseGroup(context, "pixelstoragemodes", "Pixel Storage Modes Tests")
2032 	, m_glsl_version(glsl_version)
2033 {
2034 }
2035 
~PixelStorageModesTests(void)2036 PixelStorageModesTests::~PixelStorageModesTests (void)
2037 {
2038 }
2039 
init(void)2040 void PixelStorageModesTests::init(void)
2041 {
2042 	const int cuboid_w = 64;
2043 	const int cuboid_h = 64;
2044 	const int cuboid_d = 64;
2045 	const int subcuboid_w = 32;
2046 	const int subcuboid_h = 32;
2047 	const int subcuboid_d = 8;
2048 
2049 	struct
2050 	{
2051 		const char *name;
2052 		deUint32 internalFmt;
2053 	} internalFmts[] =
2054 	{
2055 		{ "r8",			 GL_R8,				  },
2056 		{ "r8snorm",	 GL_R8_SNORM,		  },
2057 		{ "r16f",		 GL_R16F,			  },
2058 		{ "r32f",		 GL_R32F,			  },
2059 		{ "r8ui",		 GL_R8UI,			  },
2060 		{ "r8i",		 GL_R8I,			  },
2061 		{ "r16ui",		 GL_R16UI,			  },
2062 		{ "r16i",		 GL_R16I,			  },
2063 		{ "r32ui",		 GL_R32UI,			  },
2064 		{ "r32i",		 GL_R32I,			  },
2065 		{ "rg8",		 GL_RG8,			  },
2066 		{ "rg8snorm",	 GL_RG8_SNORM,		  },
2067 		{ "rg16f",		 GL_RG16F,			  },
2068 		{ "rg32f",		 GL_RG32F,			  },
2069 		{ "rg8ui",		 GL_RG8UI,			  },
2070 		{ "rg8i",		 GL_RG8I,			  },
2071 		{ "rg16ui",		 GL_RG16UI,			  },
2072 		{ "rg16i",		 GL_RG16I,			  },
2073 		{ "rg32ui",		 GL_RG32UI,			  },
2074 		{ "rg32i",		 GL_RG32I,			  },
2075 		{ "rgb8",		 GL_RGB8,			  },
2076 		{ "rgb565",		 GL_RGB565,			  },
2077 		{ "rgb8snorm",	 GL_RGB8_SNORM,		  },
2078 		{ "r11g11b10f",	 GL_R11F_G11F_B10F,	  },
2079 		{ "rgb16f",		 GL_RGB16F,			  },
2080 		{ "rgb32f",		 GL_RGB32F,			  },
2081 		{ "rgb8ui",		 GL_RGB8UI,			  },
2082 		{ "rgb8i",		 GL_RGB8I,			  },
2083 		{ "rgb16ui",	 GL_RGB16UI,		  },
2084 		{ "rgb16i",		 GL_RGB16I,			  },
2085 		{ "rgb32ui",	 GL_RGB32UI,		  },
2086 		{ "rgb32i",		 GL_RGB32I,			  },
2087 		{ "rgba8",		 GL_RGBA8,			  },
2088 		{ "rgba8snorm",	 GL_RGBA8_SNORM,	  },
2089 		{ "rgb5a1",		 GL_RGB5_A1,		  },
2090 		{ "rgba4",		 GL_RGBA4,			  },
2091 		{ "rgb10a2",	 GL_RGB10_A2,		  },
2092 		{ "rgba16f",	 GL_RGBA16F,		  },
2093 		{ "rgba32f",	 GL_RGBA32F,		  },
2094 		{ "rgba8ui",	 GL_RGBA8UI,		  },
2095 		{ "rgba8i",		 GL_RGBA8I,			  },
2096 		{ "rgb10a2ui",	 GL_RGB10_A2UI,		  },
2097 		{ "rgba16ui",	 GL_RGBA16UI,		  },
2098 		{ "rgba16i",	 GL_RGBA16I,		  },
2099 		{ "rgba32i",	 GL_RGBA32I,		  },
2100 		{ "rgba32ui",	 GL_RGBA32UI,		  },
2101 	};
2102 
2103 	struct
2104 	{
2105 		const char *name;
2106 		deUint32 internalFmt;
2107 		int bw;
2108 		int bh;
2109 		int bd;
2110 	} internalFmts_compressed[] =
2111 	{
2112 		{ "rgb_s3tc_dxt1", GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 1 },
2113 		{ "rgba_astc_8x5", GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 8, 5, 1 },
2114 	};
2115 
2116 	tcu::TestCaseGroup* texImage2DGroup = new tcu::TestCaseGroup(m_testCtx,
2117 																 "teximage2d",
2118 																 "glTexImage2D cases");
2119 	addChild(texImage2DGroup);
2120 
2121 	for (int fmts = 0; fmts < DE_LENGTH_OF_ARRAY(internalFmts); fmts++)
2122 	{
2123 		tcu::TestCaseGroup* formatsGroup = new tcu::TestCaseGroup(m_testCtx,
2124 																  internalFmts[fmts].name,
2125 																  "");
2126 		texImage2DGroup->addChild(formatsGroup);
2127 		int bw = 1;
2128 		int bh = 1;
2129 		int skip_pixels[3] =
2130 			{ 0, bw, bw * (subcuboid_w / (2 * bw)) };
2131 		int skip_rows[3] =
2132 			{ 0, bh, bh * (subcuboid_h / (2 * bh)) };
2133 
2134 		for (int r = 0; r < 3; r++)
2135 		{
2136 			for (int p = r; p < 3; p++)
2137 			{
2138 				std::string skip_name =
2139 					std::to_string(skip_pixels[p]) +
2140 					"_" +
2141 					std::to_string(skip_rows[r]);
2142 				std::string skip_desc =
2143 					"Skip " +
2144 					std::to_string(skip_pixels[p]) +
2145 					" pixels and " +
2146 					std::to_string(skip_rows[r]) +
2147 					" rows";
2148 				formatsGroup->addChild(new TexImage2DCase(m_context,
2149 														  skip_name.c_str(),
2150 														  skip_desc.c_str(),
2151 														  internalFmts[fmts].internalFmt,
2152 														  cuboid_w,
2153 														  cuboid_h,
2154 														  skip_pixels[p],
2155 														  skip_rows[r],
2156 														  subcuboid_w,
2157 														  subcuboid_h,
2158 														  m_glsl_version));
2159 			}
2160 		}
2161 	}
2162 
2163 	tcu::TestCaseGroup* texImage3DGroup = new tcu::TestCaseGroup(m_testCtx,
2164 																 "teximage3d",
2165 																 "glTexImage3D cases");
2166 	addChild(texImage3DGroup);
2167 
2168 	for (int fmts = 0; fmts < DE_LENGTH_OF_ARRAY(internalFmts); fmts++)
2169 	{
2170 		tcu::TestCaseGroup* formatsGroup = new tcu::TestCaseGroup(m_testCtx,
2171 																  internalFmts[fmts].name,
2172 																  "");
2173 		texImage3DGroup->addChild(formatsGroup);
2174 		int bw = 1;
2175 		int bh = 1;
2176 		int bd = 1;
2177 		int skip_pixels[3] =
2178 			{ 0, bw, bw * (subcuboid_w / (2 * bw)) };
2179 		int skip_rows[3] =
2180 			{ 0, bh, bh * (subcuboid_h / (2 * bh)) };
2181 		int skip_images[3] =
2182 			{ 0, bd, bd * (subcuboid_d / (2 * bd)) };
2183 
2184 		for (int i = 0; i < 3; i++)
2185 		{
2186 			for (int r = i; r < 3; r++)
2187 			{
2188 				for (int p = r; p < 3; p++)
2189 				{
2190 					std::string skip_name =
2191 						std::to_string(skip_pixels[p]) +
2192 						"_" +
2193 						std::to_string(skip_rows[r]) +
2194 						"_" +
2195 						std::to_string(skip_images[i]);
2196 					std::string skip_desc =
2197 						"Skip " +
2198 						std::to_string(skip_pixels[p]) +
2199 						" pixels, " +
2200 						std::to_string(skip_rows[r]) +
2201 						" rows, and " +
2202 						std::to_string(skip_images[i]) +
2203 						" images";
2204 					formatsGroup->addChild(new TexImage3DCase(m_context,
2205 															  skip_name.c_str(),
2206 															  skip_desc.c_str(),
2207 															  internalFmts[fmts].internalFmt,
2208 															  cuboid_w,
2209 															  cuboid_h,
2210 															  cuboid_d,
2211 															  skip_pixels[p],
2212 															  skip_rows[r],
2213 															  skip_images[i],
2214 															  subcuboid_w,
2215 															  subcuboid_h,
2216 															  subcuboid_d,
2217 															  m_glsl_version));
2218 				}
2219 			}
2220 		}
2221 	}
2222 
2223 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
2224 	{
2225 		tcu::TestCaseGroup* compressedTexImage2DGroup =
2226 			new tcu::TestCaseGroup(m_testCtx,
2227 								   "compressedteximage2d",
2228 								   "glCompressedTexImage2D cases");
2229 		addChild(compressedTexImage2DGroup);
2230 
2231 		for (int fmts = 0; fmts < DE_LENGTH_OF_ARRAY(internalFmts_compressed); fmts++)
2232 		{
2233 			tcu::TestCaseGroup* formatsGroup
2234 				= new tcu::TestCaseGroup(m_testCtx,
2235 										 internalFmts_compressed[fmts].name,
2236 										 "");
2237 			compressedTexImage2DGroup->addChild(formatsGroup);
2238 			int bw = internalFmts_compressed[fmts].bw;
2239 			int bh = internalFmts_compressed[fmts].bh;
2240 			int skip_pixels[4] =
2241 				{ 0, bw, bw * (subcuboid_w / (2 * bw)), bw * (subcuboid_w / bw) };
2242 			int skip_rows[4] =
2243 				{ 0, bh, bh * (subcuboid_h / (2 * bh)), bh * (subcuboid_h / bh) };
2244 			for (int r = 0; r < 4; r++)
2245 			{
2246 				for (int p = 0; p < 4; p++)
2247 				{
2248 					std::string skip_name =
2249 						std::to_string(skip_pixels[p]) +
2250 						"_" +
2251 						std::to_string(skip_rows[r]);
2252 					std::string skip_desc =
2253 						"Skip " +
2254 						std::to_string(skip_pixels[p]) +
2255 						" pixels and " +
2256 						std::to_string(skip_rows[r]) +
2257 						" rows";
2258 					formatsGroup->addChild(new CompressedTexImage2DCase(
2259 											  m_context,
2260 											  skip_name.c_str(),
2261 											  skip_desc.c_str(),
2262 											  internalFmts_compressed[fmts].internalFmt,
2263 											  cuboid_w,
2264 											  cuboid_h,
2265 											  skip_pixels[p],
2266 											  skip_rows[r],
2267 											  subcuboid_w,
2268 											  subcuboid_h,
2269 											  m_glsl_version));
2270 				}
2271 			}
2272 		}
2273 
2274 		tcu::TestCaseGroup* compressedTexImage3DGroup =
2275 			new tcu::TestCaseGroup(m_testCtx,
2276 								   "compressedteximage3d",
2277 								   "glCompressedTexImage3D cases");
2278 		addChild(compressedTexImage3DGroup);
2279 
2280 		for (int fmts = 0; fmts < DE_LENGTH_OF_ARRAY(internalFmts_compressed); fmts++)
2281 		{
2282 			tcu::TestCaseGroup* formatsGroup
2283 				= new tcu::TestCaseGroup(m_testCtx,
2284 										 internalFmts_compressed[fmts].name,
2285 										 "");
2286 			compressedTexImage3DGroup->addChild(formatsGroup);
2287 			int bw = internalFmts_compressed[fmts].bw;
2288 			int bh = internalFmts_compressed[fmts].bh;
2289 			int bd = internalFmts_compressed[fmts].bd;
2290 			int skip_pixels[4] =
2291 				{ 0, bw, bw * (subcuboid_w / (2 * bw)), bw * (subcuboid_w / bw) };
2292 			int skip_rows[4] =
2293 				{ 0, bh, bh * (subcuboid_h / (2 * bh)), bh * (subcuboid_h / bh) };
2294 			int skip_images[4] =
2295 				{ 0, bd, bd * (subcuboid_d / (2 * bd)), bd * (subcuboid_d / bd) };
2296 			for (int i = 0; i < 4; i++)
2297 			{
2298 				for (int r = 0; r < 4; r++)
2299 				{
2300 					for (int p = 0; p < 4; p++)
2301 					{
2302 						std::string skip_name =
2303 							std::to_string(skip_pixels[p]) +
2304 							"_" +
2305 							std::to_string(skip_rows[r]) +
2306 							"_" +
2307 							std::to_string(skip_images[i]);
2308 						std::string skip_desc =
2309 							"Skip " +
2310 							std::to_string(skip_pixels[p]) +
2311 							" pixels, " +
2312 							std::to_string(skip_rows[r]) +
2313 							" rows, and " +
2314 							std::to_string(skip_images[i]) +
2315 							" images";
2316 						formatsGroup->addChild(new CompressedTexImage3DCase(
2317 												  m_context,
2318 												  skip_name.c_str(),
2319 												  skip_desc.c_str(),
2320 												  internalFmts_compressed[fmts].internalFmt,
2321 												  cuboid_w,
2322 												  cuboid_h,
2323 												  cuboid_d,
2324 												  skip_pixels[p],
2325 												  skip_rows[r],
2326 												  skip_images[i],
2327 												  subcuboid_w,
2328 												  subcuboid_h,
2329 												  subcuboid_d,
2330 												  m_glsl_version));
2331 					}
2332 				}
2333 			}
2334 		}
2335 	}
2336 }
2337 
2338 } /* namespace glcts */
2339