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