Home | History | Annotate | Download | only in gl
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2015-2016 The Khronos Group Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  */ /*!
     20  * \file
     21  * \brief
     22  */ /*-------------------------------------------------------------------*/
     23 
     24 #include "gl4cCopyImageTests.hpp"
     25 
     26 #include "gluDefs.hpp"
     27 #include "gluStrUtil.hpp"
     28 #include "glwEnums.hpp"
     29 #include "glwFunctions.hpp"
     30 #include "tcuFloat.hpp"
     31 #include "tcuTestLog.hpp"
     32 
     33 #include <algorithm>
     34 #include <iomanip>
     35 #include <sstream>
     36 
     37 #include "deMath.h"
     38 
     39 /* There are far too much combinations specified for FunctionalTest.
     40  *
     41  * Following flags controls what is enabled. Set as 1 to enable
     42  * all test case from given category, 0 otherwise.
     43  *
     44  * By default everything is disabled - which still gives 14560 test cases.
     45  *
     46  * ALL_FORMAT  - selects all internal formats, 61 x 61
     47  * ALL_TARGETS - selects all valid targets, 10 x 10
     48  * ALL_IMG_DIM - selects all image dimmensions, 9 x 9
     49  * ALL_REG_DIM - selects all region dimmensions, 7 x 7
     50  * ALL_REG_POS - selects all region positions, like left-top corner, 8 x 8
     51  */
     52 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS 0
     53 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS 0
     54 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_IMG_DIM 0
     55 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_DIM 0
     56 #define COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS 0
     57 
     58 /* The following flags controls if workarounds are enabled */
     59 #define COPY_IMAGE_WRKARD_FORMATS 0
     60 
     61 using namespace glw;
     62 
     63 namespace gl4cts
     64 {
     65 namespace CopyImage
     66 {
     67 /** Various utilities used by all tests
     68  *
     69  **/
     70 class Utils
     71 {
     72 public:
     73 	/* Routines */
     74 	static bool areFormatsCompatible(glw::GLenum src, glw::GLenum dst);
     75 
     76 	static bool comparePixels(glw::GLenum left_internal_format, const glw::GLdouble& left_red,
     77 							  const glw::GLdouble& left_green, const glw::GLdouble& left_blue,
     78 							  const glw::GLdouble& left_alpha, glw::GLenum right_internal_format,
     79 							  const glw::GLdouble& right_red, const glw::GLdouble& right_green,
     80 							  const glw::GLdouble& right_blue, const glw::GLdouble& right_alpha);
     81 
     82 	static bool comparePixels(glw::GLuint left_pixel_size, const glw::GLubyte* left_pixel_data,
     83 							  glw::GLuint right_pixel_size, const glw::GLubyte* right_pixel_data);
     84 
     85 	static void deleteTexture(deqp::Context& context, glw::GLenum target, glw::GLuint name);
     86 
     87 	static bool isTargetMultilayer(glw::GLenum target);
     88 	static bool isTargetMultilevel(glw::GLenum target);
     89 	static bool isTargetMultisampled(glw::GLenum target);
     90 
     91 	static glw::GLuint generateTexture(deqp::Context& context, glw::GLenum target);
     92 
     93 	static void maskPixelForFormat(glw::GLenum internal_format, glw::GLubyte* pixel);
     94 
     95 	static glw::GLdouble getEpsilon(glw::GLenum internal_format);
     96 	static glw::GLuint getPixelSizeForFormat(glw::GLenum internal_format);
     97 	static glw::GLenum getFormat(glw::GLenum internal_format);
     98 	static glw::GLuint getNumberOfChannels(glw::GLenum internal_format);
     99 
    100 	static std::string getPixelString(glw::GLenum internal_format, const glw::GLubyte* pixel);
    101 
    102 	static glw::GLenum getType(glw::GLenum internal_format);
    103 	static void makeTextureComplete(deqp::Context& context, glw::GLenum target, glw::GLuint id, glw::GLint base_level,
    104 									glw::GLint max_level);
    105 
    106 	static glw::GLuint prepareCompressedTex(deqp::Context& context, glw::GLenum target, glw::GLenum internal_format);
    107 
    108 	static glw::GLuint prepareMultisampleTex(deqp::Context& context, glw::GLenum target, glw::GLsizei n_samples);
    109 
    110 	static glw::GLuint prepareRenderBuffer(deqp::Context& context, glw::GLenum internal_format);
    111 
    112 	static glw::GLuint prepareTex16x16x6(deqp::Context& context, glw::GLenum target, glw::GLenum internal_format,
    113 										 glw::GLenum format, glw::GLenum type, glw::GLuint& out_buf_id);
    114 
    115 	static void prepareTexture(deqp::Context& context, glw::GLuint name, glw::GLenum target,
    116 							   glw::GLenum internal_format, glw::GLenum format, glw::GLenum type, glw::GLuint level,
    117 							   glw::GLuint width, glw::GLuint height, glw::GLuint depth, const glw::GLvoid* pixels,
    118 							   glw::GLuint& out_buf_id);
    119 
    120 	static glw::GLenum transProxyToRealTarget(glw::GLenum target);
    121 	static glw::GLenum transRealToBindTarget(glw::GLenum target);
    122 
    123 	static void readChannel(glw::GLenum type, glw::GLuint channel, const glw::GLubyte* pixel, glw::GLdouble& out_value);
    124 
    125 	static void writeChannel(glw::GLenum type, glw::GLuint channel, glw::GLdouble value, glw::GLubyte* pixel);
    126 
    127 	static void packPixel(glw::GLenum internal_format, glw::GLenum type, glw::GLdouble red, glw::GLdouble green,
    128 						  glw::GLdouble blue, glw::GLdouble alpha, glw::GLubyte* out_pixel);
    129 
    130 	static void unpackPixel(glw::GLenum format, glw::GLenum type, const glw::GLubyte* pixel, glw::GLdouble& out_red,
    131 							glw::GLdouble& out_green, glw::GLdouble& out_blue, glw::GLdouble& out_alpha);
    132 
    133 	static bool unpackAndComaprePixels(glw::GLenum left_format, glw::GLenum left_type, glw::GLenum left_internal_format,
    134 									   const glw::GLubyte* left_pixel, glw::GLenum right_format, glw::GLenum right_type,
    135 									   glw::GLenum right_internal_format, const glw::GLubyte* right_pixel);
    136 
    137 	static inline bool roundComponent(glw::GLenum internal_format, glw::GLenum component, glw::GLdouble& value);
    138 };
    139 
    140 /* Global constants */
    141 static const GLenum s_internal_formats[] = {
    142 	/* R8 */
    143 	GL_R8, GL_R8I, GL_R8UI, GL_R8_SNORM,
    144 
    145 	/* R16 */
    146 	GL_R16, GL_R16F, GL_R16I, GL_R16UI, GL_R16_SNORM,
    147 
    148 	/* R32 */
    149 	GL_R32F, GL_R32I, GL_R32UI,
    150 
    151 	/* RG8 */
    152 	GL_RG8, GL_RG8I, GL_RG8UI, GL_RG8_SNORM,
    153 
    154 	/* RG16 */
    155 	GL_RG16, GL_RG16F, GL_RG16I, GL_RG16UI, GL_RG16_SNORM,
    156 
    157 	/* RG32 */
    158 	GL_RG32F, GL_RG32I, GL_RG32UI,
    159 
    160 	/* RGB8 */
    161 	GL_RGB8, GL_RGB8I, GL_RGB8UI, GL_RGB8_SNORM,
    162 
    163 	/* RGB16 */
    164 	GL_RGB16, GL_RGB16F, GL_RGB16I, GL_RGB16UI, GL_RGB16_SNORM,
    165 
    166 	/* RGB32 */
    167 	GL_RGB32F, GL_RGB32I, GL_RGB32UI,
    168 
    169 	/* RGBA8 */
    170 	GL_RGBA8, GL_RGBA8I, GL_RGBA8UI, GL_RGBA8_SNORM,
    171 
    172 	/* RGBA16 */
    173 	GL_RGBA16, GL_RGBA16F, GL_RGBA16I, GL_RGBA16UI, GL_RGBA16_SNORM,
    174 
    175 	/* RGBA32 */
    176 	GL_RGBA32F, GL_RGBA32I, GL_RGBA32UI,
    177 
    178 	/* 8 */
    179 	GL_R3_G3_B2, GL_RGBA2,
    180 
    181 	/* 12 */
    182 	GL_RGB4,
    183 
    184 	/* 15 */
    185 	GL_RGB5,
    186 
    187 	/* 16 */
    188 	GL_RGBA4, GL_RGB5_A1,
    189 
    190 	/* 30 */
    191 	GL_RGB10,
    192 
    193 	/* 32 */
    194 	GL_RGB10_A2, GL_RGB10_A2UI, GL_R11F_G11F_B10F, GL_RGB9_E5,
    195 
    196 	/* 36 */
    197 	GL_RGB12,
    198 
    199 	/* 48 */
    200 	GL_RGBA12,
    201 };
    202 
    203 static const GLenum s_invalid_targets[] = {
    204 	GL_TEXTURE_BUFFER,
    205 	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
    206 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
    207 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
    208 	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
    209 	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
    210 	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
    211 	GL_PROXY_TEXTURE_1D,
    212 	GL_PROXY_TEXTURE_1D_ARRAY,
    213 	GL_PROXY_TEXTURE_2D,
    214 	GL_PROXY_TEXTURE_2D_ARRAY,
    215 	GL_PROXY_TEXTURE_2D_MULTISAMPLE,
    216 	GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY,
    217 	GL_PROXY_TEXTURE_3D,
    218 	GL_PROXY_TEXTURE_CUBE_MAP,
    219 	GL_PROXY_TEXTURE_CUBE_MAP_ARRAY,
    220 	GL_PROXY_TEXTURE_RECTANGLE,
    221 };
    222 
    223 static const GLenum s_valid_targets[] = {
    224 	GL_RENDERBUFFER,
    225 	GL_TEXTURE_1D,
    226 	GL_TEXTURE_1D_ARRAY,
    227 	GL_TEXTURE_2D,
    228 	GL_TEXTURE_2D_ARRAY,
    229 	GL_TEXTURE_2D_MULTISAMPLE,
    230 	GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
    231 	GL_TEXTURE_3D,
    232 	GL_TEXTURE_CUBE_MAP,
    233 	GL_TEXTURE_CUBE_MAP_ARRAY,
    234 	GL_TEXTURE_RECTANGLE,
    235 };
    236 
    237 static const GLuint s_n_internal_formats = sizeof(s_internal_formats) / sizeof(s_internal_formats[0]);
    238 static const GLuint s_n_invalid_targets  = sizeof(s_invalid_targets) / sizeof(s_invalid_targets[0]);
    239 static const GLuint s_n_valid_targets	= sizeof(s_valid_targets) / sizeof(s_valid_targets[0]);
    240 
    241 /**
    242  * Pixel compatibility depends on pixel size. However value returned by getPixelSizeForFormat
    243  * needs some refinements
    244  *
    245  * @param internal_format Internal format of image
    246  *
    247  * @return Size of pixel for compatibility checks
    248  **/
    249 GLuint getPixelSizeForCompatibilityVerification(GLenum internal_format)
    250 {
    251 	GLuint size = Utils::getPixelSizeForFormat(internal_format);
    252 
    253 	switch (internal_format)
    254 	{
    255 	case GL_RGBA2:
    256 		size = 1;
    257 		break;
    258 	default:
    259 		break;
    260 	}
    261 
    262 	return size;
    263 }
    264 
    265 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS == 0
    266 
    267 /** Filters out formats that should not be tested by FunctionalTest
    268  *
    269  * @param format Internal format
    270  *
    271  * @return true if format should be tested, false otherwise
    272  **/
    273 bool filterFormats(GLenum format)
    274 {
    275 	bool result = true;
    276 
    277 	switch (format)
    278 	{
    279 	/* R8 */
    280 	case GL_R8I:
    281 	case GL_R8UI:
    282 	case GL_R8_SNORM:
    283 
    284 	/* R16 */
    285 	case GL_R16:
    286 	case GL_R16F:
    287 	case GL_R16I:
    288 	case GL_R16UI:
    289 	case GL_R16_SNORM:
    290 
    291 	/* R32 */
    292 	case GL_R32F:
    293 	case GL_R32I:
    294 	case GL_R32UI:
    295 
    296 	/* RG8 */
    297 	case GL_RG8:
    298 	case GL_RG8I:
    299 	case GL_RG8UI:
    300 	case GL_RG8_SNORM:
    301 
    302 	/* RG16 */
    303 	case GL_RG16:
    304 	case GL_RG16F:
    305 	case GL_RG16I:
    306 	case GL_RG16UI:
    307 	case GL_RG16_SNORM:
    308 
    309 	/* RG32 */
    310 	case GL_RG32F:
    311 	case GL_RG32I:
    312 	case GL_RG32UI:
    313 
    314 	/* RGB8 */
    315 	case GL_RGB8:
    316 	case GL_RGB8I:
    317 	case GL_RGB8UI:
    318 	case GL_RGB8_SNORM:
    319 
    320 	/* RGB16 */
    321 	case GL_RGB16:
    322 	case GL_RGB16F:
    323 	case GL_RGB16I:
    324 	case GL_RGB16UI:
    325 	case GL_RGB16_SNORM:
    326 
    327 	/* RGB32 */
    328 	case GL_RGB32I:
    329 	case GL_RGB32UI:
    330 
    331 	/* RGBA8 */
    332 	case GL_RGBA8:
    333 	case GL_RGBA8I:
    334 	case GL_RGBA8UI:
    335 	case GL_RGBA8_SNORM:
    336 
    337 	/* RGBA16 */
    338 	case GL_RGBA16:
    339 	case GL_RGBA16F:
    340 	case GL_RGBA16I:
    341 	case GL_RGBA16UI:
    342 	case GL_RGBA16_SNORM:
    343 
    344 	/* RGBA32 */
    345 	case GL_RGBA32F:
    346 	case GL_RGBA32I:
    347 	case GL_RGBA32UI:
    348 		result = false;
    349 		break;
    350 
    351 	default:
    352 		result = true;
    353 		break;
    354 	}
    355 
    356 	return result;
    357 }
    358 
    359 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS */
    360 
    361 /** Checks if two internal_formats are compatible
    362  *
    363  * @param src Internal format of source image
    364  * @param dst Internal format of destination image
    365  *
    366  * @return true for compatible formats, false otherwise
    367  **/
    368 bool Utils::areFormatsCompatible(glw::GLenum src, glw::GLenum dst)
    369 {
    370 	const GLuint dst_size = getPixelSizeForCompatibilityVerification(dst);
    371 	const GLuint src_size = getPixelSizeForCompatibilityVerification(src);
    372 
    373 	if (dst_size != src_size)
    374 	{
    375 		return false;
    376 	}
    377 
    378 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS == 0
    379 
    380 	if ((false == filterFormats(src)) || (false == filterFormats(dst)))
    381 	{
    382 		return false;
    383 	}
    384 
    385 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_FORMATS */
    386 
    387 	if (src != dst)
    388 	{
    389 		if ((GL_R3_G3_B2 == dst) || (GL_R3_G3_B2 == src) || (GL_RGBA2 == dst) || (GL_RGBA2 == src) ||
    390 			(GL_RGBA4 == dst) || (GL_RGBA4 == src) || (GL_RGB5_A1 == dst) || (GL_RGB5_A1 == src) || (GL_RGB10 == dst) ||
    391 			(GL_RGB10 == src))
    392 		{
    393 			return false;
    394 		}
    395 	}
    396 
    397 #if COPY_IMAGE_WRKARD_FORMATS
    398 
    399 	if ((GL_RGB10_A2 == src) && (GL_R11F_G11F_B10F == dst) || (GL_RGB10_A2 == src) && (GL_RGB9_E5 == dst) ||
    400 		(GL_RGB10_A2UI == src) && (GL_R11F_G11F_B10F == dst) || (GL_RGB10_A2UI == src) && (GL_RGB9_E5 == dst) ||
    401 		(GL_RGB9_E5 == src) && (GL_RGB10_A2 == dst) || (GL_RGB9_E5 == src) && (GL_RGB10_A2UI == dst) ||
    402 		(GL_R11F_G11F_B10F == src) && (GL_RGB10_A2 == dst) || (GL_R11F_G11F_B10F == src) && (GL_RGB10_A2UI == dst))
    403 	{
    404 		return false;
    405 	}
    406 
    407 #endif /* COPY_IMAGE_WRKARD_FORMATS */
    408 
    409 	if (2 == dst_size)
    410 	{
    411 		if (src == dst)
    412 		{
    413 			return true;
    414 		}
    415 
    416 		if (((GL_RGB4 == src) && (GL_RGB4 != dst)) || ((GL_RGB4 != src) && (GL_RGB4 == dst)) ||
    417 			((GL_RGB5 == src) && (GL_RGB5 != dst)) || ((GL_RGB5 != src) && (GL_RGB5 == dst)))
    418 		{
    419 			return false;
    420 		}
    421 
    422 		return true;
    423 	}
    424 
    425 	if (4 == dst_size)
    426 	{
    427 		if (src == dst)
    428 		{
    429 			return true;
    430 		}
    431 
    432 		return true;
    433 	}
    434 
    435 	return true;
    436 }
    437 
    438 /** Compare two pixels
    439  *
    440  * @param left_internal_format  Internal format of left image
    441  * @param left_red              Red channel of left image
    442  * @param left_green            Green channel of left image
    443  * @param left_blue             Blue channel of left image
    444  * @param left_alpha            Alpha channel of left image
    445  * @param right_internal_format Internal format of right image
    446  * @param right_red             Red channel of right image
    447  * @param right_green           Green channel of right image
    448  * @param right_blue            Blue channel of right image
    449  * @param right_alpha           Alpha channel of right image
    450  *
    451  * @return true if pixels match, false otherwise
    452  **/
    453 bool Utils::comparePixels(GLenum left_internal_format, const GLdouble& left_red, const GLdouble& left_green,
    454 						  const GLdouble& left_blue, const GLdouble& left_alpha, GLenum right_internal_format,
    455 						  const GLdouble& right_red, const GLdouble& right_green, const GLdouble& right_blue,
    456 						  const GLdouble& right_alpha)
    457 {
    458 	const GLuint left_n_channels  = getNumberOfChannels(left_internal_format);
    459 	const GLuint right_n_channels = getNumberOfChannels(right_internal_format);
    460 	const GLuint n_channels		  = (left_n_channels >= right_n_channels) ? right_n_channels : left_n_channels;
    461 
    462 	const GLdouble left_channels[4] = { left_red, left_green, left_blue, left_alpha };
    463 
    464 	const GLdouble right_channels[4] = { right_red, right_green, right_blue, right_alpha };
    465 
    466 	for (GLuint i = 0; i < n_channels; ++i)
    467 	{
    468 		const GLdouble left		 = left_channels[i];
    469 		const GLdouble right	 = right_channels[i];
    470 		const GLdouble left_eps  = getEpsilon(left_internal_format);
    471 		const GLdouble right_eps = getEpsilon(right_internal_format);
    472 		const GLdouble eps		 = fabs(std::max(left_eps, right_eps));
    473 
    474 		if (eps < fabs(left - right))
    475 		{
    476 			return false;
    477 		}
    478 	}
    479 
    480 	return true;
    481 }
    482 
    483 /** Compare two pixels with memcmp
    484  *
    485  * @param left_pixel_size  Size of left pixel
    486  * @param left_pixel_data  Data of left pixel
    487  * @param right_pixel_size Size of right pixel
    488  * @param right_pixel_data Data of right pixel
    489  *
    490  * @return true if memory match, false otherwise
    491  **/
    492 bool Utils::comparePixels(GLuint left_pixel_size, const GLubyte* left_pixel_data, GLuint right_pixel_size,
    493 						  const GLubyte* right_pixel_data)
    494 {
    495 	const GLuint pixel_size = (left_pixel_size >= right_pixel_size) ? left_pixel_size : right_pixel_size;
    496 
    497 	return 0 == memcmp(left_pixel_data, right_pixel_data, pixel_size);
    498 }
    499 
    500 /** Delete texture or renderbuffer
    501  *
    502  * @param context Test context
    503  * @param target  Image target
    504  * @param name    Name of image
    505  **/
    506 void Utils::deleteTexture(deqp::Context& context, GLenum target, GLuint name)
    507 {
    508 	const Functions& gl = context.getRenderContext().getFunctions();
    509 
    510 	if (GL_RENDERBUFFER == target)
    511 	{
    512 		gl.deleteRenderbuffers(1, &name);
    513 	}
    514 	else
    515 	{
    516 		gl.deleteTextures(1, &name);
    517 	}
    518 }
    519 
    520 /** Get epsilon for given internal_format
    521  *
    522  * @param internal_format Internal format of image
    523  *
    524  * @return Epsilon value
    525  **/
    526 GLdouble Utils::getEpsilon(GLenum internal_format)
    527 {
    528 	GLdouble epsilon;
    529 
    530 	switch (internal_format)
    531 	{
    532 	case GL_R8:
    533 	case GL_R8_SNORM:
    534 	case GL_R16:
    535 	case GL_R16F:
    536 	case GL_R16_SNORM:
    537 	case GL_R32F:
    538 	case GL_R8I:
    539 	case GL_R8UI:
    540 	case GL_R16I:
    541 	case GL_R16UI:
    542 	case GL_R32I:
    543 	case GL_R32UI:
    544 	case GL_RG8:
    545 	case GL_RG8_SNORM:
    546 	case GL_RG16:
    547 	case GL_RG16F:
    548 	case GL_RG16_SNORM:
    549 	case GL_RG32F:
    550 	case GL_RG8I:
    551 	case GL_RG8UI:
    552 	case GL_RG16I:
    553 	case GL_RG16UI:
    554 	case GL_RG32I:
    555 	case GL_RG32UI:
    556 	case GL_R3_G3_B2:
    557 	case GL_RGB4:
    558 	case GL_RGB5:
    559 	case GL_RGB8:
    560 	case GL_RGB8_SNORM:
    561 	case GL_R11F_G11F_B10F:
    562 	case GL_RGB16:
    563 	case GL_RGB16F:
    564 	case GL_RGB16_SNORM:
    565 	case GL_RGB32F:
    566 	case GL_RGB8I:
    567 	case GL_RGB8UI:
    568 	case GL_RGB10:
    569 	case GL_RGB16I:
    570 	case GL_RGB16UI:
    571 	case GL_RGB32I:
    572 	case GL_RGB32UI:
    573 	case GL_RGB9_E5:
    574 	case GL_RGBA2:
    575 	case GL_RGBA4:
    576 	case GL_RGB5_A1:
    577 	case GL_RGBA8:
    578 	case GL_RGBA8_SNORM:
    579 	case GL_RGB10_A2:
    580 	case GL_RGBA16:
    581 	case GL_RGBA16F:
    582 	case GL_RGBA16_SNORM:
    583 	case GL_RGBA32F:
    584 	case GL_RGBA8I:
    585 	case GL_RGBA8UI:
    586 	case GL_RGB10_A2UI:
    587 	case GL_RGBA16I:
    588 	case GL_RGBA16UI:
    589 	case GL_RGBA32I:
    590 	case GL_RGBA32UI:
    591 		epsilon = 0.0;
    592 		break;
    593 	case GL_RGB12:
    594 	case GL_RGBA12:
    595 		epsilon = 0.00390625;
    596 		break;
    597 	default:
    598 		TCU_FAIL("Invalid enum");
    599 		break;
    600 	}
    601 
    602 	return epsilon;
    603 }
    604 
    605 /** Get format for given internal format
    606  *
    607  * @param internal_format Internal format
    608  *
    609  * @return Format
    610  **/
    611 GLenum Utils::getFormat(GLenum internal_format)
    612 {
    613 	GLenum format = 0;
    614 
    615 	switch (internal_format)
    616 	{
    617 	/* R */
    618 	case GL_R8:
    619 	case GL_R8_SNORM:
    620 	case GL_R16:
    621 	case GL_R16F:
    622 	case GL_R16_SNORM:
    623 	case GL_R32F:
    624 		format = GL_RED;
    625 		break;
    626 
    627 	case GL_R8I:
    628 	case GL_R8UI:
    629 	case GL_R16I:
    630 	case GL_R16UI:
    631 	case GL_R32I:
    632 	case GL_R32UI:
    633 		format = GL_RED_INTEGER;
    634 		break;
    635 
    636 	/* RG */
    637 	case GL_RG8:
    638 	case GL_RG8_SNORM:
    639 	case GL_RG16:
    640 	case GL_RG16F:
    641 	case GL_RG16_SNORM:
    642 	case GL_RG32F:
    643 		format = GL_RG;
    644 		break;
    645 
    646 	case GL_RG8I:
    647 	case GL_RG8UI:
    648 	case GL_RG16I:
    649 	case GL_RG16UI:
    650 	case GL_RG32I:
    651 	case GL_RG32UI:
    652 		format = GL_RG_INTEGER;
    653 		break;
    654 
    655 	/* RGB */
    656 	case GL_R3_G3_B2:
    657 	case GL_RGB4:
    658 	case GL_RGB5:
    659 	case GL_RGB8:
    660 	case GL_RGB8_SNORM:
    661 	case GL_R11F_G11F_B10F:
    662 	case GL_RGB12:
    663 	case GL_RGB16:
    664 	case GL_RGB16F:
    665 	case GL_RGB16_SNORM:
    666 	case GL_RGB32F:
    667 	case GL_RGB9_E5:
    668 		format = GL_RGB;
    669 		break;
    670 
    671 	case GL_RGB8I:
    672 	case GL_RGB8UI:
    673 	case GL_RGB16I:
    674 	case GL_RGB16UI:
    675 	case GL_RGB32I:
    676 	case GL_RGB32UI:
    677 		format = GL_RGB_INTEGER;
    678 		break;
    679 
    680 	/* RGBA */
    681 	case GL_RGB10:
    682 	case GL_RGBA2:
    683 	case GL_RGBA4:
    684 	case GL_RGB5_A1:
    685 	case GL_RGBA8:
    686 	case GL_RGBA8_SNORM:
    687 	case GL_RGB10_A2:
    688 	case GL_RGBA12:
    689 	case GL_RGBA16:
    690 	case GL_RGBA16F:
    691 	case GL_RGBA16_SNORM:
    692 	case GL_RGBA32F:
    693 		format = GL_RGBA;
    694 		break;
    695 
    696 	case GL_RGBA8I:
    697 	case GL_RGBA8UI:
    698 	case GL_RGB10_A2UI:
    699 	case GL_RGBA16I:
    700 	case GL_RGBA16UI:
    701 	case GL_RGBA32I:
    702 	case GL_RGBA32UI:
    703 		format = GL_RGBA_INTEGER;
    704 		break;
    705 
    706 	default:
    707 		TCU_FAIL("Invalid enum");
    708 		break;
    709 	}
    710 
    711 	return format;
    712 }
    713 
    714 /** Get number of channels for given internal_format
    715  *
    716  * @param internal_format Internal format
    717  *
    718  * @return Number of channels
    719  **/
    720 GLuint Utils::getNumberOfChannels(GLenum internal_format)
    721 {
    722 	GLuint result = 0;
    723 
    724 	switch (internal_format)
    725 	{
    726 	case GL_R8:
    727 	case GL_R8_SNORM:
    728 	case GL_R16:
    729 	case GL_R16F:
    730 	case GL_R16_SNORM:
    731 	case GL_R32F:
    732 	case GL_R8I:
    733 	case GL_R8UI:
    734 	case GL_R16I:
    735 	case GL_R16UI:
    736 	case GL_R32I:
    737 	case GL_R32UI:
    738 		result = 1;
    739 		break;
    740 
    741 	case GL_RG8:
    742 	case GL_RG8_SNORM:
    743 	case GL_RG16:
    744 	case GL_RG16F:
    745 	case GL_RG16_SNORM:
    746 	case GL_RG32F:
    747 	case GL_RG8I:
    748 	case GL_RG8UI:
    749 	case GL_RG16I:
    750 	case GL_RG16UI:
    751 	case GL_RG32I:
    752 	case GL_RG32UI:
    753 		result = 2;
    754 		break;
    755 
    756 	case GL_R3_G3_B2:
    757 	case GL_RGB4:
    758 	case GL_RGB5:
    759 	case GL_RGB8:
    760 	case GL_RGB8_SNORM:
    761 	case GL_RGB10:
    762 	case GL_R11F_G11F_B10F:
    763 	case GL_RGB12:
    764 	case GL_RGB16:
    765 	case GL_RGB16F:
    766 	case GL_RGB16_SNORM:
    767 	case GL_RGB32F:
    768 	case GL_RGB9_E5:
    769 	case GL_RGB8I:
    770 	case GL_RGB8UI:
    771 	case GL_RGB16I:
    772 	case GL_RGB16UI:
    773 	case GL_RGB32I:
    774 	case GL_RGB32UI:
    775 		result = 3;
    776 		break;
    777 
    778 	case GL_RGBA2:
    779 	case GL_RGBA4:
    780 	case GL_RGB5_A1:
    781 	case GL_RGBA8:
    782 	case GL_RGBA8_SNORM:
    783 	case GL_RGB10_A2:
    784 	case GL_RGBA12:
    785 	case GL_RGBA16:
    786 	case GL_RGBA16F:
    787 	case GL_RGBA16_SNORM:
    788 	case GL_RGBA32F:
    789 	case GL_RGBA8I:
    790 	case GL_RGBA8UI:
    791 	case GL_RGB10_A2UI:
    792 	case GL_RGBA16I:
    793 	case GL_RGBA16UI:
    794 	case GL_RGBA32I:
    795 	case GL_RGBA32UI:
    796 		result = 4;
    797 		break;
    798 
    799 	default:
    800 		TCU_FAIL("Invalid enum");
    801 		break;
    802 	}
    803 
    804 	return result;
    805 }
    806 
    807 /** Get type for given internal format
    808  *
    809  * @param internal_format Internal format
    810  *
    811  * @return Type
    812  **/
    813 GLenum Utils::getType(GLenum internal_format)
    814 {
    815 	GLenum type = 0;
    816 
    817 	switch (internal_format)
    818 	{
    819 	case GL_R8:
    820 	case GL_R8UI:
    821 	case GL_RG8:
    822 	case GL_RG8UI:
    823 	case GL_RGB8:
    824 	case GL_RGB8UI:
    825 	case GL_RGBA8:
    826 	case GL_RGBA8UI:
    827 		type = GL_UNSIGNED_BYTE;
    828 		break;
    829 
    830 	case GL_R8_SNORM:
    831 	case GL_R8I:
    832 	case GL_RG8_SNORM:
    833 	case GL_RG8I:
    834 	case GL_RGB8_SNORM:
    835 	case GL_RGB8I:
    836 	case GL_RGBA8_SNORM:
    837 	case GL_RGBA8I:
    838 		type = GL_BYTE;
    839 		break;
    840 
    841 	case GL_R3_G3_B2:
    842 		type = GL_UNSIGNED_BYTE_3_3_2;
    843 		break;
    844 
    845 	case GL_RGB4:
    846 	case GL_RGB5:
    847 		type = GL_UNSIGNED_SHORT_5_6_5;
    848 		break;
    849 
    850 	case GL_RGBA2:
    851 	case GL_RGBA4:
    852 		type = GL_UNSIGNED_SHORT_4_4_4_4;
    853 		break;
    854 
    855 	case GL_RGB5_A1:
    856 		type = GL_UNSIGNED_SHORT_5_5_5_1;
    857 		break;
    858 
    859 	case GL_RGB10:
    860 	case GL_RGB10_A2:
    861 	case GL_RGB10_A2UI:
    862 		type = GL_UNSIGNED_INT_2_10_10_10_REV;
    863 		break;
    864 
    865 	case GL_R16F:
    866 	case GL_RG16F:
    867 	case GL_RGB16F:
    868 	case GL_RGBA16F:
    869 		type = GL_HALF_FLOAT;
    870 		break;
    871 
    872 	case GL_R16:
    873 	case GL_R16UI:
    874 	case GL_RG16:
    875 	case GL_RG16UI:
    876 	case GL_RGB12:
    877 	case GL_RGB16:
    878 	case GL_RGB16UI:
    879 	case GL_RGBA12:
    880 	case GL_RGBA16:
    881 	case GL_RGBA16UI:
    882 		type = GL_UNSIGNED_SHORT;
    883 		break;
    884 
    885 	case GL_R16_SNORM:
    886 	case GL_R16I:
    887 	case GL_RG16_SNORM:
    888 	case GL_RG16I:
    889 	case GL_RGB16_SNORM:
    890 	case GL_RGB16I:
    891 	case GL_RGBA16_SNORM:
    892 	case GL_RGBA16I:
    893 		type = GL_SHORT;
    894 		break;
    895 
    896 	case GL_R32UI:
    897 	case GL_RG32UI:
    898 	case GL_RGB32UI:
    899 	case GL_RGBA32UI:
    900 		type = GL_UNSIGNED_INT;
    901 		break;
    902 
    903 	case GL_RGB9_E5:
    904 		type = GL_UNSIGNED_INT_5_9_9_9_REV;
    905 		break;
    906 
    907 	case GL_R32I:
    908 	case GL_RG32I:
    909 	case GL_RGB32I:
    910 	case GL_RGBA32I:
    911 		type = GL_INT;
    912 		break;
    913 
    914 	case GL_R32F:
    915 	case GL_RG32F:
    916 	case GL_RGB32F:
    917 	case GL_RGBA32F:
    918 		type = GL_FLOAT;
    919 		break;
    920 
    921 	case GL_R11F_G11F_B10F:
    922 		type = GL_UNSIGNED_INT_10F_11F_11F_REV;
    923 		break;
    924 
    925 	default:
    926 		TCU_FAIL("Invalid enum");
    927 		break;
    928 	}
    929 
    930 	return type;
    931 }
    932 
    933 /** Returns mask that should be applied to pixel value
    934  *
    935  * @param internal_format Internal format of texture
    936  * @param pixel           Pixel data
    937  *
    938  * @return Mask
    939  **/
    940 void Utils::maskPixelForFormat(GLenum internal_format, GLubyte* pixel)
    941 {
    942 	switch (internal_format)
    943 	{
    944 	case GL_RGB10:
    945 		/* UINT_10_10_10_2 - ALPHA will be set to 3*/
    946 		pixel[0] |= 0x03;
    947 		break;
    948 
    949 	default:
    950 		break;
    951 	}
    952 }
    953 
    954 /** Get size of pixel for given internal format
    955  *
    956  * @param internal_format Internal format
    957  *
    958  * @return Number of bytes used by given format
    959  **/
    960 GLuint Utils::getPixelSizeForFormat(GLenum internal_format)
    961 {
    962 	GLuint size = 0;
    963 
    964 	switch (internal_format)
    965 	{
    966 	/* 8 */
    967 	case GL_R8:
    968 	case GL_R8I:
    969 	case GL_R8UI:
    970 	case GL_R8_SNORM:
    971 	case GL_R3_G3_B2:
    972 		size = 1;
    973 		break;
    974 
    975 	/* 8 */
    976 	case GL_RGBA2:
    977 		size = 2;
    978 		break;
    979 
    980 	/* 12 */
    981 	case GL_RGB4:
    982 		size = 2;
    983 		break;
    984 
    985 	/* 15 */
    986 	case GL_RGB5:
    987 		size = 2;
    988 		break;
    989 
    990 	/* 16 */
    991 	case GL_RG8:
    992 	case GL_RG8I:
    993 	case GL_RG8UI:
    994 	case GL_RG8_SNORM:
    995 	case GL_R16:
    996 	case GL_R16F:
    997 	case GL_R16I:
    998 	case GL_R16UI:
    999 	case GL_R16_SNORM:
   1000 	case GL_RGBA4:
   1001 	case GL_RGB5_A1:
   1002 		size = 2;
   1003 		break;
   1004 
   1005 	/* 24 */
   1006 	case GL_RGB8:
   1007 	case GL_RGB8I:
   1008 	case GL_RGB8UI:
   1009 	case GL_RGB8_SNORM:
   1010 		size = 3;
   1011 		break;
   1012 
   1013 	/* 30 */
   1014 	case GL_RGB10:
   1015 		size = 4;
   1016 		break;
   1017 
   1018 	/* 32 */
   1019 	case GL_RGBA8:
   1020 	case GL_RGBA8I:
   1021 	case GL_RGBA8UI:
   1022 	case GL_RGBA8_SNORM:
   1023 	case GL_RG16:
   1024 	case GL_RG16F:
   1025 	case GL_RG16I:
   1026 	case GL_RG16UI:
   1027 	case GL_RG16_SNORM:
   1028 	case GL_R32F:
   1029 	case GL_R32I:
   1030 	case GL_R32UI:
   1031 	case GL_RGB10_A2:
   1032 	case GL_RGB10_A2UI:
   1033 	case GL_R11F_G11F_B10F:
   1034 	case GL_RGB9_E5:
   1035 		size = 4;
   1036 		break;
   1037 
   1038 	/* 36 */
   1039 	case GL_RGB12:
   1040 		size = 6;
   1041 		break;
   1042 
   1043 	/* 48 */
   1044 	case GL_RGB16:
   1045 	case GL_RGB16F:
   1046 	case GL_RGB16I:
   1047 	case GL_RGB16UI:
   1048 	case GL_RGB16_SNORM:
   1049 		size = 6;
   1050 		break;
   1051 
   1052 	/* 64 */
   1053 	case GL_RGBA12:
   1054 	case GL_RGBA16:
   1055 	case GL_RGBA16F:
   1056 	case GL_RGBA16I:
   1057 	case GL_RGBA16UI:
   1058 	case GL_RGBA16_SNORM:
   1059 	case GL_RG32F:
   1060 	case GL_RG32I:
   1061 	case GL_RG32UI:
   1062 		size = 8;
   1063 		break;
   1064 
   1065 	/* 96 */
   1066 	case GL_RGB32F:
   1067 	case GL_RGB32I:
   1068 	case GL_RGB32UI:
   1069 		size = 12;
   1070 		break;
   1071 
   1072 	/* 128 */
   1073 	case GL_RGBA32F:
   1074 	case GL_RGBA32I:
   1075 	case GL_RGBA32UI:
   1076 		size = 16;
   1077 		break;
   1078 
   1079 	default:
   1080 		TCU_FAIL("Invalid enum");
   1081 		break;
   1082 	}
   1083 
   1084 	return size;
   1085 }
   1086 
   1087 /** Prepare string that represents bytes of pixel
   1088  *
   1089  * @param internal_format Format
   1090  * @param pixel           Pixel data
   1091  *
   1092  * @return String
   1093  **/
   1094 std::string Utils::getPixelString(GLenum internal_format, const GLubyte* pixel)
   1095 {
   1096 	const GLuint	  pixel_size = Utils::getPixelSizeForFormat(internal_format);
   1097 	std::stringstream stream;
   1098 
   1099 	stream << "0x";
   1100 
   1101 	for (GLint i = pixel_size - 1; i >= 0; --i)
   1102 	{
   1103 		stream << std::setbase(16) << std::setw(2) << std::setfill('0') << (GLuint)pixel[i];
   1104 	}
   1105 
   1106 	return stream.str();
   1107 }
   1108 
   1109 /** Check if target supports multiple layers
   1110  *
   1111  * @param target Texture target
   1112  *
   1113  * @return true if target is multilayered
   1114  **/
   1115 bool Utils::isTargetMultilayer(GLenum target)
   1116 {
   1117 	bool result = false;
   1118 
   1119 	switch (target)
   1120 	{
   1121 	case GL_TEXTURE_1D_ARRAY:
   1122 	case GL_TEXTURE_2D_ARRAY:
   1123 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1124 	case GL_TEXTURE_3D:
   1125 	case GL_TEXTURE_CUBE_MAP_ARRAY:
   1126 		result = true;
   1127 		break;
   1128 
   1129 	default:
   1130 		break;
   1131 	}
   1132 
   1133 	return result;
   1134 }
   1135 
   1136 /** Check if target supports multiple level
   1137  *
   1138  * @param target Texture target
   1139  *
   1140  * @return true if target supports mipmaps
   1141  **/
   1142 bool Utils::isTargetMultilevel(GLenum target)
   1143 {
   1144 	bool result = true;
   1145 
   1146 	switch (target)
   1147 	{
   1148 	case GL_TEXTURE_2D_MULTISAMPLE:
   1149 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1150 	case GL_TEXTURE_RECTANGLE:
   1151 	case GL_RENDERBUFFER:
   1152 		result = false;
   1153 		break;
   1154 	default:
   1155 		break;
   1156 	}
   1157 
   1158 	return result;
   1159 }
   1160 
   1161 /** Check if target is multisampled
   1162  *
   1163  * @param target Texture target
   1164  *
   1165  * @return true when for multisampled formats, false otherwise
   1166  **/
   1167 bool Utils::isTargetMultisampled(GLenum target)
   1168 {
   1169 	bool result = false;
   1170 
   1171 	switch (target)
   1172 	{
   1173 	case GL_TEXTURE_2D_MULTISAMPLE:
   1174 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1175 		result = true;
   1176 		break;
   1177 	default:
   1178 		break;
   1179 	}
   1180 
   1181 	return result;
   1182 }
   1183 
   1184 /** Generate texture object
   1185  *
   1186  * @param context Test context
   1187  * @param target  Target of texture
   1188  *
   1189  * @return Generated name
   1190  **/
   1191 glw::GLuint Utils::generateTexture(deqp::Context& context, GLenum target)
   1192 {
   1193 	const Functions& gl   = context.getRenderContext().getFunctions();
   1194 	GLuint			 name = 0;
   1195 
   1196 	switch (target)
   1197 	{
   1198 	case GL_RENDERBUFFER:
   1199 		gl.genRenderbuffers(1, &name);
   1200 		GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderbuffers");
   1201 		break;
   1202 
   1203 	default:
   1204 		gl.genTextures(1, &name);
   1205 		GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
   1206 		break;
   1207 	}
   1208 
   1209 	return name;
   1210 }
   1211 
   1212 /** Sets base and max level parameters of texture to make it complete
   1213  *
   1214  * @param context    Test context
   1215  * @param target     GLenum representing target of texture that should be created
   1216  * @param id         Id of texture
   1217  * @param base_level Base level value, eg 0
   1218  * @param max_level  Max level value, eg 0
   1219  **/
   1220 void Utils::makeTextureComplete(deqp::Context& context, GLenum target, GLuint id, GLint base_level, GLint max_level)
   1221 {
   1222 	const Functions& gl = context.getRenderContext().getFunctions();
   1223 
   1224 	if (GL_RENDERBUFFER == target)
   1225 	{
   1226 		return;
   1227 	}
   1228 
   1229 	/* Translate proxies into real targets */
   1230 	target = transRealToBindTarget(transProxyToRealTarget(target));
   1231 
   1232 	gl.bindTexture(target, id);
   1233 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1234 
   1235 	/* Set levels */
   1236 	if (GL_TEXTURE_BUFFER != target)
   1237 	{
   1238 		gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, base_level);
   1239 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
   1240 
   1241 		gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, max_level);
   1242 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
   1243 
   1244 		/* Integer textures won't be complete with the default min filter
   1245 		 * of GL_NEAREST_MIPMAP_LINEAR (or GL_LINEAR for rectangle textures)
   1246 		 * and default mag filter of GL_LINEAR, so switch to nearest.
   1247 		 */
   1248 		if (GL_TEXTURE_2D_MULTISAMPLE != target && GL_TEXTURE_2D_MULTISAMPLE_ARRAY != target)
   1249 		{
   1250 			gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1251 			if (GL_TEXTURE_RECTANGLE != target)
   1252 			{
   1253 				gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   1254 				GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
   1255 			}
   1256 			else
   1257 			{
   1258 				gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1259 				GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
   1260 			}
   1261 		}
   1262 	}
   1263 
   1264 	/* Clean binding point */
   1265 	gl.bindTexture(target, 0);
   1266 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1267 }
   1268 
   1269 /** Generate and initialize texture for given target
   1270  *
   1271  * @param context   Test context
   1272  * @param target    GLenum representing target of texture that should be created
   1273  * @param n_samples Number of samples
   1274  *
   1275  * @return "name" of texture
   1276  **/
   1277 GLuint Utils::prepareMultisampleTex(deqp::Context& context, GLenum target, GLsizei n_samples)
   1278 {
   1279 	static const GLuint depth			= 6;
   1280 	const Functions&	gl				= context.getRenderContext().getFunctions();
   1281 	static const GLuint height			= 16;
   1282 	static const GLenum internal_format = GL_RGBA8;
   1283 	GLuint				name			= 0;
   1284 	static const GLuint width			= 16;
   1285 
   1286 	gl.genTextures(1, &name);
   1287 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
   1288 
   1289 	/* Initialize */
   1290 	switch (target)
   1291 	{
   1292 	case GL_TEXTURE_2D_MULTISAMPLE:
   1293 		gl.bindTexture(target, name);
   1294 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1295 
   1296 		gl.texImage2DMultisample(target, n_samples, internal_format, width, height, GL_FALSE /* fixedsamplelocation */);
   1297 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2DMultisample");
   1298 
   1299 		break;
   1300 
   1301 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1302 		gl.bindTexture(target, name);
   1303 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1304 
   1305 		gl.texImage3DMultisample(target, n_samples, internal_format, width, height, depth,
   1306 								 GL_FALSE /* fixedsamplelocation */);
   1307 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage3DMultisample");
   1308 
   1309 		break;
   1310 
   1311 	default:
   1312 		TCU_FAIL("Invalid enum");
   1313 		break;
   1314 	}
   1315 
   1316 	/* Clean binding point */
   1317 	gl.bindTexture(target, 0);
   1318 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1319 
   1320 	return name;
   1321 }
   1322 
   1323 /** Generate and initialize texture for given target
   1324  *
   1325  * @param context         Test context
   1326  * @param internal_format Internal format of render buffer
   1327  *
   1328  * @return "name" of texture
   1329  **/
   1330 GLuint Utils::prepareRenderBuffer(deqp::Context& context, GLenum internal_format)
   1331 {
   1332 	const Functions&	gl	 = context.getRenderContext().getFunctions();
   1333 	static const GLuint height = 16;
   1334 	GLuint				name   = 0;
   1335 	static const GLuint width  = 16;
   1336 
   1337 	gl.genRenderbuffers(1, &name);
   1338 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderbuffers");
   1339 
   1340 	/* Initialize */
   1341 	gl.bindRenderbuffer(GL_RENDERBUFFER, name);
   1342 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderbuffer");
   1343 
   1344 	gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, width, height);
   1345 	GLU_EXPECT_NO_ERROR(gl.getError(), "RenderbufferStorage");
   1346 
   1347 	/* Clean binding point */
   1348 	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
   1349 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderbuffer");
   1350 
   1351 	return name;
   1352 }
   1353 
   1354 /** Generate and initialize texture for given target
   1355  *
   1356  * @param context         Test context
   1357  * @param target          GLenum representing target of texture that should be created
   1358  * @param internal_format <internalformat>
   1359  * @param format          <format>
   1360  * @param type            <type>
   1361  * @param out_buf_id      ID of buffer that will be used for TEXTURE_BUFFER
   1362  *
   1363  * @return "name" of texture
   1364  **/
   1365 GLuint Utils::prepareTex16x16x6(deqp::Context& context, GLenum target, GLenum internal_format, GLenum format,
   1366 								GLenum type, GLuint& out_buf_id)
   1367 {
   1368 	static const GLuint  depth  = 6;
   1369 	static const GLuint  height = 16;
   1370 	static const GLuint  level  = 0;
   1371 	GLuint				 name   = 0;
   1372 	static const GLchar* pixels = 0;
   1373 	static const GLuint  width  = 16;
   1374 
   1375 	name = generateTexture(context, target);
   1376 
   1377 	prepareTexture(context, name, target, internal_format, format, type, level, width, height, depth, pixels,
   1378 				   out_buf_id);
   1379 
   1380 	return name;
   1381 }
   1382 
   1383 /** Initialize texture
   1384  *
   1385  * @param context         Test context
   1386  * @param name            Name of texture object
   1387  * @param target          GLenum representing target of texture that should be created
   1388  * @param internal_format <internalformat>
   1389  * @param format          <format>
   1390  * @param type            <type>
   1391  * @param level           <level>
   1392  * @param width           <width>
   1393  * @param height          <height>
   1394  * @param depth           <depth>
   1395  * @param pixels          <pixels>
   1396  * @param out_buf_id      ID of buffer that will be used for TEXTURE_BUFFER
   1397  *
   1398  * @return "name" of texture
   1399  **/
   1400 void Utils::prepareTexture(deqp::Context& context, GLuint name, GLenum target, GLenum internal_format, GLenum format,
   1401 						   GLenum type, GLuint level, GLuint width, GLuint height, GLuint depth, const GLvoid* pixels,
   1402 						   GLuint& out_buf_id)
   1403 {
   1404 	static const GLint   border		   = 0;
   1405 	GLenum				 error		   = 0;
   1406 	const GLchar*		 function_name = "unknown";
   1407 	const Functions&	 gl			   = context.getRenderContext().getFunctions();
   1408 	static const GLsizei samples	   = 1;
   1409 
   1410 	/* Translate proxies into real targets */
   1411 	target = transProxyToRealTarget(target);
   1412 
   1413 	/* Initialize */
   1414 	switch (target)
   1415 	{
   1416 	case GL_RENDERBUFFER:
   1417 		gl.bindRenderbuffer(target, name);
   1418 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderbuffer");
   1419 
   1420 		gl.renderbufferStorage(target, internal_format, width, height);
   1421 		GLU_EXPECT_NO_ERROR(gl.getError(), "RenderbufferStorage");
   1422 
   1423 		gl.bindRenderbuffer(target, 0);
   1424 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderbuffer");
   1425 
   1426 		break;
   1427 
   1428 	case GL_TEXTURE_1D:
   1429 		gl.bindTexture(target, name);
   1430 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1431 
   1432 		gl.texImage1D(target, level, internal_format, width, border, format, type, pixels);
   1433 		error		  = gl.getError();
   1434 		function_name = "TexImage1D";
   1435 
   1436 		break;
   1437 
   1438 	case GL_TEXTURE_1D_ARRAY:
   1439 	case GL_TEXTURE_2D:
   1440 	case GL_TEXTURE_RECTANGLE:
   1441 		gl.bindTexture(target, name);
   1442 
   1443 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1444 
   1445 		gl.texImage2D(target, level, internal_format, width, height, border, format, type, pixels);
   1446 		error		  = gl.getError();
   1447 		function_name = "TexImage2D";
   1448 
   1449 		break;
   1450 
   1451 	case GL_TEXTURE_2D_MULTISAMPLE:
   1452 		gl.bindTexture(target, name);
   1453 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1454 
   1455 		gl.texImage2DMultisample(target, samples, internal_format, width, height, GL_FALSE /* fixedsamplelocation */);
   1456 		error		  = gl.getError();
   1457 		function_name = "TexImage2DMultisample";
   1458 
   1459 		break;
   1460 
   1461 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1462 		gl.bindTexture(target, name);
   1463 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1464 
   1465 		gl.texImage3DMultisample(target, samples, internal_format, width, height, depth,
   1466 								 GL_FALSE /* fixedsamplelocation */);
   1467 		error		  = gl.getError();
   1468 		function_name = "TexImage3DMultisample";
   1469 
   1470 		break;
   1471 
   1472 	case GL_TEXTURE_2D_ARRAY:
   1473 	case GL_TEXTURE_3D:
   1474 	case GL_TEXTURE_CUBE_MAP_ARRAY:
   1475 		gl.bindTexture(target, name);
   1476 
   1477 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1478 
   1479 		gl.texImage3D(target, level, internal_format, width, height, depth, border, format, type, pixels);
   1480 		error		  = gl.getError();
   1481 		function_name = "TexImage3D";
   1482 
   1483 		break;
   1484 
   1485 	case GL_TEXTURE_BUFFER:
   1486 		gl.genBuffers(1, &out_buf_id);
   1487 		GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
   1488 
   1489 		gl.bindBuffer(GL_TEXTURE_BUFFER, out_buf_id);
   1490 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
   1491 
   1492 		{
   1493 			GLsizei		  size = 16;
   1494 			const GLvoid* data = 0;
   1495 
   1496 			if (0 != pixels)
   1497 			{
   1498 				size = width;
   1499 				data = pixels;
   1500 			}
   1501 
   1502 			gl.bufferData(GL_TEXTURE_BUFFER, size, data, GL_DYNAMIC_COPY);
   1503 			GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
   1504 		}
   1505 
   1506 		gl.bindTexture(GL_TEXTURE_BUFFER, name);
   1507 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1508 
   1509 		gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, out_buf_id);
   1510 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
   1511 
   1512 		break;
   1513 
   1514 	case GL_TEXTURE_CUBE_MAP:
   1515 	case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   1516 	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   1517 	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   1518 	case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   1519 	case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   1520 	case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   1521 		/* Change target to CUBE_MAP, it will be used later to change base and max level */
   1522 		target = GL_TEXTURE_CUBE_MAP;
   1523 		gl.bindTexture(target, name);
   1524 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1525 
   1526 		gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internal_format, width, height, border, format, type,
   1527 					  pixels);
   1528 		gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internal_format, width, height, border, format, type,
   1529 					  pixels);
   1530 		gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internal_format, width, height, border, format, type,
   1531 					  pixels);
   1532 		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internal_format, width, height, border, format, type,
   1533 					  pixels);
   1534 		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internal_format, width, height, border, format, type,
   1535 					  pixels);
   1536 		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internal_format, width, height, border, format, type,
   1537 					  pixels);
   1538 		error		  = gl.getError();
   1539 		function_name = "TexImage2D";
   1540 
   1541 		break;
   1542 
   1543 	default:
   1544 		TCU_FAIL("Invalid enum");
   1545 		break;
   1546 	}
   1547 
   1548 	if (GL_NO_ERROR != error)
   1549 	{
   1550 		context.getTestContext().getLog()
   1551 			<< tcu::TestLog::Message << "Error: " << glu::getErrorStr(error) << ". Function: " << function_name
   1552 			<< ". Target: " << glu::getTextureTargetStr(target)
   1553 			<< ". Format: " << glu::getInternalFormatParameterStr(internal_format) << ", "
   1554 			<< glu::getTextureFormatName(format) << ", " << glu::getTypeStr(type) << tcu::TestLog::EndMessage;
   1555 		TCU_FAIL("Failed to create texture");
   1556 	}
   1557 
   1558 	if (GL_RENDERBUFFER != target)
   1559 	{
   1560 		/* Clean binding point */
   1561 		gl.bindTexture(target, 0);
   1562 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1563 	}
   1564 }
   1565 
   1566 /** Translate proxies into real targets
   1567  *
   1568  * @param target Target to be converted
   1569  *
   1570  * @return Converted target for proxies, <target> otherwise
   1571  **/
   1572 GLenum Utils::transProxyToRealTarget(GLenum target)
   1573 {
   1574 	switch (target)
   1575 	{
   1576 	case GL_PROXY_TEXTURE_1D:
   1577 		target = GL_TEXTURE_1D;
   1578 		break;
   1579 	case GL_PROXY_TEXTURE_1D_ARRAY:
   1580 		target = GL_TEXTURE_1D_ARRAY;
   1581 		break;
   1582 	case GL_PROXY_TEXTURE_2D:
   1583 		target = GL_TEXTURE_2D;
   1584 		break;
   1585 	case GL_PROXY_TEXTURE_2D_ARRAY:
   1586 		target = GL_TEXTURE_2D_ARRAY;
   1587 		break;
   1588 	case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
   1589 		target = GL_TEXTURE_2D_MULTISAMPLE;
   1590 		break;
   1591 	case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1592 		target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
   1593 		break;
   1594 	case GL_PROXY_TEXTURE_3D:
   1595 		target = GL_TEXTURE_3D;
   1596 		break;
   1597 	case GL_PROXY_TEXTURE_CUBE_MAP:
   1598 		target = GL_TEXTURE_CUBE_MAP;
   1599 		break;
   1600 	case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
   1601 		target = GL_TEXTURE_CUBE_MAP_ARRAY;
   1602 		break;
   1603 	case GL_PROXY_TEXTURE_RECTANGLE:
   1604 		target = GL_TEXTURE_RECTANGLE;
   1605 		break;
   1606 	default:
   1607 		break;
   1608 	}
   1609 
   1610 	return target;
   1611 }
   1612 
   1613 /** Translate real targets into binding targets
   1614  *
   1615  * @param target Target to be converted
   1616  *
   1617  * @return Converted target for cube map faces, <target> otherwise
   1618  **/
   1619 GLenum Utils::transRealToBindTarget(GLenum target)
   1620 {
   1621 	switch (target)
   1622 	{
   1623 	case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   1624 		target = GL_TEXTURE_CUBE_MAP;
   1625 		break;
   1626 	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   1627 		target = GL_TEXTURE_CUBE_MAP;
   1628 		break;
   1629 	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   1630 		target = GL_TEXTURE_CUBE_MAP;
   1631 		break;
   1632 	case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   1633 		target = GL_TEXTURE_CUBE_MAP;
   1634 		break;
   1635 	case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   1636 		target = GL_TEXTURE_CUBE_MAP;
   1637 		break;
   1638 	case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   1639 		target = GL_TEXTURE_CUBE_MAP;
   1640 		break;
   1641 	default:
   1642 		break;
   1643 	}
   1644 
   1645 	return target;
   1646 }
   1647 
   1648 /** Read value of channel
   1649  *
   1650  * @tparam T Type used to store channel value
   1651  *
   1652  * @param channel   Channel index
   1653  * @param pixel     Pixel data
   1654  * @param out_value Read value
   1655  **/
   1656 template <typename T>
   1657 void readBaseTypeFromUnsignedChannel(GLuint channel, const GLubyte* pixel, GLdouble& out_value)
   1658 {
   1659 	static const T max = -1;
   1660 
   1661 	const GLdouble d_max   = (GLdouble)max;
   1662 	const T*	   ptr	 = (T*)pixel;
   1663 	const T		   t_value = ptr[channel];
   1664 	const GLdouble d_value = (GLdouble)t_value;
   1665 
   1666 	out_value = d_value / d_max;
   1667 }
   1668 
   1669 /** Read value of channel
   1670  *
   1671  * @tparam T Type used to store channel value
   1672  *
   1673  * @param channel   Channel index
   1674  * @param pixel     Pixel data
   1675  * @param out_value Read value
   1676  **/
   1677 template <typename T>
   1678 void readBaseTypeFromSignedChannel(GLuint channel, const GLubyte* pixel, GLdouble& out_value)
   1679 {
   1680 	static const GLuint n_bytes = sizeof(T);
   1681 	static const GLuint n_bits  = 8u * n_bytes;
   1682 	static const T		max		= (T)((1u << (n_bits - 1u)) - 1u);
   1683 
   1684 	const GLdouble d_max   = (GLdouble)max;
   1685 	const T*	   ptr	 = (T*)pixel;
   1686 	const T		   t_value = ptr[channel];
   1687 	const GLdouble d_value = (GLdouble)t_value;
   1688 
   1689 	out_value = d_value / d_max;
   1690 }
   1691 
   1692 /** Read value of channel
   1693  *
   1694  * @tparam T Type used to store channel value
   1695  *
   1696  * @param channel   Channel index
   1697  * @param pixel     Pixel data
   1698  * @param out_value Read value
   1699  **/
   1700 void readBaseTypeFromFloatChannel(GLuint channel, const GLubyte* pixel, GLdouble& out_value)
   1701 {
   1702 	const GLfloat* ptr	 = (const GLfloat*)pixel;
   1703 	const GLfloat  t_value = ptr[channel];
   1704 	const GLdouble d_value = (GLdouble)t_value;
   1705 
   1706 	out_value = d_value;
   1707 }
   1708 
   1709 /** Read value of channel
   1710  *
   1711  * @tparam T Type used to store channel value
   1712  *
   1713  * @param channel   Channel index
   1714  * @param pixel     Pixel data
   1715  * @param out_value Read value
   1716  **/
   1717 void readBaseTypeFromHalfFloatChannel(GLuint channel, const GLubyte* pixel, GLdouble& out_value)
   1718 {
   1719 	const deUint16* ptr  = (const deUint16*)pixel;
   1720 	const deUint16  bits = ptr[channel];
   1721 	tcu::Float16	val(bits);
   1722 	const GLdouble  d_value = val.asDouble();
   1723 
   1724 	out_value = d_value;
   1725 }
   1726 
   1727 /** Read value of channel
   1728  *
   1729  * @tparam T      Type used to store pixel
   1730  * @tparam size_1 Size of channel in bits
   1731  * @tparam size_2 Size of channel in bits
   1732  * @tparam size_3 Size of channel in bits
   1733  * @tparam off_1  Offset of channel in bits
   1734  * @tparam off_2  Offset of channel in bits
   1735  * @tparam off_3  Offset of channel in bits
   1736  *
   1737  * @param channel   Channel index
   1738  * @param pixel     Pixel data
   1739  * @param out_value Read value
   1740  **/
   1741 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int off_1,
   1742 		  unsigned int off_2, unsigned int off_3>
   1743 void read3Channel(GLuint channel, const GLubyte* pixel, GLdouble& out_value)
   1744 {
   1745 	T		 mask	= 0;
   1746 	T		 max	 = 0;
   1747 	T		 off	 = 0;
   1748 	const T* ptr	 = (T*)pixel;
   1749 	T		 result  = 0;
   1750 	const T  t_value = ptr[0];
   1751 
   1752 	static const T max_1 = (1 << size_1) - 1;
   1753 	static const T max_2 = (1 << size_2) - 1;
   1754 	static const T max_3 = (1 << size_3) - 1;
   1755 
   1756 	switch (channel)
   1757 	{
   1758 	case 0:
   1759 		mask = max_1;
   1760 		max  = max_1;
   1761 		off  = off_1;
   1762 		break;
   1763 	case 1:
   1764 		mask = max_2;
   1765 		max  = max_2;
   1766 		off  = off_2;
   1767 		break;
   1768 	case 2:
   1769 		mask = max_3;
   1770 		max  = max_3;
   1771 		off  = off_3;
   1772 		break;
   1773 	default:
   1774 		TCU_FAIL("Invalid channel");
   1775 		break;
   1776 	}
   1777 
   1778 	result = (T)((t_value >> off) & mask);
   1779 
   1780 	const GLdouble d_max   = (GLdouble)max;
   1781 	const GLdouble d_value = (GLdouble)result;
   1782 
   1783 	out_value = d_value / d_max;
   1784 }
   1785 
   1786 /** Read value of channel
   1787  *
   1788  * @tparam T      Type used to store pixel
   1789  * @tparam size_1 Size of channel in bits
   1790  * @tparam size_2 Size of channel in bits
   1791  * @tparam size_3 Size of channel in bits
   1792  * @tparam size_4 Size of channel in bits
   1793  * @tparam off_1  Offset of channel in bits
   1794  * @tparam off_2  Offset of channel in bits
   1795  * @tparam off_3  Offset of channel in bits
   1796  * @tparam off_4  Offset of channel in bits
   1797  *
   1798  * @param channel   Channel index
   1799  * @param pixel     Pixel data
   1800  * @param out_value Read value
   1801  **/
   1802 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int size_4,
   1803 		  unsigned int off_1, unsigned int off_2, unsigned int off_3, unsigned int off_4>
   1804 void read4Channel(GLuint channel, const GLubyte* pixel, GLdouble& out_value)
   1805 {
   1806 	T		 mask	= 0;
   1807 	T		 max	 = 0;
   1808 	T		 off	 = 0;
   1809 	const T* ptr	 = (T*)pixel;
   1810 	T		 result  = 0;
   1811 	const T  t_value = ptr[0];
   1812 
   1813 	static const T max_1 = (1 << size_1) - 1;
   1814 	static const T max_2 = (1 << size_2) - 1;
   1815 	static const T max_3 = (1 << size_3) - 1;
   1816 	static const T max_4 = (1 << size_4) - 1;
   1817 
   1818 	switch (channel)
   1819 	{
   1820 	case 0:
   1821 		mask = max_1;
   1822 		max  = max_1;
   1823 		off  = off_1;
   1824 		break;
   1825 	case 1:
   1826 		mask = max_2;
   1827 		max  = max_2;
   1828 		off  = off_2;
   1829 		break;
   1830 	case 2:
   1831 		mask = max_3;
   1832 		max  = max_3;
   1833 		off  = off_3;
   1834 		break;
   1835 	case 3:
   1836 		mask = max_4;
   1837 		max  = max_4;
   1838 		off  = off_4;
   1839 		break;
   1840 	default:
   1841 		TCU_FAIL("Invalid channel");
   1842 		break;
   1843 	}
   1844 
   1845 	result = (T)((t_value >> off) & mask);
   1846 
   1847 	const GLdouble d_max   = (GLdouble)max;
   1848 	const GLdouble d_value = (GLdouble)result;
   1849 
   1850 	out_value = d_value / d_max;
   1851 }
   1852 
   1853 /** Read value of channel
   1854  *
   1855  * @param channel   Channel index
   1856  * @param pixel     Pixel data
   1857  * @param out_value Read value
   1858  **/
   1859 void read11F_11F_10F_Channel(GLuint channel, const GLubyte* pixel, GLdouble& out_value)
   1860 {
   1861 	const deUint32* ptr = (deUint32*)pixel;
   1862 	deUint32		val = *ptr;
   1863 
   1864 	switch (channel)
   1865 	{
   1866 	case 0:
   1867 	{
   1868 		deUint32 bits = (val & 0x000007ff);
   1869 		tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> temp_val(bits);
   1870 
   1871 		out_value = temp_val.asDouble();
   1872 	}
   1873 	break;
   1874 	case 1:
   1875 	{
   1876 		deUint32 bits = ((val >> 11) & 0x000007ff);
   1877 		tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> temp_val(bits);
   1878 
   1879 		out_value = temp_val.asDouble();
   1880 	}
   1881 	break;
   1882 	case 2:
   1883 	{
   1884 		deUint32 bits = ((val >> 22) & 0x000003ff);
   1885 		tcu::Float<deUint32, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> temp_val(bits);
   1886 
   1887 		out_value = temp_val.asDouble();
   1888 	}
   1889 	break;
   1890 	default:
   1891 		TCU_FAIL("Invalid channel");
   1892 		break;
   1893 	}
   1894 }
   1895 
   1896 /** Write value of channel
   1897  *
   1898  * @tparam T Type used to store pixel
   1899  *
   1900  * @param channel Channel index
   1901  * @param value   Value to write
   1902  * @param pixel   Pixel data
   1903  **/
   1904 template <typename T>
   1905 void writeBaseTypeToUnsignedChannel(GLuint channel, GLdouble value, GLubyte* pixel)
   1906 {
   1907 	static const T max = -1;
   1908 
   1909 	const GLdouble d_max   = (GLdouble)max;
   1910 	const GLdouble d_value = value * d_max;
   1911 	const T		   t_value = (T)d_value;
   1912 
   1913 	T* ptr = (T*)pixel;
   1914 
   1915 	ptr[channel] = t_value;
   1916 }
   1917 
   1918 /** Write value of channel
   1919  *
   1920  * @tparam T Type used to store pixel
   1921  *
   1922  * @param channel Channel index
   1923  * @param value   Value to write
   1924  * @param pixel   Pixel data
   1925  **/
   1926 template <typename T>
   1927 void writeBaseTypeToSignedChannel(GLuint channel, GLdouble value, GLubyte* pixel)
   1928 {
   1929 	static const GLuint n_bytes = sizeof(T);
   1930 	static const GLuint n_bits  = 8u * n_bytes;
   1931 	static const T		max		= (T)((1u << (n_bits - 1u)) - 1u);
   1932 
   1933 	const GLdouble d_max   = (GLdouble)max;
   1934 	const GLdouble d_value = value * d_max;
   1935 	const T		   t_value = (T)d_value;
   1936 
   1937 	T* ptr = (T*)pixel;
   1938 
   1939 	ptr[channel] = t_value;
   1940 }
   1941 
   1942 /** Write value of channel
   1943  *
   1944  * @param channel Channel index
   1945  * @param value   Value to write
   1946  * @param pixel   Pixel data
   1947  **/
   1948 void writeBaseTypeToFloatChannel(GLuint channel, GLdouble value, GLubyte* pixel)
   1949 {
   1950 	const GLfloat t_value = (GLfloat)value;
   1951 
   1952 	GLfloat* ptr = (GLfloat*)pixel;
   1953 
   1954 	ptr[channel] = t_value;
   1955 }
   1956 
   1957 /** Write value of channel
   1958  *
   1959  * @param channel Channel index
   1960  * @param value   Value to write
   1961  * @param pixel   Pixel data
   1962  **/
   1963 void writeBaseTypeToHalfFloatChannel(GLuint channel, GLdouble value, GLubyte* pixel)
   1964 {
   1965 	deUint16* ptr = (deUint16*)pixel;
   1966 
   1967 	tcu::Float16 val(value);
   1968 
   1969 	ptr[channel] = val.bits();
   1970 }
   1971 
   1972 /** Write value of channel
   1973  *
   1974  * @tparam T      Type used to store pixel
   1975  * @tparam size_1 Size of channel in bits
   1976  * @tparam size_2 Size of channel in bits
   1977  * @tparam size_3 Size of channel in bits
   1978  * @tparam off_1  Offset of channel in bits
   1979  * @tparam off_2  Offset of channel in bits
   1980  * @tparam off_3  Offset of channel in bits
   1981  *
   1982  * @param channel Channel index
   1983  * @param value   Value to write
   1984  * @param pixel   Pixel data
   1985  **/
   1986 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int off_1,
   1987 		  unsigned int off_2, unsigned int off_3>
   1988 void write3Channel(GLuint channel, GLdouble value, GLubyte* pixel)
   1989 {
   1990 	T  mask   = 0;
   1991 	T  max	= 0;
   1992 	T  off	= 0;
   1993 	T* ptr	= (T*)pixel;
   1994 	T  result = 0;
   1995 
   1996 	static const T max_1 = (1 << size_1) - 1;
   1997 	static const T max_2 = (1 << size_2) - 1;
   1998 	static const T max_3 = (1 << size_3) - 1;
   1999 
   2000 	switch (channel)
   2001 	{
   2002 	case 0:
   2003 		mask = max_1;
   2004 		max  = max_1;
   2005 		off  = off_1;
   2006 		break;
   2007 	case 1:
   2008 		mask = max_2;
   2009 		max  = max_2;
   2010 		off  = off_2;
   2011 		break;
   2012 	case 2:
   2013 		mask = max_3;
   2014 		max  = max_3;
   2015 		off  = off_3;
   2016 		break;
   2017 	default:
   2018 		TCU_FAIL("Invalid channel");
   2019 		break;
   2020 	}
   2021 
   2022 	const GLdouble d_max   = (GLdouble)max;
   2023 	const GLdouble d_value = value * d_max;
   2024 	const T		   t_value = (T)d_value;
   2025 
   2026 	result = (T)((t_value & mask) << off);
   2027 
   2028 	*ptr |= result;
   2029 }
   2030 
   2031 /** Write value of channel
   2032  *
   2033  * @tparam T      Type used to store pixel
   2034  * @tparam size_1 Size of channel in bits
   2035  * @tparam size_2 Size of channel in bits
   2036  * @tparam size_3 Size of channel in bits
   2037  * @tparam size_4 Size of channel in bits
   2038  * @tparam off_1  Offset of channel in bits
   2039  * @tparam off_2  Offset of channel in bits
   2040  * @tparam off_3  Offset of channel in bits
   2041  * @tparam off_4  Offset of channel in bits
   2042  *
   2043  * @param channel Channel index
   2044  * @param value   Value to write
   2045  * @param pixel   Pixel data
   2046  **/
   2047 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int size_4,
   2048 		  unsigned int off_1, unsigned int off_2, unsigned int off_3, unsigned int off_4>
   2049 void write4Channel(GLuint channel, GLdouble value, GLubyte* pixel)
   2050 {
   2051 	T  mask   = 0;
   2052 	T  max	= 0;
   2053 	T  off	= 0;
   2054 	T* ptr	= (T*)pixel;
   2055 	T  result = 0;
   2056 
   2057 	static const T max_1 = (1 << size_1) - 1;
   2058 	static const T max_2 = (1 << size_2) - 1;
   2059 	static const T max_3 = (1 << size_3) - 1;
   2060 	static const T max_4 = (1 << size_4) - 1;
   2061 
   2062 	switch (channel)
   2063 	{
   2064 	case 0:
   2065 		mask = max_1;
   2066 		max  = max_1;
   2067 		off  = off_1;
   2068 		break;
   2069 	case 1:
   2070 		mask = max_2;
   2071 		max  = max_2;
   2072 		off  = off_2;
   2073 		break;
   2074 	case 2:
   2075 		mask = max_3;
   2076 		max  = max_3;
   2077 		off  = off_3;
   2078 		break;
   2079 	case 3:
   2080 		mask = max_4;
   2081 		max  = max_4;
   2082 		off  = off_4;
   2083 		break;
   2084 	default:
   2085 		TCU_FAIL("Invalid channel");
   2086 		break;
   2087 	}
   2088 
   2089 	const GLdouble d_max   = (GLdouble)max;
   2090 	const GLdouble d_value = value * d_max;
   2091 	const T		   t_value = (T)d_value;
   2092 
   2093 	result = (T)((t_value & mask) << off);
   2094 
   2095 	*ptr |= result;
   2096 }
   2097 
   2098 /** Write value of channel
   2099  *
   2100  * @param channel Channel index
   2101  * @param value   Value to write
   2102  * @param pixel   Pixel data
   2103  **/
   2104 void write11F_11F_10F_Channel(GLuint channel, GLdouble value, GLubyte* pixel)
   2105 {
   2106 	deUint32* ptr = (deUint32*)pixel;
   2107 
   2108 	switch (channel)
   2109 	{
   2110 	case 0:
   2111 	{
   2112 		tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> val(value);
   2113 		deUint32 bits = val.bits();
   2114 
   2115 		*ptr |= bits;
   2116 	}
   2117 	break;
   2118 	case 1:
   2119 	{
   2120 		tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> val(value);
   2121 		deUint32 bits = val.bits();
   2122 
   2123 		*ptr |= (bits << 11);
   2124 	}
   2125 	break;
   2126 	case 2:
   2127 	{
   2128 		tcu::Float<deUint32, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> val(value);
   2129 		deUint32 bits = val.bits();
   2130 
   2131 		*ptr |= (bits << 22);
   2132 	}
   2133 	break;
   2134 	default:
   2135 		TCU_FAIL("Invalid channel");
   2136 		break;
   2137 	}
   2138 }
   2139 
   2140 /** Read value of channel
   2141  *
   2142  * @param type    Type used by pixel
   2143  * @param channel Channel index
   2144  * @param pixel   Pixel data
   2145  * @param value   Read value
   2146  **/
   2147 void Utils::readChannel(GLenum type, GLuint channel, const GLubyte* pixel, GLdouble& value)
   2148 {
   2149 	switch (type)
   2150 	{
   2151 	/* Base types */
   2152 	case GL_UNSIGNED_BYTE:
   2153 		readBaseTypeFromUnsignedChannel<GLubyte>(channel, pixel, value);
   2154 		break;
   2155 	case GL_UNSIGNED_SHORT:
   2156 		readBaseTypeFromUnsignedChannel<GLushort>(channel, pixel, value);
   2157 		break;
   2158 	case GL_UNSIGNED_INT:
   2159 		readBaseTypeFromUnsignedChannel<GLuint>(channel, pixel, value);
   2160 		break;
   2161 	case GL_BYTE:
   2162 		readBaseTypeFromSignedChannel<GLbyte>(channel, pixel, value);
   2163 		break;
   2164 	case GL_SHORT:
   2165 		readBaseTypeFromSignedChannel<GLshort>(channel, pixel, value);
   2166 		break;
   2167 	case GL_INT:
   2168 		readBaseTypeFromSignedChannel<GLint>(channel, pixel, value);
   2169 		break;
   2170 	case GL_HALF_FLOAT:
   2171 		readBaseTypeFromHalfFloatChannel(channel, pixel, value);
   2172 		break;
   2173 	case GL_FLOAT:
   2174 		readBaseTypeFromFloatChannel(channel, pixel, value);
   2175 		break;
   2176 
   2177 	/* Complicated */
   2178 	/* 3 channles */
   2179 	case GL_UNSIGNED_BYTE_3_3_2:
   2180 		read3Channel<GLubyte, 3, 3, 2, 5, 2, 0>(channel, pixel, value);
   2181 		break;
   2182 	case GL_UNSIGNED_SHORT_5_6_5:
   2183 		read3Channel<GLushort, 5, 6, 5, 11, 5, 0>(channel, pixel, value);
   2184 		break;
   2185 
   2186 	/* 4 channels */
   2187 	case GL_UNSIGNED_SHORT_4_4_4_4:
   2188 		read4Channel<GLushort, 4, 4, 4, 4, 12, 8, 4, 0>(channel, pixel, value);
   2189 		break;
   2190 	case GL_UNSIGNED_SHORT_5_5_5_1:
   2191 		read4Channel<GLushort, 5, 5, 5, 1, 11, 6, 1, 0>(channel, pixel, value);
   2192 		break;
   2193 	case GL_UNSIGNED_INT_2_10_10_10_REV:
   2194 		read4Channel<GLuint, 2, 10, 10, 10, 30, 20, 10, 0>(3 - channel, pixel, value);
   2195 		break;
   2196 	case GL_UNSIGNED_INT_5_9_9_9_REV:
   2197 		read4Channel<GLuint, 5, 9, 9, 9, 27, 18, 9, 0>(3 - channel, pixel, value);
   2198 		break;
   2199 
   2200 	/* R11F_G11F_B10F - uber complicated */
   2201 	case GL_UNSIGNED_INT_10F_11F_11F_REV:
   2202 		read11F_11F_10F_Channel(channel, pixel, value);
   2203 		break;
   2204 
   2205 	default:
   2206 		TCU_FAIL("Invalid enum");
   2207 		break;
   2208 	}
   2209 }
   2210 
   2211 /** Write value of channel
   2212  *
   2213  * @param type    Type used by pixel
   2214  * @param channel Channel index
   2215  * @param value   Value to write
   2216  * @param pixel   Pixel data
   2217  **/
   2218 void Utils::writeChannel(GLenum type, GLuint channel, GLdouble value, GLubyte* pixel)
   2219 {
   2220 	switch (type)
   2221 	{
   2222 	/* Base types */
   2223 	case GL_UNSIGNED_BYTE:
   2224 		writeBaseTypeToUnsignedChannel<GLubyte>(channel, value, pixel);
   2225 		break;
   2226 	case GL_UNSIGNED_SHORT:
   2227 		writeBaseTypeToUnsignedChannel<GLushort>(channel, value, pixel);
   2228 		break;
   2229 	case GL_UNSIGNED_INT:
   2230 		writeBaseTypeToUnsignedChannel<GLuint>(channel, value, pixel);
   2231 		break;
   2232 	case GL_BYTE:
   2233 		writeBaseTypeToSignedChannel<GLbyte>(channel, value, pixel);
   2234 		break;
   2235 	case GL_SHORT:
   2236 		writeBaseTypeToSignedChannel<GLshort>(channel, value, pixel);
   2237 		break;
   2238 	case GL_INT:
   2239 		writeBaseTypeToSignedChannel<GLint>(channel, value, pixel);
   2240 		break;
   2241 	case GL_HALF_FLOAT:
   2242 		writeBaseTypeToHalfFloatChannel(channel, value, pixel);
   2243 		break;
   2244 	case GL_FLOAT:
   2245 		writeBaseTypeToFloatChannel(channel, value, pixel);
   2246 		break;
   2247 
   2248 	/* Complicated */
   2249 
   2250 	/* 3 channles */
   2251 	case GL_UNSIGNED_BYTE_3_3_2:
   2252 		write3Channel<GLubyte, 3, 3, 2, 5, 2, 0>(channel, value, pixel);
   2253 		break;
   2254 	case GL_UNSIGNED_SHORT_5_6_5:
   2255 		write3Channel<GLushort, 5, 6, 5, 11, 5, 0>(channel, value, pixel);
   2256 		break;
   2257 
   2258 	/* 4 channels */
   2259 	case GL_UNSIGNED_SHORT_4_4_4_4:
   2260 		write4Channel<GLushort, 4, 4, 4, 4, 12, 8, 4, 0>(channel, value, pixel);
   2261 		break;
   2262 	case GL_UNSIGNED_SHORT_5_5_5_1:
   2263 		write4Channel<GLushort, 5, 5, 5, 1, 11, 6, 1, 0>(channel, value, pixel);
   2264 		break;
   2265 	case GL_UNSIGNED_INT_2_10_10_10_REV:
   2266 		write4Channel<GLuint, 2, 10, 10, 10, 30, 20, 10, 0>(3 - channel, value, pixel);
   2267 		break;
   2268 	case GL_UNSIGNED_INT_5_9_9_9_REV:
   2269 		write4Channel<GLuint, 5, 9, 9, 9, 27, 18, 9, 0>(3 - channel, value, pixel);
   2270 		break;
   2271 
   2272 	/* R11F_G11F_B10F - uber complicated */
   2273 	case GL_UNSIGNED_INT_10F_11F_11F_REV:
   2274 		write11F_11F_10F_Channel(channel, value, pixel);
   2275 		break;
   2276 
   2277 	default:
   2278 		TCU_FAIL("Invalid enum");
   2279 		break;
   2280 	}
   2281 }
   2282 
   2283 /** Packs given channels to pixel
   2284  *
   2285  * @param internal_format Internal format of image
   2286  * @param type            Type used by image
   2287  * @param red             Red channel
   2288  * @param green           Green channel
   2289  * @param blue            Blue channel
   2290  * @param alpha           Alpha channel
   2291  * @param out_pixel       Pixel data
   2292  **/
   2293 void Utils::packPixel(GLenum internal_format, GLenum type, GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha,
   2294 					  GLubyte* out_pixel)
   2295 {
   2296 	switch (internal_format)
   2297 	{
   2298 	case GL_R8:
   2299 	case GL_R8_SNORM:
   2300 	case GL_R16:
   2301 	case GL_R16F:
   2302 	case GL_R16_SNORM:
   2303 	case GL_R32F:
   2304 	case GL_R8I:
   2305 	case GL_R8UI:
   2306 	case GL_R16I:
   2307 	case GL_R16UI:
   2308 	case GL_R32I:
   2309 	case GL_R32UI:
   2310 		writeChannel(type, 0, red, out_pixel);
   2311 		break;
   2312 
   2313 	case GL_RG8:
   2314 	case GL_RG8_SNORM:
   2315 	case GL_RG16:
   2316 	case GL_RG16F:
   2317 	case GL_RG16_SNORM:
   2318 	case GL_RG32F:
   2319 	case GL_RG8I:
   2320 	case GL_RG8UI:
   2321 	case GL_RG16I:
   2322 	case GL_RG16UI:
   2323 	case GL_RG32I:
   2324 	case GL_RG32UI:
   2325 		writeChannel(type, 0, red, out_pixel);
   2326 		writeChannel(type, 1, green, out_pixel);
   2327 		break;
   2328 
   2329 	case GL_R3_G3_B2:
   2330 	case GL_RGB4:
   2331 	case GL_RGB5:
   2332 	case GL_RGB8:
   2333 	case GL_RGB8_SNORM:
   2334 	case GL_RGB10:
   2335 	case GL_R11F_G11F_B10F:
   2336 	case GL_RGB12:
   2337 	case GL_RGB16:
   2338 	case GL_RGB16F:
   2339 	case GL_RGB16_SNORM:
   2340 	case GL_RGB32F:
   2341 	case GL_RGB8I:
   2342 	case GL_RGB8UI:
   2343 	case GL_RGB16I:
   2344 	case GL_RGB16UI:
   2345 	case GL_RGB32I:
   2346 	case GL_RGB32UI:
   2347 		writeChannel(type, 0, red, out_pixel);
   2348 		writeChannel(type, 1, green, out_pixel);
   2349 		writeChannel(type, 2, blue, out_pixel);
   2350 		break;
   2351 
   2352 	case GL_RGB9_E5:
   2353 	case GL_RGBA2:
   2354 	case GL_RGBA4:
   2355 	case GL_RGB5_A1:
   2356 	case GL_RGBA8:
   2357 	case GL_RGBA8_SNORM:
   2358 	case GL_RGB10_A2:
   2359 	case GL_RGBA12:
   2360 	case GL_RGBA16:
   2361 	case GL_RGBA16F:
   2362 	case GL_RGBA16_SNORM:
   2363 	case GL_RGBA32F:
   2364 	case GL_RGBA8I:
   2365 	case GL_RGBA8UI:
   2366 	case GL_RGB10_A2UI:
   2367 	case GL_RGBA16I:
   2368 	case GL_RGBA16UI:
   2369 	case GL_RGBA32I:
   2370 	case GL_RGBA32UI:
   2371 		writeChannel(type, 0, red, out_pixel);
   2372 		writeChannel(type, 1, green, out_pixel);
   2373 		writeChannel(type, 2, blue, out_pixel);
   2374 		writeChannel(type, 3, alpha, out_pixel);
   2375 		break;
   2376 
   2377 	default:
   2378 		TCU_FAIL("Invalid enum");
   2379 		break;
   2380 	}
   2381 }
   2382 
   2383 /** Unpacks channels from pixel
   2384  *
   2385  * @param internal_format Internal format of image
   2386  * @param type            Type used by image
   2387  * @param pixel           Pixel data
   2388  * @param red             Red channel
   2389  * @param green           Green channel
   2390  * @param blue            Blue channel
   2391  * @param alpha           Alpha channel
   2392  **/
   2393 void Utils::unpackPixel(GLenum format, GLenum type, const GLubyte* pixel, GLdouble& out_red, GLdouble& out_green,
   2394 						GLdouble& out_blue, GLdouble& out_alpha)
   2395 {
   2396 	switch (format)
   2397 	{
   2398 	case GL_RED:
   2399 	case GL_RED_INTEGER:
   2400 		readChannel(type, 0, pixel, out_red);
   2401 		out_green = 1.0;
   2402 		out_blue  = 1.0;
   2403 		out_alpha = 1.0;
   2404 		break;
   2405 	case GL_RG:
   2406 	case GL_RG_INTEGER:
   2407 		readChannel(type, 0, pixel, out_red);
   2408 		readChannel(type, 1, pixel, out_green);
   2409 		out_blue  = 1.0;
   2410 		out_alpha = 1.0;
   2411 		break;
   2412 	case GL_RGB:
   2413 	case GL_RGB_INTEGER:
   2414 		switch (type)
   2415 		{
   2416 		case GL_UNSIGNED_INT_5_9_9_9_REV:
   2417 			readChannel(type, 0, pixel, out_red);
   2418 			readChannel(type, 1, pixel, out_green);
   2419 			readChannel(type, 2, pixel, out_blue);
   2420 			readChannel(type, 3, pixel, out_alpha);
   2421 			break;
   2422 		default:
   2423 			readChannel(type, 0, pixel, out_red);
   2424 			readChannel(type, 1, pixel, out_green);
   2425 			readChannel(type, 2, pixel, out_blue);
   2426 			out_alpha = 1.0;
   2427 			break;
   2428 		}
   2429 		break;
   2430 	case GL_RGBA:
   2431 	case GL_RGBA_INTEGER:
   2432 		readChannel(type, 0, pixel, out_red);
   2433 		readChannel(type, 1, pixel, out_green);
   2434 		readChannel(type, 2, pixel, out_blue);
   2435 		readChannel(type, 3, pixel, out_alpha);
   2436 		break;
   2437 	default:
   2438 		TCU_FAIL("Invalid enum");
   2439 		break;
   2440 	}
   2441 }
   2442 
   2443 inline bool Utils::roundComponent(GLenum internal_format, GLenum component, GLdouble& value)
   2444 {
   2445 	int exponent = (internal_format == GL_RGB4 ? 4 : (internal_format == GL_RGB5 ? 5 : 0));
   2446 	if (!exponent)
   2447 		return false; //Currently this only happens with GL_RGB4 and GL_RGB5 when stored as 565 type.
   2448 
   2449 	int rounded_value = static_cast<int>(floor((pow(2, exponent) - 1) * value + 0.5));
   2450 	int multiplier	= (component == GL_GREEN ? 2 : 1);
   2451 	if (internal_format == GL_RGB4)
   2452 	{
   2453 		multiplier *= 2;
   2454 	}
   2455 	value = rounded_value * multiplier;
   2456 	return true;
   2457 }
   2458 
   2459 /** Unpacks pixels and compars them
   2460  *
   2461  * @param left_format           Format of left image
   2462  * @param left_type             Type of left image
   2463  * @param left_internal_format  Internal format of left image
   2464  * @param left_pixel            Data of left pixel
   2465  * @param right_format          Format of right image
   2466  * @param right_type            Type of right image
   2467  * @param right_internal_format Internal format of right image
   2468  * @param right_pixel           Data of right pixel
   2469  *
   2470  * @return true if pixels match, false otherwise
   2471  **/
   2472 bool Utils::unpackAndComaprePixels(GLenum left_format, GLenum left_type, GLenum left_internal_format,
   2473 								   const GLubyte* left_pixel, GLenum right_format, GLenum right_type,
   2474 								   GLenum right_internal_format, const GLubyte* right_pixel)
   2475 {
   2476 	GLdouble left_red;
   2477 	GLdouble left_green;
   2478 	GLdouble left_blue;
   2479 	GLdouble left_alpha;
   2480 	GLdouble right_red;
   2481 	GLdouble right_green;
   2482 	GLdouble right_blue;
   2483 	GLdouble right_alpha;
   2484 
   2485 	unpackPixel(left_format, left_type, left_pixel, left_red, left_green, left_blue, left_alpha);
   2486 
   2487 	unpackPixel(right_format, right_type, right_pixel, right_red, right_green, right_blue, right_alpha);
   2488 
   2489 	roundComponent(left_internal_format, GL_RED, left_red);
   2490 	roundComponent(left_internal_format, GL_GREEN, left_green);
   2491 	roundComponent(left_internal_format, GL_BLUE, left_blue);
   2492 
   2493 	roundComponent(right_internal_format, GL_RED, right_red);
   2494 	roundComponent(right_internal_format, GL_GREEN, right_green);
   2495 	roundComponent(right_internal_format, GL_BLUE, right_blue);
   2496 
   2497 	return comparePixels(left_internal_format, left_red, left_green, left_blue, left_alpha, right_internal_format,
   2498 						 right_red, right_green, right_blue, right_alpha);
   2499 }
   2500 
   2501 /* FunctionalTest */
   2502 #define FUNCTIONAL_TEST_N_LAYERS 12
   2503 #define FUNCTIONAL_TEST_N_LEVELS 3
   2504 
   2505 /** Constructor
   2506  *
   2507  * @param context Text context
   2508  **/
   2509 FunctionalTest::FunctionalTest(deqp::Context& context)
   2510 	: TestCase(context, "functional", "Test verifies CopySubImageData copy data as requested")
   2511 	, m_dst_buf_name(0)
   2512 	, m_dst_tex_name(0)
   2513 	, m_rb_name(0)
   2514 	, m_src_buf_name(0)
   2515 	, m_src_tex_name(0)
   2516 	, m_test_case_index(0)
   2517 {
   2518 	for (GLuint src_tgt_id = 0; src_tgt_id < s_n_valid_targets; ++src_tgt_id)
   2519 	{
   2520 		const GLenum src_target = s_valid_targets[src_tgt_id];
   2521 
   2522 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS == 0
   2523 		if ((GL_TEXTURE_1D == src_target) || (GL_TEXTURE_1D_ARRAY == src_target) || (GL_TEXTURE_2D == src_target) ||
   2524 			(GL_TEXTURE_CUBE_MAP == src_target) || (GL_TEXTURE_CUBE_MAP_ARRAY == src_target))
   2525 		{
   2526 			continue;
   2527 		}
   2528 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS == 0 */
   2529 
   2530 		for (GLuint dst_tgt_id = 0; dst_tgt_id < s_n_valid_targets; ++dst_tgt_id)
   2531 		{
   2532 			const GLenum dst_target = s_valid_targets[dst_tgt_id];
   2533 
   2534 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS == 0
   2535 			if ((GL_TEXTURE_1D == dst_target) || (GL_TEXTURE_1D_ARRAY == dst_target) || (GL_TEXTURE_2D == dst_target) ||
   2536 				(GL_TEXTURE_CUBE_MAP == dst_target) || (GL_TEXTURE_CUBE_MAP_ARRAY == dst_target))
   2537 			{
   2538 				continue;
   2539 			}
   2540 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_TARGETS == 0 */
   2541 
   2542 			/* Skip render buffer as destination */
   2543 			if (GL_RENDERBUFFER == dst_target)
   2544 			{
   2545 				continue;
   2546 			}
   2547 
   2548 			/* Skip multisampled */
   2549 			if ((true == Utils::isTargetMultisampled(src_target)) || (true == Utils::isTargetMultisampled(dst_target)))
   2550 			{
   2551 				continue;
   2552 			}
   2553 
   2554 			for (GLuint src_frmt_id = 0; src_frmt_id < s_n_internal_formats; ++src_frmt_id)
   2555 			{
   2556 				const GLenum src_format = s_internal_formats[src_frmt_id];
   2557 
   2558 				if (src_format == GL_RGB9_E5 && src_target == GL_RENDERBUFFER)
   2559 				{
   2560 					continue;
   2561 				}
   2562 
   2563 				for (GLuint dst_frmt_id = 0; dst_frmt_id < s_n_internal_formats; ++dst_frmt_id)
   2564 				{
   2565 					const GLenum dst_format = s_internal_formats[dst_frmt_id];
   2566 
   2567 					/* Skip not compatible formats */
   2568 					if (false == Utils::areFormatsCompatible(src_format, dst_format))
   2569 					{
   2570 						continue;
   2571 					}
   2572 
   2573 					prepareTestCases(dst_format, dst_target, src_format, src_target);
   2574 				}
   2575 			}
   2576 		}
   2577 	}
   2578 }
   2579 
   2580 /** Execute test
   2581  *
   2582  * @return CONTINUE as long there are more test case, STOP otherwise
   2583  **/
   2584 tcu::TestNode::IterateResult FunctionalTest::iterate()
   2585 {
   2586 	GLubyte*					 dst_pixels[FUNCTIONAL_TEST_N_LEVELS] = { 0 };
   2587 	const Functions&			 gl									  = m_context.getRenderContext().getFunctions();
   2588 	tcu::TestNode::IterateResult it_result							  = tcu::TestNode::STOP;
   2589 	bool						 result								  = false;
   2590 	GLubyte*					 src_pixels[FUNCTIONAL_TEST_N_LEVELS] = { 0 };
   2591 	const testCase&				 test_case							  = m_test_cases[m_test_case_index];
   2592 
   2593 	gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
   2594 	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2595 	GLU_EXPECT_NO_ERROR(gl.getError(), "PixelStorei");
   2596 
   2597 	try
   2598 	{
   2599 		/* Prepare pixels */
   2600 		prepareDstPxls(test_case.m_dst, dst_pixels);
   2601 		prepareSrcPxls(test_case.m_src, test_case.m_dst.m_internal_format, src_pixels);
   2602 
   2603 		/* Prepare textures */
   2604 		m_dst_tex_name = prepareTexture(test_case.m_dst, (const GLubyte**)dst_pixels, m_dst_buf_name);
   2605 
   2606 		if (GL_RENDERBUFFER == test_case.m_src.m_target)
   2607 		{
   2608 			targetDesc desc = test_case.m_src;
   2609 			desc.m_target   = GL_TEXTURE_2D;
   2610 
   2611 			m_rb_name	  = prepareTexture(test_case.m_src, (const GLubyte**)src_pixels, m_src_buf_name);
   2612 			m_src_tex_name = prepareTexture(desc, (const GLubyte**)src_pixels, m_src_buf_name);
   2613 		}
   2614 		else
   2615 		{
   2616 			m_src_tex_name = prepareTexture(test_case.m_src, (const GLubyte**)src_pixels, m_src_buf_name);
   2617 		}
   2618 
   2619 		/* Copy images and verify results */
   2620 		result = copyAndVerify(test_case, (const GLubyte**)dst_pixels, (const GLubyte**)src_pixels);
   2621 	}
   2622 	catch (tcu::Exception& exc)
   2623 	{
   2624 		clean();
   2625 		cleanPixels((GLubyte**)dst_pixels);
   2626 		cleanPixels((GLubyte**)src_pixels);
   2627 		throw exc;
   2628 	}
   2629 
   2630 	/* Free resources */
   2631 	clean();
   2632 	cleanPixels((GLubyte**)dst_pixels);
   2633 	cleanPixels((GLubyte**)src_pixels);
   2634 
   2635 	/* Set result */
   2636 	if (true == result)
   2637 	{
   2638 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2639 
   2640 		/* Increase index */
   2641 		m_test_case_index += 1;
   2642 
   2643 		/* Are there any test cases left */
   2644 		if (m_test_cases.size() > m_test_case_index)
   2645 		{
   2646 			it_result = tcu::TestNode::CONTINUE;
   2647 		}
   2648 	}
   2649 	else
   2650 	{
   2651 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failure. " << tcu::TestLog::EndMessage;
   2652 
   2653 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2654 	}
   2655 
   2656 	/* Done */
   2657 	return it_result;
   2658 }
   2659 
   2660 /** Calculate dimmensions of all levels based on size of specific level
   2661  *
   2662  * @param target      Target of image
   2663  * @param level       Level index
   2664  * @param width       Width of image at <level>
   2665  * @param height      Height of image at <level>
   2666  * @param out_widths  Calcualted widths, array of FUNCTIONAL_TEST_N_LEVELS'th elements
   2667  * @param out_heights Calculated heights, array of FUNCTIONAL_TEST_N_LEVELS'th elements
   2668  * @param out_depths  Calculated dephts, array of FUNCTIONAL_TEST_N_LEVELS'th elements
   2669  **/
   2670 void FunctionalTest::calculateDimmensions(GLenum target, GLuint level, GLuint width, GLuint height, GLuint* out_widths,
   2671 										  GLuint* out_heights, GLuint* out_depths) const
   2672 {
   2673 	GLuint		 divide = 100;
   2674 	GLuint		 factors[FUNCTIONAL_TEST_N_LEVELS];
   2675 	GLuint		 factor			= divide;
   2676 	const bool   is_multi_layer = Utils::isTargetMultilayer(target);
   2677 	const GLuint n_layers		= (true == is_multi_layer) ? FUNCTIONAL_TEST_N_LAYERS : 1;
   2678 
   2679 	for (GLint i = (GLint)level; i >= 0; --i)
   2680 	{
   2681 		factors[i] = factor;
   2682 		factor *= 2;
   2683 	}
   2684 
   2685 	factor = divide / 2;
   2686 	for (GLuint i = level + 1; i < FUNCTIONAL_TEST_N_LEVELS; ++i)
   2687 	{
   2688 		factors[i] = factor;
   2689 		factor /= 2;
   2690 	}
   2691 
   2692 	for (GLuint i = 0; i < FUNCTIONAL_TEST_N_LEVELS; ++i)
   2693 	{
   2694 		out_widths[i]  = width * factors[i] / divide;
   2695 		out_heights[i] = height * factors[i] / divide;
   2696 
   2697 		if (GL_TEXTURE_3D == target)
   2698 		{
   2699 			out_depths[i] = FUNCTIONAL_TEST_N_LAYERS * factors[i] / divide;
   2700 		}
   2701 		else
   2702 		{
   2703 			out_depths[i] = n_layers;
   2704 		}
   2705 	}
   2706 }
   2707 
   2708 /** Execute copyImageSubData for given test case and verify results
   2709  *
   2710  * @param test_case  Test case
   2711  * @param dst_pixels Data of destination image
   2712  * @param src_pixels Data of source image
   2713  *
   2714  * @return true if there is no error and results match expectations, false otherwise
   2715  **/
   2716 bool FunctionalTest::copyAndVerify(const testCase& test_case, const GLubyte** dst_pixels, const GLubyte** src_pixels)
   2717 {
   2718 	GLenum			 error				= GL_NO_ERROR;
   2719 	const Functions& gl					= m_context.getRenderContext().getFunctions();
   2720 	GLuint			 region_depth		= 1;
   2721 	GLuint			 dst_layer_step		= 0;
   2722 	const bool		 is_dst_multi_layer = Utils::isTargetMultilayer(test_case.m_dst.m_target);
   2723 	const bool		 is_src_multi_layer = Utils::isTargetMultilayer(test_case.m_src.m_target);
   2724 	bool			 result				= false;
   2725 	GLuint			 src_layer_step		= 0;
   2726 	GLuint			 n_layers			= 1;
   2727 
   2728 	/* Configure layers */
   2729 	if ((true == is_dst_multi_layer) || (true == is_src_multi_layer))
   2730 	{
   2731 		if (is_src_multi_layer == is_dst_multi_layer)
   2732 		{
   2733 			/* Both objects are multilayered, copy all layers at once, verify at once */
   2734 			region_depth = FUNCTIONAL_TEST_N_LAYERS;
   2735 		}
   2736 		else if (true == is_dst_multi_layer)
   2737 		{
   2738 			/* Destination is multilayered, copy each layer separetly, verify at once */
   2739 			n_layers	   = FUNCTIONAL_TEST_N_LAYERS;
   2740 			dst_layer_step = 1;
   2741 		}
   2742 		else
   2743 		{
   2744 			/* Destination is multilayered, copy and verify each layer separetly */
   2745 			n_layers	   = FUNCTIONAL_TEST_N_LAYERS;
   2746 			src_layer_step = 1;
   2747 		}
   2748 	}
   2749 
   2750 	/* Copy and verification */
   2751 	{
   2752 		GLuint dst_layer = 0;
   2753 		GLuint src_layer = 0;
   2754 
   2755 		/* For each layer */
   2756 		for (GLuint layer = 0; layer < n_layers; ++layer)
   2757 		{
   2758 			if (0 == m_rb_name)
   2759 			{
   2760 				gl.copyImageSubData(m_src_tex_name, test_case.m_src.m_target, test_case.m_src.m_level,
   2761 									test_case.m_src_x, test_case.m_src_y, src_layer, m_dst_tex_name,
   2762 									test_case.m_dst.m_target, test_case.m_dst.m_level, test_case.m_dst_x,
   2763 									test_case.m_dst_y, dst_layer, test_case.m_width, test_case.m_height, region_depth);
   2764 			}
   2765 			else /* Copy from src to rb and from rb to dst */
   2766 			{
   2767 				/* Src and rb shares differs only on target */
   2768 				gl.copyImageSubData(m_src_tex_name, GL_TEXTURE_2D, test_case.m_src.m_level, test_case.m_src_x,
   2769 									test_case.m_src_y, src_layer, m_rb_name, test_case.m_src.m_target,
   2770 									test_case.m_src.m_level, test_case.m_src_x, test_case.m_src_y, src_layer,
   2771 									test_case.m_width, test_case.m_height, region_depth);
   2772 
   2773 				gl.copyImageSubData(m_rb_name, test_case.m_src.m_target, test_case.m_src.m_level, test_case.m_src_x,
   2774 									test_case.m_src_y, src_layer, m_dst_tex_name, test_case.m_dst.m_target,
   2775 									test_case.m_dst.m_level, test_case.m_dst_x, test_case.m_dst_y, dst_layer,
   2776 									test_case.m_width, test_case.m_height, region_depth);
   2777 			}
   2778 
   2779 			/* Verify generated error */
   2780 			error = gl.getError();
   2781 
   2782 			if (GL_NO_ERROR == error)
   2783 			{
   2784 				/* Verify copy results */
   2785 				result = verify(test_case, dst_layer, dst_pixels, src_layer, src_pixels, region_depth);
   2786 			}
   2787 
   2788 			if ((GL_NO_ERROR != error) || (false == result))
   2789 			{
   2790 				m_context.getTestContext().getLog()
   2791 					<< tcu::TestLog::Message
   2792 					<< "Failure. Targets src: " << glu::getTextureTargetStr(test_case.m_src.m_target)
   2793 					<< ", dst: " << glu::getTextureTargetStr(test_case.m_dst.m_target)
   2794 					<< ". Levels src: " << test_case.m_src.m_level << ", dst: " << test_case.m_dst.m_level
   2795 					<< ". Dimmensions src [" << test_case.m_src.m_width << ", " << test_case.m_src.m_height
   2796 					<< "], dst [" << test_case.m_dst.m_width << ", " << test_case.m_dst.m_height << "]. Region ["
   2797 					<< test_case.m_width << " x " << test_case.m_height << " x " << region_depth << "] from ["
   2798 					<< test_case.m_src_x << ", " << test_case.m_src_y << ", " << src_layer << "] to ["
   2799 					<< test_case.m_dst_x << ", " << test_case.m_dst_y << ", " << dst_layer
   2800 					<< "]. Format src: " << glu::getInternalFormatParameterStr(test_case.m_src.m_internal_format)
   2801 					<< ", dst: " << glu::getInternalFormatParameterStr(test_case.m_dst.m_internal_format)
   2802 					<< tcu::TestLog::EndMessage;
   2803 
   2804 				if (GL_NO_ERROR != error)
   2805 				{
   2806 					m_context.getTestContext().getLog() << tcu::TestLog::Message
   2807 														<< "Failed due to error: " << glu::getErrorStr(error)
   2808 														<< tcu::TestLog::EndMessage;
   2809 
   2810 					TCU_FAIL("Copy operation failed");
   2811 				}
   2812 
   2813 				return false;
   2814 			}
   2815 
   2816 			/* Step one layer */
   2817 			dst_layer += dst_layer_step;
   2818 			src_layer += src_layer_step;
   2819 		}
   2820 	}
   2821 
   2822 	return true;
   2823 }
   2824 
   2825 /** Cleans resources
   2826  *
   2827  **/
   2828 void FunctionalTest::clean()
   2829 {
   2830 	const Functions& gl = m_context.getRenderContext().getFunctions();
   2831 
   2832 	/* Clean textures and buffers. Errors ignored */
   2833 	gl.deleteTextures(1, &m_dst_tex_name);
   2834 	gl.deleteTextures(1, &m_src_tex_name);
   2835 
   2836 	m_dst_tex_name = 0;
   2837 	m_src_tex_name = 0;
   2838 
   2839 	if (0 != m_dst_buf_name)
   2840 	{
   2841 		gl.deleteBuffers(1, &m_dst_buf_name);
   2842 		m_dst_buf_name = 0;
   2843 	}
   2844 
   2845 	if (0 != m_rb_name)
   2846 	{
   2847 		gl.deleteRenderbuffers(1, &m_rb_name);
   2848 		m_rb_name = 0;
   2849 	}
   2850 
   2851 	if (0 != m_src_buf_name)
   2852 	{
   2853 		gl.deleteBuffers(1, &m_src_buf_name);
   2854 		m_src_buf_name = 0;
   2855 	}
   2856 }
   2857 
   2858 /** Free memory allocated for images
   2859  *
   2860  * @param pixels Array of pointers to image data
   2861  **/
   2862 void FunctionalTest::cleanPixels(GLubyte** pixels) const
   2863 {
   2864 	for (GLuint i = 0; i < FUNCTIONAL_TEST_N_LEVELS; ++i)
   2865 	{
   2866 		if (0 != pixels[i])
   2867 		{
   2868 			delete[] pixels[i];
   2869 			pixels[i] = 0;
   2870 		}
   2871 	}
   2872 }
   2873 
   2874 /** Compare two images
   2875  * @param left_desc     Descriptor of left image
   2876  * @param left_data     Data of left image
   2877  * @param left_x        X of left image
   2878  * @param left_y        Y of left image
   2879  * @param left_layer    Layer of left image
   2880  * @param left_level    Level of left image
   2881  * @param right_desc    Descriptor of right image
   2882  * @param right_data    Data of right image
   2883  * @param right_x       X of right image
   2884  * @param right_y       Y of right image
   2885  * @param right_layer   Layer of right image
   2886  * @param right_level   Level of right image
   2887  * @param region_width  Width of region to compare
   2888  * @param region_height Height of region to compare
   2889  *
   2890  * @return true if images are considered idenctial, false otherwise
   2891  **/
   2892 bool FunctionalTest::compareImages(const targetDesc& left_desc, const GLubyte* left_data, GLuint left_x, GLuint left_y,
   2893 								   GLuint left_layer, GLuint left_level, const targetDesc& right_desc,
   2894 								   const glw::GLubyte* right_data, GLuint right_x, GLuint right_y, GLuint right_layer,
   2895 								   GLuint right_level, GLuint region_width, GLuint region_height) const
   2896 {
   2897 	/* Get level dimmensions */
   2898 	GLuint left_heights[FUNCTIONAL_TEST_N_LEVELS];
   2899 	GLuint left_widths[FUNCTIONAL_TEST_N_LEVELS];
   2900 	GLuint left_depths[FUNCTIONAL_TEST_N_LEVELS];
   2901 	GLuint right_heights[FUNCTIONAL_TEST_N_LEVELS];
   2902 	GLuint right_widths[FUNCTIONAL_TEST_N_LEVELS];
   2903 	GLuint right_depths[FUNCTIONAL_TEST_N_LEVELS];
   2904 
   2905 	calculateDimmensions(left_desc.m_target, left_desc.m_level, left_desc.m_width, left_desc.m_height, left_widths,
   2906 						 left_heights, left_depths);
   2907 
   2908 	calculateDimmensions(right_desc.m_target, right_desc.m_level, right_desc.m_width, right_desc.m_height, right_widths,
   2909 						 right_heights, right_depths);
   2910 
   2911 	/* Constants */
   2912 	/* Dimmensions */
   2913 	const GLuint left_height  = left_heights[left_level];
   2914 	const GLuint left_width   = left_widths[left_level];
   2915 	const GLuint right_height = right_heights[right_level];
   2916 	const GLuint right_width  = right_widths[right_level];
   2917 	/* Sizes */
   2918 	const GLuint left_pixel_size  = Utils::getPixelSizeForFormat(left_desc.m_internal_format);
   2919 	const GLuint left_line_size   = left_pixel_size * left_width;
   2920 	const GLuint left_layer_size  = left_line_size * left_height;
   2921 	const GLuint right_pixel_size = Utils::getPixelSizeForFormat(right_desc.m_internal_format);
   2922 	const GLuint right_line_size  = right_pixel_size * right_width;
   2923 	const GLuint right_layer_size = right_line_size * right_height;
   2924 
   2925 	/* Offsets */
   2926 	const GLuint left_layer_offset	 = left_layer_size * left_layer;
   2927 	const GLuint left_reg_line_offset  = left_line_size * left_y;
   2928 	const GLuint left_reg_pix_offset   = left_pixel_size * left_x;
   2929 	const GLuint right_layer_offset	= right_layer_size * right_layer;
   2930 	const GLuint right_reg_line_offset = right_line_size * right_y;
   2931 	const GLuint right_reg_pix_offset  = right_pixel_size * right_x;
   2932 
   2933 	/* Pointers */
   2934 	const GLubyte* left_layer_data  = left_data + left_layer_offset;
   2935 	const GLubyte* right_layer_data = right_data + right_layer_offset;
   2936 
   2937 	/* For each line of region */
   2938 	for (GLuint y = 0; y < region_height; ++y)
   2939 	{
   2940 		/* Offsets */
   2941 		const GLuint left_line_offset  = left_reg_line_offset + y * left_line_size;
   2942 		const GLuint right_line_offset = right_reg_line_offset + y * right_line_size;
   2943 
   2944 		/* Pointers */
   2945 		const GLubyte* left_line_data  = left_layer_data + left_line_offset;
   2946 		const GLubyte* right_line_data = right_layer_data + right_line_offset;
   2947 
   2948 		/* For each pixel of region */
   2949 		for (GLuint x = 0; x < region_width; ++x)
   2950 		{
   2951 			/* Offsets */
   2952 			const GLuint left_pixel_offset  = left_reg_pix_offset + x * left_pixel_size;
   2953 			const GLuint right_pixel_offset = right_reg_pix_offset + x * right_pixel_size;
   2954 
   2955 			/* Pointers */
   2956 			const GLubyte* left_pixel_data  = left_line_data + left_pixel_offset;
   2957 			const GLubyte* right_pixel_data = right_line_data + right_pixel_offset;
   2958 
   2959 			/* Compare */
   2960 			if (false == Utils::comparePixels(left_pixel_size, left_pixel_data, right_pixel_size, right_pixel_data))
   2961 			{
   2962 				if (false == Utils::unpackAndComaprePixels(left_desc.m_format, left_desc.m_type,
   2963 														   left_desc.m_internal_format, left_pixel_data,
   2964 														   right_desc.m_format, right_desc.m_type,
   2965 														   right_desc.m_internal_format, right_pixel_data))
   2966 				{
   2967 					m_context.getTestContext().getLog()
   2968 						<< tcu::TestLog::Message << "Not matching pixels found. Left: [" << x + left_x << ", "
   2969 						<< y + left_y << ", " << left_layer << "] lvl:" << left_level
   2970 						<< ", off: " << left_pixel_data - left_data
   2971 						<< ", data: " << Utils::getPixelString(left_desc.m_internal_format, left_pixel_data)
   2972 						<< ". Right: [" << x + right_x << ", " << y + right_y << ", " << right_layer
   2973 						<< "] lvl: " << right_level << ", off: " << right_pixel_data - right_data
   2974 						<< ", data: " << Utils::getPixelString(right_desc.m_internal_format, right_pixel_data)
   2975 						<< tcu::TestLog::EndMessage;
   2976 
   2977 					return false;
   2978 				}
   2979 			}
   2980 		}
   2981 	}
   2982 
   2983 	return true;
   2984 }
   2985 
   2986 /** Prepare regions that should not be modified during test case
   2987  *
   2988  * @param test_case     Test case descriptor
   2989  * @param dst_level     Level of destination image
   2990  * @param out_regions   Number of regions
   2991  * @param out_n_regions Regions
   2992  **/
   2993 void FunctionalTest::getCleanRegions(const testCase& test_case, GLuint dst_level, GLuint out_regions[4][4],
   2994 									 GLuint& out_n_regions) const
   2995 {
   2996 	GLuint dst_heights[FUNCTIONAL_TEST_N_LEVELS];
   2997 	GLuint dst_widths[FUNCTIONAL_TEST_N_LEVELS];
   2998 	GLuint dst_depths[FUNCTIONAL_TEST_N_LEVELS];
   2999 
   3000 	out_n_regions = 0;
   3001 
   3002 	calculateDimmensions(test_case.m_dst.m_target, dst_level, test_case.m_dst.m_width, test_case.m_dst.m_height,
   3003 						 dst_widths, dst_heights, dst_depths);
   3004 
   3005 	/* Constants */
   3006 	/* Copied region */
   3007 	const GLuint reg_x = test_case.m_dst_x;
   3008 	const GLuint reg_y = test_case.m_dst_y;
   3009 	const GLuint reg_w = test_case.m_width;
   3010 	const GLuint reg_h = test_case.m_height;
   3011 	const GLuint reg_r = reg_x + reg_w;
   3012 	const GLuint reg_t = reg_y + reg_h;
   3013 
   3014 	/* Image */
   3015 	const GLuint img_w = dst_widths[dst_level];
   3016 	const GLuint img_h = dst_heights[dst_level];
   3017 
   3018 	/* Bottom row */
   3019 	if (0 != reg_y)
   3020 	{
   3021 		out_regions[out_n_regions][0] = 0;
   3022 		out_regions[out_n_regions][1] = 0;
   3023 		out_regions[out_n_regions][2] = img_w;
   3024 		out_regions[out_n_regions][3] = reg_y;
   3025 		out_n_regions += 1;
   3026 	}
   3027 
   3028 	/* Left edge */
   3029 	if (0 != reg_x)
   3030 	{
   3031 		out_regions[out_n_regions][0] = 0;
   3032 		out_regions[out_n_regions][1] = reg_y;
   3033 		out_regions[out_n_regions][2] = reg_x;
   3034 		out_regions[out_n_regions][3] = reg_h;
   3035 		out_n_regions += 1;
   3036 	}
   3037 
   3038 	/* Right edge */
   3039 	if (img_w != reg_r)
   3040 	{
   3041 		out_regions[out_n_regions][0] = reg_r;
   3042 		out_regions[out_n_regions][1] = reg_y;
   3043 		out_regions[out_n_regions][2] = img_w - reg_r;
   3044 		out_regions[out_n_regions][3] = reg_h;
   3045 		out_n_regions += 1;
   3046 	}
   3047 
   3048 	/* Top row */
   3049 	if (img_h != reg_t)
   3050 	{
   3051 		out_regions[out_n_regions][0] = 0;
   3052 		out_regions[out_n_regions][1] = reg_t;
   3053 		out_regions[out_n_regions][2] = img_w;
   3054 		out_regions[out_n_regions][3] = img_h - reg_t;
   3055 		out_n_regions += 1;
   3056 	}
   3057 }
   3058 
   3059 /** Get pixel data for image
   3060  *
   3061  * @param name       Name of image
   3062  * @param desc       Descriptor of image
   3063  * @param level      Level to capture
   3064  * @param out_pixels Pixels
   3065  **/
   3066 void FunctionalTest::getPixels(GLuint name, const targetDesc& desc, GLuint level, GLubyte* out_pixels) const
   3067 {
   3068 	const Functions& gl = m_context.getRenderContext().getFunctions();
   3069 
   3070 	gl.bindTexture(desc.m_target, name);
   3071 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   3072 
   3073 	gl.getTexImage(desc.m_target, level, desc.m_format, desc.m_type, out_pixels);
   3074 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
   3075 
   3076 	gl.bindTexture(desc.m_target, 0);
   3077 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   3078 }
   3079 
   3080 /** Prepare data for destination image
   3081  *
   3082  * @param desc       Descriptor
   3083  * @param out_pixels Array of pointer to image data
   3084  **/
   3085 void FunctionalTest::prepareDstPxls(const FunctionalTest::targetDesc& desc, GLubyte** out_pixels) const
   3086 {
   3087 	const GLenum internal_format = desc.m_internal_format;
   3088 	const bool   is_multi_level  = Utils::isTargetMultilevel(desc.m_target);
   3089 	GLuint		 n_levels		 = 1;
   3090 	const GLuint pixel_size		 = Utils::getPixelSizeForFormat(desc.m_internal_format);
   3091 	const GLenum type			 = desc.m_type;
   3092 
   3093 	/* Configure levels */
   3094 	if (true == is_multi_level)
   3095 	{
   3096 		n_levels = FUNCTIONAL_TEST_N_LEVELS;
   3097 	}
   3098 
   3099 	/* Calculate dimmensions */
   3100 	GLuint heights[FUNCTIONAL_TEST_N_LEVELS];
   3101 	GLuint widths[FUNCTIONAL_TEST_N_LEVELS];
   3102 	GLuint depths[FUNCTIONAL_TEST_N_LEVELS];
   3103 
   3104 	calculateDimmensions(desc.m_target, desc.m_level, desc.m_width, desc.m_height, widths, heights, depths);
   3105 
   3106 	/* Prepare storage */
   3107 	for (GLuint i = 0; i < n_levels; ++i)
   3108 	{
   3109 		const GLuint req_memory_per_layer = pixel_size * widths[i] * heights[i];
   3110 		const GLuint req_memory_for_level = req_memory_per_layer * depths[i];
   3111 
   3112 		out_pixels[i] = new GLubyte[req_memory_for_level];
   3113 
   3114 		if (0 == out_pixels[i])
   3115 		{
   3116 			TCU_FAIL("Memory allocation failed");
   3117 		}
   3118 
   3119 		memset(out_pixels[i], 0, req_memory_for_level);
   3120 	}
   3121 
   3122 	/* Fill pixels */
   3123 	for (GLuint i = 0; i < n_levels; ++i)
   3124 	{
   3125 		const GLuint n_layers = depths[i];
   3126 		const GLuint n_pixels = widths[i] * heights[i];
   3127 		GLubyte*	 ptr	  = (GLubyte*)out_pixels[i];
   3128 
   3129 		for (GLuint j = 0; j < n_pixels * n_layers; ++j)
   3130 		{
   3131 			GLubyte* pixel_data = ptr + j * pixel_size;
   3132 
   3133 			Utils::packPixel(internal_format, type, 1.0, 1.0, 1.0, 1.0, pixel_data);
   3134 		}
   3135 	}
   3136 }
   3137 
   3138 /** Prepare data for source image
   3139  *
   3140  * @param desc                Descriptor
   3141  * @param dst_internal_format Internal format of destination image
   3142  * @param out_pixels          Array of pointer to image data
   3143  **/
   3144 void FunctionalTest::prepareSrcPxls(const FunctionalTest::targetDesc& desc, GLenum /* dst_internal_format */,
   3145 									GLubyte**						  out_pixels) const
   3146 {
   3147 	const GLenum internal_format = desc.m_internal_format;
   3148 	const bool   is_multi_level  = Utils::isTargetMultilevel(desc.m_target);
   3149 	GLuint		 n_levels		 = 1;
   3150 	const GLuint pixel_size		 = Utils::getPixelSizeForFormat(desc.m_internal_format);
   3151 	const GLenum type			 = desc.m_type;
   3152 
   3153 	/* Configure levels */
   3154 	if (true == is_multi_level)
   3155 	{
   3156 		n_levels = FUNCTIONAL_TEST_N_LEVELS;
   3157 	}
   3158 
   3159 	/* Calculate dimmensions */
   3160 	GLuint heights[FUNCTIONAL_TEST_N_LEVELS];
   3161 	GLuint widths[FUNCTIONAL_TEST_N_LEVELS];
   3162 	GLuint depths[FUNCTIONAL_TEST_N_LEVELS];
   3163 
   3164 	calculateDimmensions(desc.m_target, desc.m_level, desc.m_width, desc.m_height, widths, heights, depths);
   3165 
   3166 	/* Prepare storage */
   3167 	for (GLuint i = 0; i < n_levels; ++i)
   3168 	{
   3169 		const GLuint req_memory_per_layer = pixel_size * widths[i] * heights[i];
   3170 		const GLuint req_memory_for_level = req_memory_per_layer * depths[i];
   3171 
   3172 		out_pixels[i] = new GLubyte[req_memory_for_level];
   3173 
   3174 		if (0 == out_pixels[i])
   3175 		{
   3176 			TCU_FAIL("Memory allocation failed");
   3177 		}
   3178 
   3179 		memset(out_pixels[i], 0, req_memory_for_level);
   3180 	}
   3181 
   3182 	for (GLuint lvl = 0; lvl < n_levels; ++lvl)
   3183 	{
   3184 		const GLuint n_layers			  = depths[lvl];
   3185 		const GLuint line_size			  = pixel_size * widths[lvl];
   3186 		const GLuint req_memory_per_layer = line_size * heights[lvl];
   3187 		GLubyte*	 level				  = (GLubyte*)out_pixels[lvl];
   3188 
   3189 		for (GLuint lay = 0; lay < n_layers; ++lay)
   3190 		{
   3191 			const GLuint layer_offset = lay * req_memory_per_layer;
   3192 
   3193 			GLubyte* layer = ((GLubyte*)level) + layer_offset;
   3194 
   3195 			for (GLuint y = 0; y < heights[lvl]; ++y)
   3196 			{
   3197 				const GLuint line_offset = line_size * y;
   3198 
   3199 				GLubyte* line = layer + line_offset;
   3200 
   3201 				for (GLuint x = 0; x < widths[lvl]; ++x)
   3202 				{
   3203 					const GLuint pixel_offset = x * pixel_size;
   3204 
   3205 					GLubyte* pixel = line + pixel_offset;
   3206 
   3207 					/* 255 is max ubyte. 1/15.9375 = 16/255 */
   3208 					const GLdouble red   = ((GLdouble)x) / 255.0 + (((GLdouble)y) / 15.9375);
   3209 					const GLdouble green = ((GLdouble)lay) / 255.0 + (((GLdouble)lvl) / 15.9375);
   3210 					const GLdouble blue  = 0.125;
   3211 					const GLdouble alpha = 1.0; /* This value has special meaning for some internal_formats */
   3212 
   3213 					Utils::packPixel(internal_format, type, red, green, blue, alpha, pixel);
   3214 				}
   3215 			}
   3216 		}
   3217 	}
   3218 }
   3219 
   3220 /** Prepare test cases for given targets and internal formats
   3221  *
   3222  * @param dst_internal_format Internal format of destination image
   3223  * @param dst_target          Target of destination image
   3224  * @param src_internal_format Internal format of source image
   3225  * @param src_target          Target of source image
   3226  **/
   3227 void FunctionalTest::prepareTestCases(GLenum dst_internal_format, GLenum dst_target, GLenum src_internal_format,
   3228 									  GLenum src_target)
   3229 {
   3230 	static const GLuint image_dimmensions[] = {
   3231 		7,
   3232 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_IMG_DIM
   3233 		8,
   3234 		9,
   3235 		10,
   3236 		11,
   3237 		12,
   3238 		13,
   3239 		14,
   3240 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_IMG_DIM */
   3241 		15
   3242 	};
   3243 
   3244 	static const GLuint region_dimmensions[] = {
   3245 		1,
   3246 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_DIM
   3247 		2,
   3248 		3,
   3249 		4,
   3250 		5,
   3251 		6,
   3252 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_DIM */
   3253 		7
   3254 	};
   3255 
   3256 	static const GLuint n_image_dimmensions  = sizeof(image_dimmensions) / sizeof(image_dimmensions[0]);
   3257 	static const GLuint n_region_dimmensions = sizeof(region_dimmensions) / sizeof(region_dimmensions[0]);
   3258 
   3259 	const bool   is_dst_multi_level = Utils::isTargetMultilevel(dst_target);
   3260 	const bool   is_src_multi_level = Utils::isTargetMultilevel(src_target);
   3261 	const GLenum dst_format			= Utils::getFormat(dst_internal_format);
   3262 	const GLuint dst_n_levels		= (true == is_dst_multi_level) ? FUNCTIONAL_TEST_N_LEVELS : 1;
   3263 	const GLenum dst_type			= Utils::getType(dst_internal_format);
   3264 	const GLenum src_format			= Utils::getFormat(src_internal_format);
   3265 	const GLuint src_n_levels		= (true == is_src_multi_level) ? FUNCTIONAL_TEST_N_LEVELS : 1;
   3266 	const GLenum src_type			= Utils::getType(src_internal_format);
   3267 
   3268 	for (GLuint src_level = 0; src_level < src_n_levels; ++src_level)
   3269 	{
   3270 		for (GLuint dst_level = 0; dst_level < dst_n_levels; ++dst_level)
   3271 		{
   3272 			for (GLuint src_img_dim_id = 0; src_img_dim_id < n_image_dimmensions; ++src_img_dim_id)
   3273 			{
   3274 				const GLuint src_image_dimmension = image_dimmensions[src_img_dim_id];
   3275 
   3276 				for (GLuint dst_img_dim_id = 0; dst_img_dim_id < n_image_dimmensions; ++dst_img_dim_id)
   3277 				{
   3278 					const GLuint dst_image_dimmension = image_dimmensions[dst_img_dim_id];
   3279 
   3280 					for (GLuint reg_dim_id = 0; reg_dim_id < n_region_dimmensions; ++reg_dim_id)
   3281 					{
   3282 						const GLuint region_dimmension = region_dimmensions[reg_dim_id];
   3283 						GLuint		 dst_coord[3]	  = { 0, 0, 0 };
   3284 						const GLuint dst_dim_diff	  = dst_image_dimmension - region_dimmension;
   3285 						GLuint		 n_dst_coords	  = 1;
   3286 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS
   3287 						GLuint n_src_coords = 1;
   3288 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */
   3289 						GLuint		 src_coord[3] = { 0, 0, 0 };
   3290 						const GLuint src_dim_diff = src_image_dimmension - region_dimmension;
   3291 
   3292 						/* Calculate coords */
   3293 						if (1 == dst_dim_diff)
   3294 						{
   3295 							dst_coord[1] = 1;
   3296 							n_dst_coords = 2;
   3297 						}
   3298 						else if (1 < dst_dim_diff)
   3299 						{
   3300 							dst_coord[1] = dst_dim_diff / 2;
   3301 							dst_coord[2] = dst_dim_diff;
   3302 							n_dst_coords = 3;
   3303 						}
   3304 
   3305 						if (1 == src_dim_diff)
   3306 						{
   3307 							src_coord[1] = 1;
   3308 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS
   3309 							n_src_coords = 2;
   3310 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */
   3311 						}
   3312 						else if (1 < src_dim_diff)
   3313 						{
   3314 							src_coord[1] = src_dim_diff / 2;
   3315 							src_coord[2] = src_dim_diff;
   3316 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS
   3317 							n_src_coords = 3;
   3318 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */
   3319 						}
   3320 
   3321 						testCase test_case = {
   3322 							{									/* m_dst */
   3323 							  dst_target, dst_image_dimmension, /* width */
   3324 							  dst_image_dimmension,				/* height */
   3325 							  dst_level, dst_internal_format, dst_format, dst_type },
   3326 							0,									/* dst_x */
   3327 							0,									/* dst_y */
   3328 							{									/* m_src */
   3329 							  src_target, src_image_dimmension, /* width */
   3330 							  src_image_dimmension,				/* height */
   3331 							  src_level, src_internal_format, src_format, src_type },
   3332 							0,				   /* src_x */
   3333 							0,				   /* src_y */
   3334 							region_dimmension, /* width */
   3335 							region_dimmension, /* height */
   3336 						};
   3337 
   3338 #if COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS
   3339 						for (GLuint src_x = 0; src_x < n_src_coords; ++src_x)
   3340 						{
   3341 							for (GLuint src_y = 0; src_y < n_src_coords; ++src_y)
   3342 							{
   3343 								for (GLuint dst_x = 0; dst_x < n_dst_coords; ++dst_x)
   3344 								{
   3345 									for (GLuint dst_y = 0; dst_y < n_dst_coords; ++dst_y)
   3346 									{
   3347 										test_case.m_dst_x = dst_coord[dst_x];
   3348 										test_case.m_dst_y = dst_coord[dst_y];
   3349 										test_case.m_src_x = src_coord[src_x];
   3350 										test_case.m_src_y = src_coord[src_y];
   3351 
   3352 										m_test_cases.push_back(test_case);
   3353 									}
   3354 								}
   3355 							}
   3356 						}
   3357 #else  /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */
   3358 						test_case.m_dst_x = dst_coord[n_dst_coords - 1];
   3359 						test_case.m_dst_y = dst_coord[n_dst_coords - 1];
   3360 						test_case.m_src_x = src_coord[0];
   3361 						test_case.m_src_y = src_coord[0];
   3362 
   3363 						m_test_cases.push_back(test_case);
   3364 #endif /* COPY_IMAGE_FUNCTIONAL_TEST_ENABLE_ALL_REG_POS */
   3365 
   3366 						/* Whole image, for non 7x7 */
   3367 						if ((dst_image_dimmension == src_image_dimmension) &&
   3368 							(image_dimmensions[0] != dst_image_dimmension))
   3369 						{
   3370 							test_case.m_dst_x  = 0;
   3371 							test_case.m_dst_y  = 0;
   3372 							test_case.m_src_x  = 0;
   3373 							test_case.m_src_y  = 0;
   3374 							test_case.m_width  = dst_image_dimmension;
   3375 							test_case.m_height = dst_image_dimmension;
   3376 
   3377 							m_test_cases.push_back(test_case);
   3378 						}
   3379 					}
   3380 				}
   3381 			}
   3382 		}
   3383 	}
   3384 }
   3385 
   3386 /** Prepare texture
   3387  *
   3388  * @param desc       Descriptor
   3389  * @param pixels     Image data
   3390  * @param out_buf_id Id of buffer used by texture buffer
   3391  *
   3392  * @return Name of iamge
   3393  **/
   3394 GLuint FunctionalTest::prepareTexture(const targetDesc& desc, const GLubyte** pixels, GLuint& out_buf_id)
   3395 {
   3396 	GLuint name = Utils::generateTexture(m_context, desc.m_target);
   3397 
   3398 	if (false == Utils::isTargetMultilevel(desc.m_target))
   3399 	{
   3400 		Utils::prepareTexture(m_context, name, desc.m_target, desc.m_internal_format, desc.m_format, desc.m_type,
   3401 							  0 /* level */, desc.m_width, desc.m_height,
   3402 							  FUNCTIONAL_TEST_N_LAYERS /* depth - 12 for multilayered, 1D and 2D will ignore that */,
   3403 							  pixels[0], out_buf_id);
   3404 
   3405 		Utils::makeTextureComplete(m_context, desc.m_target, name, 0 /* base */, 0 /* max */);
   3406 	}
   3407 	else
   3408 	{
   3409 		/* Calculate dimmensions */
   3410 		GLuint heights[FUNCTIONAL_TEST_N_LEVELS];
   3411 		GLuint widths[FUNCTIONAL_TEST_N_LEVELS];
   3412 		GLuint depths[FUNCTIONAL_TEST_N_LEVELS];
   3413 
   3414 		calculateDimmensions(desc.m_target, desc.m_level, desc.m_width, desc.m_height, widths, heights, depths);
   3415 
   3416 		for (GLuint level = 0; level < FUNCTIONAL_TEST_N_LEVELS; ++level)
   3417 		{
   3418 			Utils::prepareTexture(m_context, name, desc.m_target, desc.m_internal_format, desc.m_format, desc.m_type,
   3419 								  level, widths[level], heights[level], depths[level], pixels[level], out_buf_id);
   3420 
   3421 			Utils::makeTextureComplete(m_context, desc.m_target, name, 0 /* base */, 2 /* max */);
   3422 		}
   3423 	}
   3424 
   3425 	return name;
   3426 }
   3427 
   3428 /** Verify copy operation
   3429  *
   3430  * @param test_case  Test case
   3431  * @param dst_layer  First layer modified by copy
   3432  * @param dst_pixels Origiranl data of destination image
   3433  * @param src_layer  First layer read by copy
   3434  * @param src_pixels Original data of source image
   3435  * @param depth      Number of copied layers
   3436  *
   3437  * @return true if everything is as expected, false otherwise
   3438  **/
   3439 bool FunctionalTest::verify(const testCase& test_case, GLuint dst_layer, const GLubyte** dst_pixels, GLuint src_layer,
   3440 							const GLubyte** src_pixels, GLuint depth)
   3441 {
   3442 	const bool			 is_dst_multi_level = Utils::isTargetMultilevel(test_case.m_dst.m_target);
   3443 	const bool			 is_src_multi_level = Utils::isTargetMultilevel(test_case.m_src.m_target);
   3444 	const GLuint		 dst_level			= test_case.m_dst.m_level;
   3445 	std::vector<GLubyte> dst_level_data;
   3446 	const GLuint		 dst_pixel_size = Utils::getPixelSizeForFormat(test_case.m_dst.m_internal_format);
   3447 	targetDesc			 src_desc		= test_case.m_src;
   3448 	const GLuint		 src_level		= src_desc.m_level;
   3449 	std::vector<GLubyte> src_level_data;
   3450 	const GLuint		 src_pixel_size = Utils::getPixelSizeForFormat(src_desc.m_internal_format);
   3451 
   3452 	if (0 != m_rb_name)
   3453 	{
   3454 		src_desc.m_target = GL_TEXTURE_2D;
   3455 	}
   3456 
   3457 	/* Calculate storage requirements */
   3458 	GLuint dst_req_mem_per_layer[FUNCTIONAL_TEST_N_LEVELS];
   3459 	GLuint dst_heights[FUNCTIONAL_TEST_N_LEVELS];
   3460 	GLuint dst_widths[FUNCTIONAL_TEST_N_LEVELS];
   3461 	GLuint dst_depths[FUNCTIONAL_TEST_N_LEVELS];
   3462 	GLuint src_req_mem_per_layer[FUNCTIONAL_TEST_N_LEVELS];
   3463 	GLuint src_heights[FUNCTIONAL_TEST_N_LEVELS];
   3464 	GLuint src_widths[FUNCTIONAL_TEST_N_LEVELS];
   3465 	GLuint src_depths[FUNCTIONAL_TEST_N_LEVELS];
   3466 
   3467 	calculateDimmensions(test_case.m_dst.m_target, dst_level, test_case.m_dst.m_width, test_case.m_dst.m_height,
   3468 						 dst_widths, dst_heights, dst_depths);
   3469 
   3470 	calculateDimmensions(src_desc.m_target, src_level, src_desc.m_width, src_desc.m_height, src_widths, src_heights,
   3471 						 src_depths);
   3472 
   3473 	for (GLuint i = 0; i < FUNCTIONAL_TEST_N_LEVELS; ++i)
   3474 	{
   3475 		dst_req_mem_per_layer[i] = dst_widths[i] * dst_heights[i] * dst_pixel_size;
   3476 		src_req_mem_per_layer[i] = src_widths[i] * src_heights[i] * src_pixel_size;
   3477 	}
   3478 
   3479 	/* Prepare storage, use 0 level as it is the biggest one */
   3480 	dst_level_data.resize(dst_req_mem_per_layer[0] * dst_depths[0]);
   3481 	src_level_data.resize(src_req_mem_per_layer[0] * src_depths[0]);
   3482 
   3483 	/* Verification of contents
   3484 	 * - source image                                           - expect no modification
   3485 	 * - destination image, mipmap before and after dst_level   - expect no modification
   3486 	 * - destination image, mipmap at dst_level:
   3487 	 *   * layers after dst_layer + depth                       - expect no modification
   3488 	 *   * layers <0, dst_layer + depth>                        - expect that contents at selected region were copied
   3489 	 */
   3490 
   3491 	/* Check if source image was not modified */
   3492 	{
   3493 		const GLuint n_levels = (true == is_src_multi_level) ? FUNCTIONAL_TEST_N_LEVELS : 1;
   3494 
   3495 		for (GLuint level = 0; level < n_levels; ++level)
   3496 		{
   3497 			getPixels(m_src_tex_name, src_desc, level, &src_level_data[0]);
   3498 
   3499 			for (GLuint layer = 0; layer < src_depths[level]; ++layer)
   3500 			{
   3501 				if (false == compareImages(src_desc, src_pixels[level], 0, 0, layer, level, src_desc,
   3502 										   &src_level_data[0], 0, 0, layer, level, src_widths[level],
   3503 										   src_heights[level]))
   3504 				{
   3505 					m_context.getTestContext().getLog()
   3506 						<< tcu::TestLog::Message
   3507 						<< "CopyImageSubData modified contents of source image. Original data: left."
   3508 						<< tcu::TestLog::EndMessage;
   3509 					return false;
   3510 				}
   3511 			}
   3512 		}
   3513 	}
   3514 
   3515 	/* Check if contents of destination at levels != dst_level were not modified */
   3516 	{
   3517 		const GLuint n_levels = (true == is_dst_multi_level) ? FUNCTIONAL_TEST_N_LEVELS : 1;
   3518 
   3519 		for (GLuint level = 0; level < n_levels; ++level)
   3520 		{
   3521 			if (dst_level == level)
   3522 			{
   3523 				continue;
   3524 			}
   3525 
   3526 			getPixels(m_dst_tex_name, test_case.m_dst, level, &dst_level_data[0]);
   3527 
   3528 			for (GLuint layer = 0; layer < dst_depths[level]; ++layer)
   3529 			{
   3530 				if (false == compareImages(test_case.m_dst, dst_pixels[level], 0, 0, layer, level, test_case.m_dst,
   3531 										   &dst_level_data[0], 0, 0, layer, level, dst_widths[level],
   3532 										   dst_heights[level]))
   3533 				{
   3534 					m_context.getTestContext().getLog()
   3535 						<< tcu::TestLog::Message
   3536 						<< "CopyImageSubData modified contents of wrong mipmap level. Original data: left."
   3537 						<< tcu::TestLog::EndMessage;
   3538 
   3539 					return false;
   3540 				}
   3541 			}
   3542 		}
   3543 	}
   3544 
   3545 	/* Check contents of modified level */
   3546 	{
   3547 		getPixels(m_dst_tex_name, test_case.m_dst, dst_level, &dst_level_data[0]);
   3548 
   3549 		/* Check anything after dst_layer + depth */
   3550 		{
   3551 			for (GLuint layer = dst_layer + depth; layer < dst_depths[dst_level]; ++layer)
   3552 			{
   3553 				if (false == compareImages(test_case.m_dst, dst_pixels[dst_level], 0, 0, layer, dst_level,
   3554 										   test_case.m_dst, &dst_level_data[0], 0, 0, layer, dst_level,
   3555 										   dst_widths[dst_level], dst_heights[dst_level]))
   3556 				{
   3557 					m_context.getTestContext().getLog()
   3558 						<< tcu::TestLog::Message
   3559 						<< "CopyImageSubData modified contents of wrong layer. Original data: left."
   3560 						<< tcu::TestLog::EndMessage;
   3561 
   3562 					return false;
   3563 				}
   3564 			}
   3565 		}
   3566 
   3567 		/* Check modified layers */
   3568 		for (GLuint layer = 0; layer < depth; ++layer)
   3569 		{
   3570 			/* Check contents outside of copied region */
   3571 			{
   3572 				GLuint n_regions	 = 0;
   3573 				GLuint regions[4][4] = { { 0 } };
   3574 
   3575 				getCleanRegions(test_case, dst_level, regions, n_regions);
   3576 
   3577 				for (GLuint region = 0; region < n_regions; ++region)
   3578 				{
   3579 					const GLuint x = regions[region][0];
   3580 					const GLuint y = regions[region][1];
   3581 					const GLuint w = regions[region][2];
   3582 					const GLuint h = regions[region][3];
   3583 
   3584 					if (false == compareImages(test_case.m_dst, dst_pixels[dst_level], x, y, layer + dst_layer,
   3585 											   dst_level, test_case.m_dst, &dst_level_data[0], x, y, layer + dst_layer,
   3586 											   dst_level, w, h))
   3587 					{
   3588 						m_context.getTestContext().getLog()
   3589 							<< tcu::TestLog::Message
   3590 							<< "CopyImageSubData modified contents outside of copied region. Original data: left."
   3591 							<< tcu::TestLog::EndMessage;
   3592 						return false;
   3593 					}
   3594 				}
   3595 			}
   3596 
   3597 			/* Check contents of copied region */
   3598 			if (false == compareImages(test_case.m_dst, &dst_level_data[0], test_case.m_dst_x, test_case.m_dst_y,
   3599 									   layer + dst_layer, dst_level, src_desc, src_pixels[src_level], test_case.m_src_x,
   3600 									   test_case.m_src_y, layer + src_layer, src_level, test_case.m_width,
   3601 									   test_case.m_height))
   3602 			{
   3603 				m_context.getTestContext().getLog()
   3604 					<< tcu::TestLog::Message
   3605 					<< "CopyImageSubData stored invalid data in copied region. Destination data: left."
   3606 					<< tcu::TestLog::EndMessage;
   3607 				return false;
   3608 			}
   3609 		}
   3610 	}
   3611 
   3612 	return true;
   3613 }
   3614 
   3615 /* SmokeTest */
   3616 /* Constants */
   3617 const GLuint SmokeTest::m_width  = 16;
   3618 const GLuint SmokeTest::m_height = 16;
   3619 const GLuint SmokeTest::m_depth  = 1;
   3620 
   3621 /** Constructor
   3622  *
   3623  * @param context Text context
   3624  **/
   3625 SmokeTest::SmokeTest(deqp::Context& context)
   3626 	: TestCase(context, "smoke_test", "Test tries all formats and targets")
   3627 	, m_dst_buf_name(0)
   3628 	, m_dst_tex_name(0)
   3629 	, m_rb_name(0)
   3630 	, m_src_buf_name(0)
   3631 	, m_src_tex_name(0)
   3632 	, m_test_case_index(0)
   3633 {
   3634 	/* Iterate over valid targets */
   3635 	for (GLuint tgt_id = 0; tgt_id < s_n_valid_targets; ++tgt_id)
   3636 	{
   3637 		const GLenum target = s_valid_targets[tgt_id];
   3638 
   3639 		if (true == Utils::isTargetMultisampled(target))
   3640 		{
   3641 			continue;
   3642 		}
   3643 
   3644 		const testCase test_case = { target, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT };
   3645 
   3646 		m_test_cases.push_back(test_case);
   3647 	}
   3648 
   3649 	/* Iterate over internal formats */
   3650 	for (GLuint fmt_id = 0; fmt_id < s_n_internal_formats; ++fmt_id)
   3651 	{
   3652 		const GLenum internal_format = s_internal_formats[fmt_id];
   3653 		const GLenum format			 = Utils::getFormat(internal_format);
   3654 		const GLenum type			 = Utils::getType(internal_format);
   3655 
   3656 		const testCase test_case = { GL_TEXTURE_2D, internal_format, format, type };
   3657 
   3658 		m_test_cases.push_back(test_case);
   3659 	}
   3660 }
   3661 
   3662 /** Cleans resources
   3663  *
   3664  **/
   3665 void SmokeTest::clean()
   3666 {
   3667 	const Functions& gl = m_context.getRenderContext().getFunctions();
   3668 
   3669 	/* Clean textures and buffers. Errors ignored */
   3670 	gl.deleteTextures(1, &m_dst_tex_name);
   3671 	gl.deleteTextures(1, &m_src_tex_name);
   3672 
   3673 	m_dst_tex_name = 0;
   3674 	m_src_tex_name = 0;
   3675 
   3676 	if (0 != m_dst_buf_name)
   3677 	{
   3678 		gl.deleteBuffers(1, &m_dst_buf_name);
   3679 		m_dst_buf_name = 0;
   3680 	}
   3681 
   3682 	if (0 != m_rb_name)
   3683 	{
   3684 		gl.deleteRenderbuffers(1, &m_rb_name);
   3685 		m_rb_name = 0;
   3686 	}
   3687 
   3688 	if (0 != m_src_buf_name)
   3689 	{
   3690 		gl.deleteBuffers(1, &m_src_buf_name);
   3691 		m_src_buf_name = 0;
   3692 	}
   3693 }
   3694 
   3695 /** Free memory allocated for images
   3696  *
   3697  * @param pixels Pointers to image data
   3698  **/
   3699 void SmokeTest::cleanPixels(GLubyte*& pixels) const
   3700 {
   3701 	if (0 == pixels)
   3702 	{
   3703 		return;
   3704 	}
   3705 
   3706 	delete[] pixels;
   3707 	pixels = 0;
   3708 }
   3709 
   3710 /** Compare two images
   3711  * @param test_case     Test case descriptor
   3712  * @param left_data     Data of left image
   3713  * @param right_data    Data of right image
   3714  *
   3715  * @return true if images are considered idenctial, false otherwise
   3716  **/
   3717 bool SmokeTest::compareImages(const testCase& test_case, const GLubyte* left_data, const GLubyte* right_data) const
   3718 {
   3719 	/* Constants */
   3720 	/* Sizes */
   3721 	const GLuint pixel_size = Utils::getPixelSizeForFormat(test_case.m_internal_format);
   3722 	const GLuint line_size  = pixel_size * m_width;
   3723 
   3724 	GLuint height = m_height;
   3725 
   3726 	if ((GL_TEXTURE_1D == test_case.m_target) || (GL_TEXTURE_1D_ARRAY == test_case.m_target))
   3727 	{
   3728 		height = 1;
   3729 	}
   3730 
   3731 	/* For each line */
   3732 	for (GLuint y = 0; y < height; ++y)
   3733 	{
   3734 		/* Offsets */
   3735 		const GLuint line_offset = y * line_size;
   3736 
   3737 		/* Pointers */
   3738 		const GLubyte* left_line_data  = left_data + line_offset;
   3739 		const GLubyte* right_line_data = right_data + line_offset;
   3740 
   3741 		/* For each pixel of region */
   3742 		for (GLuint x = 0; x < m_width; ++x)
   3743 		{
   3744 			/* Offsets */
   3745 			const GLuint pixel_offset = x * pixel_size;
   3746 
   3747 			/* Pointers */
   3748 			const GLubyte* left_pixel_data  = left_line_data + pixel_offset;
   3749 			const GLubyte* right_pixel_data = right_line_data + pixel_offset;
   3750 
   3751 			/* Compare */
   3752 			if (false == Utils::comparePixels(pixel_size, left_pixel_data, pixel_size, right_pixel_data))
   3753 			{
   3754 				if (false == Utils::unpackAndComaprePixels(
   3755 								 test_case.m_format, test_case.m_type, test_case.m_internal_format, left_pixel_data,
   3756 								 test_case.m_format, test_case.m_type, test_case.m_internal_format, right_pixel_data))
   3757 				{
   3758 					m_context.getTestContext().getLog()
   3759 						<< tcu::TestLog::Message << "Not matching pixels found. "
   3760 						<< "[" << x << ", " << y << "], off: " << left_pixel_data - left_data
   3761 						<< ". Data left: " << Utils::getPixelString(test_case.m_internal_format, left_pixel_data)
   3762 						<< ", right: " << Utils::getPixelString(test_case.m_internal_format, right_pixel_data)
   3763 						<< tcu::TestLog::EndMessage;
   3764 
   3765 					return false;
   3766 				}
   3767 			}
   3768 		}
   3769 	}
   3770 
   3771 	return true;
   3772 }
   3773 
   3774 /** Execute copyImageSubData for given test case and verify results
   3775  *
   3776  * @param test_case  Test case
   3777  * @param src_pixels Data of source image
   3778  *
   3779  * @return true if there is no error and results match expectations, false otherwise
   3780  **/
   3781 bool SmokeTest::copyAndVerify(const testCase& test_case, const GLubyte* src_pixels)
   3782 {
   3783 	GLenum			 error  = GL_NO_ERROR;
   3784 	const Functions& gl		= m_context.getRenderContext().getFunctions();
   3785 	bool			 result = false;
   3786 
   3787 	/* Copy and verification */
   3788 	{
   3789 		if (0 == m_rb_name)
   3790 		{
   3791 			GLuint height = m_height;
   3792 
   3793 			if ((GL_TEXTURE_1D == test_case.m_target) || (GL_TEXTURE_1D_ARRAY == test_case.m_target))
   3794 			{
   3795 				height = 1;
   3796 			}
   3797 
   3798 			gl.copyImageSubData(m_src_tex_name, test_case.m_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */,
   3799 								0 /* srcZ */, m_dst_tex_name, test_case.m_target, 0 /* dstLevel */, 0 /* dstX */,
   3800 								0 /* dstY */, 0 /* dstZ */, m_width, height, m_depth);
   3801 		}
   3802 		else /* Copy from src to rb and from rb to dst */
   3803 		{
   3804 			/* Src and rb shares differs only on target */
   3805 			gl.copyImageSubData(m_src_tex_name, GL_TEXTURE_2D, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */,
   3806 								0 /* srcZ */, m_rb_name, test_case.m_target, 0 /* dstLevel */, 0 /* dstX */,
   3807 								0 /* dstY */, 0 /* dstZ */, m_width, m_height, m_depth);
   3808 
   3809 			gl.copyImageSubData(m_rb_name, test_case.m_target, 0 /* dstLevel */, 0 /* dstX */, 0 /* dstY */,
   3810 								0 /* dstZ */, m_dst_tex_name, GL_TEXTURE_2D, 0 /* dstLevel */, 0 /* dstX */,
   3811 								0 /* dstY */, 0 /* dstZ */, m_width, m_height, m_depth);
   3812 		}
   3813 
   3814 		/* Verify generated error */
   3815 		error = gl.getError();
   3816 
   3817 		if (GL_NO_ERROR == error)
   3818 		{
   3819 			/* Verify copy results */
   3820 			result = verify(test_case, src_pixels);
   3821 		}
   3822 
   3823 		if ((GL_NO_ERROR != error) || (false == result))
   3824 		{
   3825 			m_context.getTestContext().getLog()
   3826 				<< tcu::TestLog::Message << "Failure. Target: " << glu::getTextureTargetStr(test_case.m_target)
   3827 				<< ". Format: " << glu::getInternalFormatParameterStr(test_case.m_internal_format)
   3828 				<< tcu::TestLog::EndMessage;
   3829 
   3830 			if (GL_NO_ERROR != error)
   3831 			{
   3832 				m_context.getTestContext().getLog() << tcu::TestLog::Message
   3833 													<< "Failed due to error: " << glu::getErrorStr(error)
   3834 													<< tcu::TestLog::EndMessage;
   3835 
   3836 				TCU_FAIL("Copy operation failed");
   3837 			}
   3838 
   3839 			return false;
   3840 		}
   3841 	}
   3842 
   3843 	return true;
   3844 }
   3845 
   3846 /** Get pixel data for image
   3847  *
   3848  * @param name       Name of image
   3849  * @param test_case  Test case descriptor
   3850  * @param out_pixels Pixels
   3851  **/
   3852 void SmokeTest::getPixels(GLuint name, const SmokeTest::testCase& test_case, GLubyte* out_pixels) const
   3853 {
   3854 	const Functions& gl		  = m_context.getRenderContext().getFunctions();
   3855 	GLenum			 tgt_bind = test_case.m_target;
   3856 	GLenum			 tgt_get  = test_case.m_target;
   3857 
   3858 	if (GL_RENDERBUFFER == test_case.m_target)
   3859 	{
   3860 		tgt_bind = GL_TEXTURE_2D;
   3861 		tgt_get  = GL_TEXTURE_2D;
   3862 	}
   3863 	else if (GL_TEXTURE_CUBE_MAP == test_case.m_target)
   3864 	{
   3865 		tgt_get = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
   3866 	}
   3867 
   3868 	gl.bindTexture(tgt_bind, name);
   3869 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   3870 
   3871 	gl.getTexImage(tgt_get, 0 /* level */, test_case.m_format, test_case.m_type, out_pixels);
   3872 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
   3873 
   3874 	gl.bindTexture(tgt_bind, 0);
   3875 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   3876 }
   3877 
   3878 /** Execute test
   3879  *
   3880  * @return CONTINUE as long there are more test case, STOP otherwise
   3881  **/
   3882 tcu::TestNode::IterateResult SmokeTest::iterate()
   3883 {
   3884 	GLubyte*					 dst_pixels = 0;
   3885 	const Functions&			 gl			= m_context.getRenderContext().getFunctions();
   3886 	tcu::TestNode::IterateResult it_result  = tcu::TestNode::STOP;
   3887 	bool						 result		= false;
   3888 	GLubyte*					 src_pixels = 0;
   3889 	const testCase&				 test_case  = m_test_cases[m_test_case_index];
   3890 
   3891 	gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
   3892 	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3893 	GLU_EXPECT_NO_ERROR(gl.getError(), "PixelStorei");
   3894 
   3895 	try
   3896 	{
   3897 		/* Prepare pixels */
   3898 		prepareDstPxls(test_case, dst_pixels);
   3899 		prepareSrcPxls(test_case, src_pixels);
   3900 
   3901 		/* Prepare textures */
   3902 		if (GL_RENDERBUFFER == test_case.m_target)
   3903 		{
   3904 			testCase desc	= test_case;
   3905 			GLuint   ignored = 0;
   3906 
   3907 			desc.m_target = GL_TEXTURE_2D;
   3908 
   3909 			m_rb_name	  = prepareTexture(test_case, 0 /* pixels */, ignored /* buffer name */);
   3910 			m_dst_tex_name = prepareTexture(desc, dst_pixels, m_dst_buf_name);
   3911 			m_src_tex_name = prepareTexture(desc, src_pixels, m_src_buf_name);
   3912 		}
   3913 		else
   3914 		{
   3915 			m_dst_tex_name = prepareTexture(test_case, dst_pixels, m_dst_buf_name);
   3916 			m_src_tex_name = prepareTexture(test_case, src_pixels, m_src_buf_name);
   3917 		}
   3918 
   3919 		/* Copy images and verify results */
   3920 		result = copyAndVerify(test_case, src_pixels);
   3921 	}
   3922 	catch (tcu::Exception& exc)
   3923 	{
   3924 		clean();
   3925 		cleanPixels(dst_pixels);
   3926 		cleanPixels(src_pixels);
   3927 		throw exc;
   3928 	}
   3929 
   3930 	/* Free resources */
   3931 	clean();
   3932 	cleanPixels(dst_pixels);
   3933 	cleanPixels(src_pixels);
   3934 
   3935 	/* Set result */
   3936 	if (true == result)
   3937 	{
   3938 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3939 
   3940 		/* Increase index */
   3941 		m_test_case_index += 1;
   3942 
   3943 		/* Are there any test cases left */
   3944 		if (m_test_cases.size() > m_test_case_index)
   3945 		{
   3946 			it_result = tcu::TestNode::CONTINUE;
   3947 		}
   3948 	}
   3949 	else
   3950 	{
   3951 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failure. " << tcu::TestLog::EndMessage;
   3952 
   3953 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3954 	}
   3955 
   3956 	/* Done */
   3957 	return it_result;
   3958 }
   3959 
   3960 /** Prepare data for destination image
   3961  *
   3962  * @param test_case  Test case descriptor
   3963  * @param out_pixels Pointer to image data
   3964  **/
   3965 void SmokeTest::prepareDstPxls(const SmokeTest::testCase& test_case, GLubyte*& out_pixels) const
   3966 {
   3967 	static const GLuint n_pixels_per_layer = m_width * m_height;
   3968 
   3969 	const GLenum internal_format = test_case.m_internal_format;
   3970 	const GLuint n_layers		 = (GL_TEXTURE_CUBE_MAP_ARRAY != test_case.m_target) ? m_depth : 6;
   3971 	const GLuint n_pixels		 = n_pixels_per_layer * n_layers;
   3972 	const GLuint pixel_size		 = Utils::getPixelSizeForFormat(internal_format);
   3973 	const GLuint req_memory		 = pixel_size * n_pixels;
   3974 	const GLenum type			 = test_case.m_type;
   3975 
   3976 	/* Prepare storage */
   3977 	out_pixels = new GLubyte[req_memory];
   3978 
   3979 	if (0 == out_pixels)
   3980 	{
   3981 		TCU_FAIL("Memory allocation failed");
   3982 	}
   3983 
   3984 	memset(out_pixels, 0, req_memory);
   3985 
   3986 	/* Fill pixels */
   3987 	for (GLuint j = 0; j < n_pixels; ++j)
   3988 	{
   3989 		GLubyte* pixel_data = out_pixels + j * pixel_size;
   3990 
   3991 		Utils::packPixel(internal_format, type, 1.0, 1.0, 1.0, 1.0, pixel_data);
   3992 	}
   3993 }
   3994 
   3995 /** Prepare data for source image
   3996  *
   3997  * @param test_case  Test case descriptor
   3998  * @param out_pixels Pointer to image data
   3999  **/
   4000 void SmokeTest::prepareSrcPxls(const SmokeTest::testCase& test_case, GLubyte*& out_pixels) const
   4001 {
   4002 	static const GLuint n_pixels_per_layer = m_width * m_height;
   4003 
   4004 	const GLenum internal_format = test_case.m_internal_format;
   4005 	const GLuint n_layers		 = (GL_TEXTURE_CUBE_MAP_ARRAY != test_case.m_target) ? m_depth : 6;
   4006 	const GLuint n_pixels		 = n_pixels_per_layer * n_layers;
   4007 	const GLuint pixel_size		 = Utils::getPixelSizeForFormat(internal_format);
   4008 	const GLuint layer_size		 = pixel_size * n_pixels_per_layer;
   4009 	const GLuint line_size		 = pixel_size * m_width;
   4010 	const GLuint req_memory		 = pixel_size * n_pixels;
   4011 	const GLenum type			 = test_case.m_type;
   4012 
   4013 	/* Prepare storage */
   4014 	out_pixels = new GLubyte[req_memory];
   4015 
   4016 	if (0 == out_pixels)
   4017 	{
   4018 		TCU_FAIL("Memory allocation failed");
   4019 	}
   4020 
   4021 	memset(out_pixels, 0, req_memory);
   4022 
   4023 	/* Fill pixels */
   4024 	for (GLuint layer = 0; layer < n_layers; ++layer)
   4025 	{
   4026 		const GLuint layer_offset = layer * layer_size;
   4027 
   4028 		GLubyte* layer_data = out_pixels + layer_offset;
   4029 
   4030 		for (GLuint y = 0; y < m_height; ++y)
   4031 		{
   4032 			const GLuint line_offset = line_size * y;
   4033 
   4034 			GLubyte* line_data = layer_data + line_offset;
   4035 
   4036 			for (GLuint x = 0; x < m_width; ++x)
   4037 			{
   4038 				const GLuint pixel_offset = x * pixel_size;
   4039 
   4040 				GLubyte* pixel_data = line_data + pixel_offset;
   4041 
   4042 				/* 255 is max ubyte. 1/15.9375 = 16/255 */
   4043 				const GLdouble red   = ((GLdouble)x) / 255.0 + (((GLdouble)y) / 15.9375);
   4044 				const GLdouble green = ((GLdouble)layer) / 255.0 + (1.0 / 15.9375);
   4045 				const GLdouble blue  = 0.125;
   4046 				const GLdouble alpha = 1.0; /* This value has special meaning for some internal_formats */
   4047 
   4048 				Utils::packPixel(internal_format, type, red, green, blue, alpha, pixel_data);
   4049 			}
   4050 		}
   4051 	}
   4052 }
   4053 
   4054 /** Prepare texture
   4055  *
   4056  * @param desc       Descriptor
   4057  * @param pixels     Image data
   4058  * @param out_buf_id Id of buffer used by texture buffer
   4059  *
   4060  * @return Name of iamge
   4061  **/
   4062 GLuint SmokeTest::prepareTexture(const testCase& test_case, const GLubyte* pixels, GLuint& out_buf_id)
   4063 {
   4064 	const GLuint n_layers = (GL_TEXTURE_CUBE_MAP_ARRAY != test_case.m_target) ? m_depth : 6;
   4065 	GLuint		 name	 = Utils::generateTexture(m_context, test_case.m_target);
   4066 
   4067 	Utils::prepareTexture(m_context, name, test_case.m_target, test_case.m_internal_format, test_case.m_format,
   4068 						  test_case.m_type, 0 /* level */, m_width, m_height, n_layers, pixels, out_buf_id);
   4069 
   4070 	Utils::makeTextureComplete(m_context, test_case.m_target, name, 0 /* base */, 0 /* max */);
   4071 
   4072 	return name;
   4073 }
   4074 
   4075 /** Verify copy operation
   4076  *
   4077  * @param test_case  Test case
   4078  * @param src_pixels Original data of source image
   4079  *
   4080  * @return true if everything is as expected, false otherwise
   4081  **/
   4082 bool SmokeTest::verify(const testCase& test_case, const GLubyte* src_pixels)
   4083 {
   4084 	std::vector<GLubyte> dst_data;
   4085 	const GLuint		 n_layers   = (GL_TEXTURE_CUBE_MAP_ARRAY != test_case.m_target) ? m_depth : 6;
   4086 	const GLuint		 pixel_size = Utils::getPixelSizeForFormat(test_case.m_internal_format);
   4087 	const GLuint		 line_size  = pixel_size * m_width;
   4088 	const GLuint		 req_memory = line_size * m_height * n_layers;
   4089 	std::vector<GLubyte> src_data;
   4090 
   4091 	/* Prepare storage */
   4092 	dst_data.resize(req_memory);
   4093 	src_data.resize(req_memory);
   4094 
   4095 	/* Check if source image was not modified */
   4096 	{
   4097 		getPixels(m_src_tex_name, test_case, &src_data[0]);
   4098 
   4099 		if (false == compareImages(test_case, src_pixels, &src_data[0]))
   4100 		{
   4101 			m_context.getTestContext().getLog()
   4102 				<< tcu::TestLog::Message << "CopyImageSubData modified contents of source image. Original data: left."
   4103 				<< tcu::TestLog::EndMessage;
   4104 			return false;
   4105 		}
   4106 	}
   4107 
   4108 	/* Check contents of destination image */
   4109 	{
   4110 		getPixels(m_dst_tex_name, test_case, &dst_data[0]);
   4111 
   4112 		if (false == compareImages(test_case, src_pixels, &dst_data[0]))
   4113 		{
   4114 			m_context.getTestContext().getLog()
   4115 				<< tcu::TestLog::Message
   4116 				<< "CopyImageSubData stored invalid contents in destination image. Source data: left."
   4117 				<< tcu::TestLog::EndMessage;
   4118 
   4119 			return false;
   4120 		}
   4121 	}
   4122 
   4123 	return true;
   4124 }
   4125 
   4126 /* InvalidTargetTest */
   4127 /** Constructor
   4128  *
   4129  * @param context Text context
   4130  **/
   4131 InvalidTargetTest::InvalidTargetTest(deqp::Context& context)
   4132 	: TestCase(context, "invalid_target",
   4133 			   "Test verifies if INVALID_ENUM is generated when invalid target is provided to CopySubImageData")
   4134 	, m_dst_buf_name(0)
   4135 	, m_dst_tex_name(0)
   4136 	, m_src_buf_name(0)
   4137 	, m_src_tex_name(0)
   4138 	, m_test_case_index(0)
   4139 {
   4140 
   4141 	/* Valid source, valid dst */
   4142 	for (GLuint src = 0; src < s_n_valid_targets; ++src)
   4143 	{
   4144 		for (GLuint dst = 0; dst < s_n_valid_targets; ++dst)
   4145 		{
   4146 			const GLenum src_target = s_valid_targets[src];
   4147 			const GLenum dst_target = s_valid_targets[dst];
   4148 			testCase	 test_case  = { src_target, dst_target, GL_NO_ERROR };
   4149 
   4150 			if (Utils::isTargetMultisampled(dst_target) != Utils::isTargetMultisampled(src_target))
   4151 			{
   4152 				test_case.m_expected_result = GL_INVALID_OPERATION;
   4153 			}
   4154 
   4155 			m_test_cases.push_back(test_case);
   4156 		}
   4157 	}
   4158 
   4159 	/* Invalid source, invalid dst */
   4160 	for (GLuint src = 0; src < s_n_invalid_targets; ++src)
   4161 	{
   4162 		for (GLuint dst = 0; dst < s_n_invalid_targets; ++dst)
   4163 		{
   4164 			const GLenum   src_target = s_invalid_targets[src];
   4165 			const GLenum   dst_target = s_invalid_targets[dst];
   4166 			const testCase test_case  = { src_target, dst_target, GL_INVALID_ENUM };
   4167 
   4168 			m_test_cases.push_back(test_case);
   4169 		}
   4170 	}
   4171 
   4172 	/* Invalid source, valid dst */
   4173 	for (GLuint src = 0; src < s_n_invalid_targets; ++src)
   4174 	{
   4175 		for (GLuint dst = 0; dst < s_n_valid_targets; ++dst)
   4176 		{
   4177 			const GLenum   src_target = s_invalid_targets[src];
   4178 			const GLenum   dst_target = s_valid_targets[dst];
   4179 			const testCase test_case  = { src_target, dst_target, GL_INVALID_ENUM };
   4180 
   4181 			m_test_cases.push_back(test_case);
   4182 		}
   4183 	}
   4184 
   4185 	/* Valid source, invalid dst */
   4186 	for (GLuint src = 0; src < s_n_valid_targets; ++src)
   4187 	{
   4188 		for (GLuint dst = 0; dst < s_n_invalid_targets; ++dst)
   4189 		{
   4190 			const GLenum   src_target = s_valid_targets[src];
   4191 			const GLenum   dst_target = s_invalid_targets[dst];
   4192 			const testCase test_case  = { src_target, dst_target, GL_INVALID_ENUM };
   4193 
   4194 			m_test_cases.push_back(test_case);
   4195 		}
   4196 	}
   4197 }
   4198 
   4199 /** Execute test
   4200  *
   4201  * @return CONTINUE as long there are more test case, STOP otherwise
   4202  **/
   4203 tcu::TestNode::IterateResult InvalidTargetTest::iterate()
   4204 {
   4205 	GLenum						 error	 = GL_NO_ERROR;
   4206 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   4207 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   4208 	bool						 result	= false;
   4209 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   4210 
   4211 	try
   4212 	{
   4213 		/* Prepare textures */
   4214 		m_dst_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_dst_target, GL_RGBA8, GL_RGBA,
   4215 												  GL_UNSIGNED_BYTE, m_dst_buf_name);
   4216 		m_src_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_src_target, GL_RGBA8, GL_RGBA,
   4217 												  GL_UNSIGNED_BYTE, m_src_buf_name);
   4218 
   4219 		/* Make textures complete */
   4220 		Utils::makeTextureComplete(m_context, test_case.m_dst_target, m_dst_tex_name, 0 /* base */, 0 /* max */);
   4221 		Utils::makeTextureComplete(m_context, test_case.m_src_target, m_src_tex_name, 0 /* base */, 0 /* max */);
   4222 	}
   4223 	catch (tcu::Exception& exc)
   4224 	{
   4225 		clean();
   4226 		throw exc;
   4227 	}
   4228 
   4229 	/* Execute CopyImageSubData */
   4230 	gl.copyImageSubData(m_src_tex_name, test_case.m_src_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */,
   4231 						0 /* srcZ */, m_dst_tex_name, test_case.m_dst_target, 0 /* dstLevel */, 0 /* dstX */,
   4232 						0 /* dstY */, 0 /* dstZ */, 1 /* srcWidth */, 1 /* srcHeight */, 1 /* srcDepth */);
   4233 
   4234 	/* Verify generated error */
   4235 	error  = gl.getError();
   4236 	result = (test_case.m_expected_result == error);
   4237 
   4238 	/* Free resources */
   4239 	clean();
   4240 
   4241 	/* Set result */
   4242 	if (true == result)
   4243 	{
   4244 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4245 
   4246 		/* Increase index */
   4247 		m_test_case_index += 1;
   4248 
   4249 		/* Are there any test cases left */
   4250 		if (m_test_cases.size() > m_test_case_index)
   4251 		{
   4252 			it_result = tcu::TestNode::CONTINUE;
   4253 		}
   4254 	}
   4255 	else
   4256 	{
   4257 		m_context.getTestContext().getLog()
   4258 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   4259 			<< " got: " << glu::getErrorStr(error)
   4260 			<< ". Source target: " << glu::getTextureTargetStr(test_case.m_src_target)
   4261 			<< ", destination target: " << glu::getTextureTargetStr(test_case.m_dst_target) << tcu::TestLog::EndMessage;
   4262 
   4263 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4264 	}
   4265 
   4266 	/* Done */
   4267 	return it_result;
   4268 }
   4269 
   4270 /** Cleans resources
   4271  *
   4272  **/
   4273 void InvalidTargetTest::clean()
   4274 {
   4275 	const Functions& gl		   = m_context.getRenderContext().getFunctions();
   4276 	const testCase&  test_case = m_test_cases[m_test_case_index];
   4277 
   4278 	/* Clean textures and buffers. Errors ignored */
   4279 	Utils::deleteTexture(m_context, test_case.m_dst_target, m_dst_tex_name);
   4280 	Utils::deleteTexture(m_context, test_case.m_src_target, m_src_tex_name);
   4281 
   4282 	m_dst_tex_name = 0;
   4283 	m_src_tex_name = 0;
   4284 
   4285 	if (0 != m_dst_buf_name)
   4286 	{
   4287 		gl.deleteBuffers(1, &m_dst_buf_name);
   4288 		m_dst_buf_name = 0;
   4289 	}
   4290 
   4291 	if (0 != m_src_buf_name)
   4292 	{
   4293 		gl.deleteBuffers(1, &m_src_buf_name);
   4294 		m_src_buf_name = 0;
   4295 	}
   4296 }
   4297 
   4298 /* TargetMissMatchTest */
   4299 /** Constructor
   4300  *
   4301  * @param context Text context
   4302  **/
   4303 TargetMissMatchTest::TargetMissMatchTest(deqp::Context& context)
   4304 	: TestCase(
   4305 		  context, "target_miss_match",
   4306 		  "Test verifies if INVALID_ENUM is generated when target provided to CopySubImageData does not match texture")
   4307 	, m_dst_buf_name(0)
   4308 	, m_dst_tex_name(0)
   4309 	, m_src_buf_name(0)
   4310 	, m_src_tex_name(0)
   4311 	, m_test_case_index(0)
   4312 {
   4313 	/* Wrong dst target */
   4314 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4315 	{
   4316 		for (GLuint dst = 0; dst < s_n_valid_targets; ++dst)
   4317 		{
   4318 			const GLenum dst_target = s_valid_targets[dst];
   4319 			const GLenum src_target = s_valid_targets[target];
   4320 			const GLenum tex_target = s_valid_targets[target];
   4321 			testCase	 test_case  = { tex_target, src_target, dst_target, GL_INVALID_ENUM };
   4322 
   4323 			/* Skip renderbuffers */
   4324 			if ((GL_RENDERBUFFER == tex_target) || (GL_RENDERBUFFER == dst_target) || (GL_RENDERBUFFER == src_target))
   4325 			{
   4326 				continue;
   4327 			}
   4328 
   4329 			/* Valid case */
   4330 			if (dst_target == tex_target)
   4331 			{
   4332 				test_case.m_expected_result = GL_NO_ERROR;
   4333 			}
   4334 
   4335 			/* Skip cases with multisampling conflict */
   4336 			if (Utils::isTargetMultisampled(dst_target) != Utils::isTargetMultisampled(src_target))
   4337 			{
   4338 				continue;
   4339 			}
   4340 
   4341 			m_test_cases.push_back(test_case);
   4342 		}
   4343 	}
   4344 
   4345 	/* Wrong src target */
   4346 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4347 	{
   4348 		for (GLuint src = 0; src < s_n_valid_targets; ++src)
   4349 		{
   4350 			const GLenum dst_target = s_valid_targets[target];
   4351 			const GLenum src_target = s_valid_targets[src];
   4352 			const GLenum tex_target = s_valid_targets[target];
   4353 			testCase	 test_case  = { tex_target, src_target, dst_target, GL_INVALID_ENUM };
   4354 
   4355 			/* Skip renderbuffers */
   4356 			if ((GL_RENDERBUFFER == tex_target) || (GL_RENDERBUFFER == dst_target) || (GL_RENDERBUFFER == src_target))
   4357 			{
   4358 				continue;
   4359 			}
   4360 
   4361 			/* Valid case */
   4362 			if (src_target == tex_target)
   4363 			{
   4364 				test_case.m_expected_result = GL_NO_ERROR;
   4365 			}
   4366 
   4367 			/* Skip cases with multisampling conflict */
   4368 			if (Utils::isTargetMultisampled(dst_target) != Utils::isTargetMultisampled(src_target))
   4369 			{
   4370 				continue;
   4371 			}
   4372 
   4373 			m_test_cases.push_back(test_case);
   4374 		}
   4375 	}
   4376 }
   4377 
   4378 /** Execute test
   4379  *
   4380  * @return CONTINUE as long there are more test case, STOP otherwise
   4381  **/
   4382 tcu::TestNode::IterateResult TargetMissMatchTest::iterate()
   4383 {
   4384 	GLenum						 error	 = GL_NO_ERROR;
   4385 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   4386 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   4387 	bool						 result	= false;
   4388 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   4389 
   4390 	try
   4391 	{
   4392 		/* Prepare textures */
   4393 		m_dst_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA,
   4394 												  GL_UNSIGNED_BYTE, m_dst_buf_name);
   4395 		m_src_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA,
   4396 												  GL_UNSIGNED_BYTE, m_src_buf_name);
   4397 
   4398 		/* Make textures complete */
   4399 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_dst_tex_name, 0 /* base */, 0 /* max */);
   4400 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_src_tex_name, 0 /* base */, 0 /* max */);
   4401 	}
   4402 	catch (tcu::Exception& exc)
   4403 	{
   4404 		clean();
   4405 		throw exc;
   4406 	}
   4407 
   4408 	/* Execute CopyImageSubData */
   4409 	gl.copyImageSubData(m_src_tex_name, test_case.m_src_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */,
   4410 						0 /* srcZ */, m_dst_tex_name, test_case.m_dst_target, 0 /* dstLevel */, 0 /* dstX */,
   4411 						0 /* dstY */, 0 /* dstZ */, 1 /* srcWidth */, 1 /* srcHeight */, 1 /* srcDepth */);
   4412 
   4413 	/* Verify generated error */
   4414 	error  = gl.getError();
   4415 	result = (test_case.m_expected_result == error);
   4416 
   4417 	/* Remove resources */
   4418 	clean();
   4419 
   4420 	if (true == result)
   4421 	{
   4422 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4423 
   4424 		/* Increase index */
   4425 		m_test_case_index += 1;
   4426 
   4427 		/* Are there any test cases left */
   4428 		if (m_test_cases.size() > m_test_case_index)
   4429 		{
   4430 			it_result = tcu::TestNode::CONTINUE;
   4431 		}
   4432 	}
   4433 	else
   4434 	{
   4435 		m_context.getTestContext().getLog()
   4436 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   4437 			<< " got: " << glu::getErrorStr(error)
   4438 			<< ". Texture target: " << glu::getTextureTargetStr(test_case.m_tex_target)
   4439 			<< ". Source target: " << glu::getTextureTargetStr(test_case.m_src_target)
   4440 			<< ", destination target: " << glu::getTextureTargetStr(test_case.m_dst_target) << tcu::TestLog::EndMessage;
   4441 
   4442 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4443 	}
   4444 
   4445 	/* Done */
   4446 	return it_result;
   4447 }
   4448 
   4449 /** Cleans resources
   4450  *
   4451  **/
   4452 void TargetMissMatchTest::clean()
   4453 {
   4454 	const Functions& gl = m_context.getRenderContext().getFunctions();
   4455 
   4456 	/* Clean textures and buffers. Errors ignored */
   4457 	gl.deleteTextures(1, &m_dst_tex_name);
   4458 	gl.deleteTextures(1, &m_src_tex_name);
   4459 
   4460 	m_dst_tex_name = 0;
   4461 	m_src_tex_name = 0;
   4462 
   4463 	if (0 != m_dst_buf_name)
   4464 	{
   4465 		gl.deleteBuffers(1, &m_dst_buf_name);
   4466 		m_dst_buf_name = 0;
   4467 	}
   4468 
   4469 	if (0 != m_src_buf_name)
   4470 	{
   4471 		gl.deleteBuffers(1, &m_src_buf_name);
   4472 		m_src_buf_name = 0;
   4473 	}
   4474 }
   4475 
   4476 /* TargetMissMatchTest */
   4477 /** Constructor
   4478  *
   4479  * @param context Text context
   4480  **/
   4481 IncompleteTexTest::IncompleteTexTest(deqp::Context& context)
   4482 	: TestCase(
   4483 		  context, "incomplete_tex",
   4484 		  "Test verifies if INVALID_OPERATION is generated when texture provided to CopySubImageData is incomplete")
   4485 	, m_dst_buf_name(0)
   4486 	, m_dst_tex_name(0)
   4487 	, m_src_buf_name(0)
   4488 	, m_src_tex_name(0)
   4489 	, m_test_case_index(0)
   4490 {
   4491 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4492 	{
   4493 		const GLenum tex_target = s_valid_targets[target];
   4494 		testCase	 test_case  = { tex_target, false, false, GL_INVALID_OPERATION };
   4495 
   4496 		/* Skip targets that are not multi level */
   4497 		if (false == Utils::isTargetMultilevel(tex_target))
   4498 		{
   4499 			continue;
   4500 		}
   4501 
   4502 		m_test_cases.push_back(test_case);
   4503 
   4504 		test_case.m_is_dst_complete = true;
   4505 		test_case.m_is_src_complete = false;
   4506 		m_test_cases.push_back(test_case);
   4507 
   4508 		test_case.m_is_dst_complete = false;
   4509 		test_case.m_is_src_complete = true;
   4510 		m_test_cases.push_back(test_case);
   4511 
   4512 		test_case.m_is_dst_complete = true;
   4513 		test_case.m_is_src_complete = true;
   4514 		test_case.m_expected_result = GL_NO_ERROR;
   4515 		m_test_cases.push_back(test_case);
   4516 	}
   4517 }
   4518 
   4519 /** Execute test
   4520  *
   4521  * @return CONTINUE as long there are more test case, STOP otherwise
   4522  **/
   4523 tcu::TestNode::IterateResult IncompleteTexTest::iterate()
   4524 {
   4525 	GLenum						 error	 = GL_NO_ERROR;
   4526 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   4527 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   4528 	bool						 result	= false;
   4529 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   4530 
   4531 	try
   4532 	{
   4533 		/* Prepare textures */
   4534 		m_dst_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA,
   4535 												  GL_UNSIGNED_BYTE, m_dst_buf_name);
   4536 		m_src_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA,
   4537 												  GL_UNSIGNED_BYTE, m_src_buf_name);
   4538 
   4539 		/* Make textures complete */
   4540 		if (true == test_case.m_is_dst_complete)
   4541 		{
   4542 			Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_dst_tex_name, 0 /* base */, 0 /* max */);
   4543 		}
   4544 
   4545 		if (true == test_case.m_is_src_complete)
   4546 		{
   4547 			Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_src_tex_name, 0 /* base */, 0 /* max */);
   4548 		}
   4549 	}
   4550 	catch (tcu::Exception& exc)
   4551 	{
   4552 		clean();
   4553 		throw exc;
   4554 	}
   4555 
   4556 	/* Execute CopyImageSubData */
   4557 	gl.copyImageSubData(m_src_tex_name, test_case.m_tex_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */,
   4558 						0 /* srcZ */, m_dst_tex_name, test_case.m_tex_target, 0 /* dstLevel */, 0 /* dstX */,
   4559 						0 /* dstY */, 0 /* dstZ */, 1 /* srcWidth */, 1 /* srcHeight */, 1 /* srcDepth */);
   4560 
   4561 	/* Verify generated error */
   4562 	error  = gl.getError();
   4563 	result = (test_case.m_expected_result == error);
   4564 
   4565 	/* Remove resources */
   4566 	clean();
   4567 
   4568 	if (true == result)
   4569 	{
   4570 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4571 
   4572 		/* Increase index */
   4573 		m_test_case_index += 1;
   4574 
   4575 		/* Are there any test cases left */
   4576 		if (m_test_cases.size() > m_test_case_index)
   4577 		{
   4578 			it_result = tcu::TestNode::CONTINUE;
   4579 		}
   4580 	}
   4581 	else
   4582 	{
   4583 		m_context.getTestContext().getLog()
   4584 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   4585 			<< " got: " << glu::getErrorStr(error)
   4586 			<< ". Texture target: " << glu::getTextureTargetStr(test_case.m_tex_target)
   4587 			<< ". Is source complete: " << test_case.m_is_src_complete
   4588 			<< ", is destination complete: " << test_case.m_is_dst_complete << tcu::TestLog::EndMessage;
   4589 
   4590 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4591 	}
   4592 
   4593 	/* Done */
   4594 	return it_result;
   4595 }
   4596 
   4597 /** Cleans resources
   4598  *
   4599  **/
   4600 void IncompleteTexTest::clean()
   4601 {
   4602 	const Functions& gl = m_context.getRenderContext().getFunctions();
   4603 
   4604 	/* Clean textures and buffers. Errors ignored */
   4605 	gl.deleteTextures(1, &m_dst_tex_name);
   4606 	gl.deleteTextures(1, &m_src_tex_name);
   4607 
   4608 	m_dst_tex_name = 0;
   4609 	m_src_tex_name = 0;
   4610 
   4611 	if (0 != m_dst_buf_name)
   4612 	{
   4613 		gl.deleteBuffers(1, &m_dst_buf_name);
   4614 		m_dst_buf_name = 0;
   4615 	}
   4616 
   4617 	if (0 != m_src_buf_name)
   4618 	{
   4619 		gl.deleteBuffers(1, &m_src_buf_name);
   4620 		m_src_buf_name = 0;
   4621 	}
   4622 }
   4623 
   4624 /* IncompatibleFormatsTest */
   4625 /** Constructor
   4626  *
   4627  * @param context Text context
   4628  **/
   4629 IncompatibleFormatsTest::IncompatibleFormatsTest(deqp::Context& context)
   4630 	: TestCase(
   4631 		  context, "incompatible_formats",
   4632 		  "Test verifies if INVALID_OPERATION is generated when textures provided to CopySubImageData are incompatible")
   4633 	, m_dst_buf_name(0)
   4634 	, m_dst_tex_name(0)
   4635 	, m_src_buf_name(0)
   4636 	, m_src_tex_name(0)
   4637 	, m_test_case_index(0)
   4638 {
   4639 	/* RGBA8UI vs RGBA16UI */
   4640 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4641 	{
   4642 		const GLenum tex_target = s_valid_targets[target];
   4643 
   4644 		testCase test_case = { tex_target,  GL_RGBA8UI,		 GL_RGBA_INTEGER,   GL_UNSIGNED_BYTE,
   4645 							   GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_INVALID_OPERATION };
   4646 
   4647 		/* Skip multisampled and rectangle targets */
   4648 		if (true == Utils::isTargetMultisampled(tex_target))
   4649 		{
   4650 			continue;
   4651 		}
   4652 
   4653 		m_test_cases.push_back(test_case);
   4654 	}
   4655 
   4656 	/* RGBA8UI vs RGBA32UI */
   4657 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4658 	{
   4659 		const GLenum tex_target = s_valid_targets[target];
   4660 
   4661 		testCase test_case = { tex_target,  GL_RGBA8UI,		 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
   4662 							   GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_INVALID_OPERATION };
   4663 
   4664 		/* Skip multisampled and rectangle targets */
   4665 		if (true == Utils::isTargetMultisampled(tex_target))
   4666 		{
   4667 			continue;
   4668 		}
   4669 
   4670 		m_test_cases.push_back(test_case);
   4671 	}
   4672 
   4673 	/* RGBA16UI vs RG16UI */
   4674 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4675 	{
   4676 		const GLenum tex_target = s_valid_targets[target];
   4677 
   4678 		testCase test_case = { tex_target, GL_RGBA16UI,   GL_RGBA_INTEGER,   GL_UNSIGNED_SHORT,
   4679 							   GL_RG16UI,  GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_INVALID_OPERATION };
   4680 
   4681 		/* Skip multisampled and rectangle targets */
   4682 		if (true == Utils::isTargetMultisampled(tex_target))
   4683 		{
   4684 			continue;
   4685 		}
   4686 
   4687 		m_test_cases.push_back(test_case);
   4688 	}
   4689 
   4690 	/* RGBA32UI vs RGBA32F */
   4691 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4692 	{
   4693 		const GLenum tex_target = s_valid_targets[target];
   4694 
   4695 		testCase test_case = { tex_target, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
   4696 							   GL_RGBA32F, GL_RGBA,		GL_FLOAT,		 GL_NO_ERROR };
   4697 
   4698 		/* Skip multisampled and rectangle targets */
   4699 		if (true == Utils::isTargetMultisampled(tex_target))
   4700 		{
   4701 			continue;
   4702 		}
   4703 
   4704 		m_test_cases.push_back(test_case);
   4705 	}
   4706 
   4707 	/* RGBA8 vs RGBA32F */
   4708 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4709 	{
   4710 		const GLenum tex_target = s_valid_targets[target];
   4711 
   4712 		testCase test_case = { tex_target, GL_RGBA8, GL_RGBA,  GL_UNSIGNED_BYTE,
   4713 							   GL_RGBA32F, GL_RGBA,  GL_FLOAT, GL_INVALID_OPERATION };
   4714 
   4715 		/* Skip multisampled and rectangle targets */
   4716 		if (true == Utils::isTargetMultisampled(tex_target))
   4717 		{
   4718 			continue;
   4719 		}
   4720 
   4721 		m_test_cases.push_back(test_case);
   4722 	}
   4723 }
   4724 
   4725 /** Execute test
   4726  *
   4727  * @return CONTINUE as long there are more test case, STOP otherwise
   4728  **/
   4729 tcu::TestNode::IterateResult IncompatibleFormatsTest::iterate()
   4730 {
   4731 	GLenum						 error	 = GL_NO_ERROR;
   4732 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   4733 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   4734 	bool						 result	= false;
   4735 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   4736 
   4737 	try
   4738 	{
   4739 		/* Prepare textures */
   4740 		m_dst_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, test_case.m_dst_internal_format,
   4741 												  test_case.m_dst_format, test_case.m_dst_type, m_dst_buf_name);
   4742 		m_src_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, test_case.m_src_internal_format,
   4743 												  test_case.m_src_format, test_case.m_src_type, m_src_buf_name);
   4744 
   4745 		/* Make textures complete */
   4746 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_dst_tex_name, 0 /* base */, 0 /* max */);
   4747 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_src_tex_name, 0 /* base */, 0 /* max */);
   4748 	}
   4749 	catch (tcu::Exception& exc)
   4750 	{
   4751 		clean();
   4752 		throw exc;
   4753 	}
   4754 
   4755 	/* Execute CopyImageSubData */
   4756 	gl.copyImageSubData(m_src_tex_name, test_case.m_tex_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */,
   4757 						0 /* srcZ */, m_dst_tex_name, test_case.m_tex_target, 0 /* dstLevel */, 0 /* dstX */,
   4758 						0 /* dstY */, 0 /* dstZ */, 1 /* srcWidth */, 1 /* srcHeight */, 1 /* srcDepth */);
   4759 
   4760 	/* Verify generated error */
   4761 	error  = gl.getError();
   4762 	result = (test_case.m_expected_result == error);
   4763 
   4764 	/* Remove resources */
   4765 	clean();
   4766 
   4767 	if (true == result)
   4768 	{
   4769 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4770 
   4771 		/* Increase index */
   4772 		m_test_case_index += 1;
   4773 
   4774 		/* Are there any test cases left */
   4775 		if (m_test_cases.size() > m_test_case_index)
   4776 		{
   4777 			it_result = tcu::TestNode::CONTINUE;
   4778 		}
   4779 	}
   4780 	else
   4781 	{
   4782 		m_context.getTestContext().getLog()
   4783 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   4784 			<< " got: " << glu::getErrorStr(error)
   4785 			<< ". Texture target: " << glu::getTextureTargetStr(test_case.m_tex_target)
   4786 			<< ". Source format: " << glu::getInternalFormatParameterStr(test_case.m_src_internal_format)
   4787 			<< ". Destination format: " << glu::getInternalFormatParameterStr(test_case.m_dst_internal_format)
   4788 			<< tcu::TestLog::EndMessage;
   4789 
   4790 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4791 	}
   4792 
   4793 	/* Done */
   4794 	return it_result;
   4795 }
   4796 
   4797 /** Cleans resources
   4798  *
   4799  **/
   4800 void IncompatibleFormatsTest::clean()
   4801 {
   4802 	const Functions& gl		   = m_context.getRenderContext().getFunctions();
   4803 	const testCase&  test_case = m_test_cases[m_test_case_index];
   4804 
   4805 	/* Clean textures and buffers. Errors ignored */
   4806 	Utils::deleteTexture(m_context, test_case.m_tex_target, m_dst_tex_name);
   4807 	Utils::deleteTexture(m_context, test_case.m_tex_target, m_src_tex_name);
   4808 
   4809 	m_dst_tex_name = 0;
   4810 	m_src_tex_name = 0;
   4811 
   4812 	if (0 != m_dst_buf_name)
   4813 	{
   4814 		gl.deleteBuffers(1, &m_dst_buf_name);
   4815 		m_dst_buf_name = 0;
   4816 	}
   4817 
   4818 	if (0 != m_src_buf_name)
   4819 	{
   4820 		gl.deleteBuffers(1, &m_src_buf_name);
   4821 		m_src_buf_name = 0;
   4822 	}
   4823 }
   4824 
   4825 /* InvalidTargetTest */
   4826 /** Constructor
   4827  *
   4828  * @param context Text context
   4829  **/
   4830 SamplesMissMatchTest::SamplesMissMatchTest(deqp::Context& context)
   4831 	: TestCase(context, "samples_missmatch", "Test verifies if INVALID_OPERATION is generated when textures provided "
   4832 											 "to CopySubImageData have different number of samples")
   4833 	, m_dst_tex_name(0)
   4834 	, m_src_tex_name(0)
   4835 	, m_test_case_index(0)
   4836 {
   4837 	testCase test_case;
   4838 
   4839 	static const GLsizei n_samples[2] = { 1, 4 };
   4840 
   4841 	static const GLenum targets[2] = { GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
   4842 
   4843 	for (GLuint src_sample = 0; src_sample < 2; ++src_sample)
   4844 	{
   4845 		for (GLuint dst_sample = 0; dst_sample < 2; ++dst_sample)
   4846 		{
   4847 			for (GLuint src_target = 0; src_target < 2; ++src_target)
   4848 			{
   4849 				for (GLuint dst_target = 0; dst_target < 2; ++dst_target)
   4850 				{
   4851 					test_case.m_src_target	= targets[src_target];
   4852 					test_case.m_src_n_samples = n_samples[src_sample];
   4853 					test_case.m_dst_target	= targets[dst_target];
   4854 					test_case.m_dst_n_samples = n_samples[dst_sample];
   4855 
   4856 					if (test_case.m_src_n_samples == test_case.m_dst_n_samples)
   4857 					{
   4858 						test_case.m_expected_result = GL_NO_ERROR;
   4859 					}
   4860 					else
   4861 					{
   4862 						test_case.m_expected_result = GL_INVALID_OPERATION;
   4863 					}
   4864 
   4865 					m_test_cases.push_back(test_case);
   4866 				}
   4867 			}
   4868 		}
   4869 	}
   4870 }
   4871 
   4872 /** Execute test
   4873  *
   4874  * @return CONTINUE as long there are more test case, STOP otherwise
   4875  **/
   4876 tcu::TestNode::IterateResult SamplesMissMatchTest::iterate()
   4877 {
   4878 	GLenum						 error	 = GL_NO_ERROR;
   4879 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   4880 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   4881 	bool						 result	= false;
   4882 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   4883 
   4884 	try
   4885 	{
   4886 		/* Prepare textures */
   4887 		m_dst_tex_name = Utils::prepareMultisampleTex(m_context, test_case.m_dst_target, test_case.m_dst_n_samples);
   4888 		m_src_tex_name = Utils::prepareMultisampleTex(m_context, test_case.m_src_target, test_case.m_src_n_samples);
   4889 	}
   4890 	catch (tcu::Exception& exc)
   4891 	{
   4892 		clean();
   4893 		throw exc;
   4894 	}
   4895 
   4896 	/* Execute CopyImageSubData */
   4897 	gl.copyImageSubData(m_src_tex_name, test_case.m_src_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */,
   4898 						0 /* srcZ */, m_dst_tex_name, test_case.m_dst_target, 0 /* dstLevel */, 0 /* dstX */,
   4899 						0 /* dstY */, 0 /* dstZ */, 1 /* srcWidth */, 1 /* srcHeight */, 1 /* srcDepth */);
   4900 
   4901 	/* Verify generated error */
   4902 	error  = gl.getError();
   4903 	result = (test_case.m_expected_result == error);
   4904 
   4905 	/* Free resources */
   4906 	clean();
   4907 
   4908 	/* Set result */
   4909 	if (true == result)
   4910 	{
   4911 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4912 
   4913 		/* Increase index */
   4914 		m_test_case_index += 1;
   4915 
   4916 		/* Are there any test cases left */
   4917 		if (m_test_cases.size() > m_test_case_index)
   4918 		{
   4919 			it_result = tcu::TestNode::CONTINUE;
   4920 		}
   4921 	}
   4922 	else
   4923 	{
   4924 		m_context.getTestContext().getLog()
   4925 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   4926 			<< " got: " << glu::getErrorStr(error)
   4927 			<< ". Source target: " << glu::getTextureTargetStr(test_case.m_src_target)
   4928 			<< " samples: " << test_case.m_src_n_samples
   4929 			<< ", destination target: " << glu::getTextureTargetStr(test_case.m_dst_target)
   4930 			<< " samples: " << test_case.m_dst_n_samples << tcu::TestLog::EndMessage;
   4931 
   4932 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4933 	}
   4934 
   4935 	/* Done */
   4936 	return it_result;
   4937 }
   4938 
   4939 /** Cleans resources
   4940  *
   4941  **/
   4942 void SamplesMissMatchTest::clean()
   4943 {
   4944 	const Functions& gl = m_context.getRenderContext().getFunctions();
   4945 
   4946 	/* Clean textures . Errors ignored */
   4947 	gl.deleteTextures(1, &m_dst_tex_name);
   4948 	gl.deleteTextures(1, &m_src_tex_name);
   4949 
   4950 	m_dst_tex_name = 0;
   4951 	m_src_tex_name = 0;
   4952 }
   4953 
   4954 /* IncompatibleFormatsCompressionTest */
   4955 /** Constructor
   4956  *
   4957  * @param context Text context
   4958  **/
   4959 IncompatibleFormatsCompressionTest::IncompatibleFormatsCompressionTest(deqp::Context& context)
   4960 	: TestCase(context, "incompatible_formats_compression", "Test verifies if INVALID_OPERATION is generated when "
   4961 															"textures provided to CopySubImageData are incompatible, "
   4962 															"one of formats is compressed")
   4963 	, m_dst_tex_name(0)
   4964 	, m_src_tex_name(0)
   4965 	, m_test_case_index(0)
   4966 {
   4967 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   4968 	{
   4969 		const GLenum tex_target = s_valid_targets[target];
   4970 
   4971 		/* Skip 1D targets, not supported */
   4972 		if ((GL_TEXTURE_1D == tex_target) || (GL_TEXTURE_1D_ARRAY == tex_target) || (GL_TEXTURE_3D == tex_target) ||
   4973 			(GL_TEXTURE_RECTANGLE == tex_target) || (GL_RENDERBUFFER == tex_target) || (GL_TEXTURE_CUBE_MAP_ARRAY == tex_target))
   4974 		{
   4975 			continue;
   4976 		}
   4977 
   4978 		/* Skip multisampled and rectangle targets */
   4979 		if (true == Utils::isTargetMultisampled(tex_target))
   4980 		{
   4981 			continue;
   4982 		}
   4983 
   4984 		/* Compressed 128bit vs RGBA32UI */
   4985 		{
   4986 			testCase test_case = {
   4987 				tex_target, GL_RGBA32UI,	  GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_COMPRESSED_RG_RGTC2,
   4988 				GL_RG,		GL_UNSIGNED_BYTE, GL_NO_ERROR
   4989 			};
   4990 
   4991 			m_test_cases.push_back(test_case);
   4992 		}
   4993 
   4994 		/* Compressed 128bit vs RGBA16UI */
   4995 		{
   4996 			testCase test_case = {
   4997 				tex_target, GL_RGBA16UI,	  GL_RGBA_INTEGER,	 GL_UNSIGNED_SHORT, GL_COMPRESSED_RG_RGTC2,
   4998 				GL_RG,		GL_UNSIGNED_BYTE, GL_INVALID_OPERATION
   4999 			};
   5000 
   5001 			m_test_cases.push_back(test_case);
   5002 		}
   5003 	}
   5004 }
   5005 
   5006 /** Execute test
   5007  *
   5008  * @return CONTINUE as long there are more test case, STOP otherwise
   5009  **/
   5010 tcu::TestNode::IterateResult IncompatibleFormatsCompressionTest::iterate()
   5011 {
   5012 	GLenum						 error	 = GL_NO_ERROR;
   5013 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   5014 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   5015 	bool						 result	= false;
   5016 	GLuint						 temp	  = 0;
   5017 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   5018 
   5019 	try
   5020 	{
   5021 		/* Prepare textures */
   5022 		m_dst_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, test_case.m_dst_internal_format,
   5023 												  test_case.m_dst_format, test_case.m_dst_type, temp);
   5024 		m_src_tex_name = Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, test_case.m_src_internal_format,
   5025 												  test_case.m_src_format, test_case.m_src_type, temp);
   5026 
   5027 		/* Make textures complete */
   5028 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_dst_tex_name, 0 /* base */, 0 /* max */);
   5029 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_src_tex_name, 0 /* base */, 0 /* max */);
   5030 	}
   5031 	catch (tcu::Exception& exc)
   5032 	{
   5033 		clean();
   5034 		throw exc;
   5035 	}
   5036 
   5037 	/* Execute CopyImageSubData */
   5038 	gl.copyImageSubData(m_src_tex_name, test_case.m_tex_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */,
   5039 						0 /* srcZ */, m_dst_tex_name, test_case.m_tex_target, 0 /* dstLevel */, 0 /* dstX */,
   5040 						0 /* dstY */, 0 /* dstZ */, 4 /* srcWidth */, 4 /* srcHeight */, 1 /* srcDepth */);
   5041 
   5042 	/* Verify generated error */
   5043 	error  = gl.getError();
   5044 	result = (test_case.m_expected_result == error);
   5045 
   5046 	/* Remove resources */
   5047 	clean();
   5048 
   5049 	if (true == result)
   5050 	{
   5051 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5052 
   5053 		/* Increase index */
   5054 		m_test_case_index += 1;
   5055 
   5056 		/* Are there any test cases left */
   5057 		if (m_test_cases.size() > m_test_case_index)
   5058 		{
   5059 			it_result = tcu::TestNode::CONTINUE;
   5060 		}
   5061 	}
   5062 	else
   5063 	{
   5064 		m_context.getTestContext().getLog()
   5065 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   5066 			<< " got: " << glu::getErrorStr(error)
   5067 			<< ". Texture target: " << glu::getTextureTargetStr(test_case.m_tex_target)
   5068 			<< ". Source format: " << glu::getInternalFormatParameterStr(test_case.m_src_internal_format)
   5069 			<< ". Destination format: " << glu::getInternalFormatParameterStr(test_case.m_dst_internal_format)
   5070 			<< tcu::TestLog::EndMessage;
   5071 
   5072 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5073 	}
   5074 
   5075 	/* Done */
   5076 	return it_result;
   5077 }
   5078 
   5079 /** Cleans resources
   5080  *
   5081  **/
   5082 void IncompatibleFormatsCompressionTest::clean()
   5083 {
   5084 	const Functions& gl = m_context.getRenderContext().getFunctions();
   5085 
   5086 	/* Clean textures and buffers. Errors ignored */
   5087 	gl.deleteTextures(1, &m_dst_tex_name);
   5088 	gl.deleteTextures(1, &m_src_tex_name);
   5089 
   5090 	m_dst_tex_name = 0;
   5091 	m_src_tex_name = 0;
   5092 }
   5093 
   5094 /* MissMatchObjectTest */
   5095 /** Constructor
   5096  *
   5097  * @param context Text context
   5098  **/
   5099 MissMatchObjectTest::MissMatchObjectTest(deqp::Context& context)
   5100 	: TestCase(
   5101 		  context, "missmatch_object",
   5102 		  "Test verifies if INVALID_VALUE is generated when object & target provided to CopySubImageData do not match")
   5103 	, m_dst_name(0)
   5104 	, m_src_name(0)
   5105 	, m_test_case_index(0)
   5106 {
   5107 	static const testCase test_cases[] = { { GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_NO_ERROR },
   5108 										   { GL_TEXTURE_2D, GL_RENDERBUFFER, GL_TEXTURE_2D, GL_INVALID_VALUE },
   5109 										   { GL_TEXTURE_2D, GL_TEXTURE_2D, GL_RENDERBUFFER, GL_INVALID_VALUE },
   5110 										   { GL_TEXTURE_2D, GL_RENDERBUFFER, GL_RENDERBUFFER, GL_INVALID_VALUE },
   5111 										   { GL_RENDERBUFFER, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_INVALID_VALUE },
   5112 										   { GL_RENDERBUFFER, GL_RENDERBUFFER, GL_TEXTURE_2D, GL_INVALID_VALUE },
   5113 										   { GL_RENDERBUFFER, GL_TEXTURE_2D, GL_RENDERBUFFER, GL_INVALID_VALUE },
   5114 										   { GL_RENDERBUFFER, GL_RENDERBUFFER, GL_RENDERBUFFER, GL_NO_ERROR } };
   5115 
   5116 	static const GLuint n_test_cases = sizeof(test_cases) / sizeof(testCase);
   5117 
   5118 	for (GLuint i = 0; i < n_test_cases; ++i)
   5119 	{
   5120 		const testCase& test_case = test_cases[i];
   5121 
   5122 		m_test_cases.push_back(test_case);
   5123 	}
   5124 }
   5125 
   5126 /** Execute test
   5127  *
   5128  * @return CONTINUE as long there are more test case, STOP otherwise
   5129  **/
   5130 tcu::TestNode::IterateResult MissMatchObjectTest::iterate()
   5131 {
   5132 	GLenum						 error	 = GL_NO_ERROR;
   5133 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   5134 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   5135 	bool						 result	= false;
   5136 	GLuint						 temp	  = 0;
   5137 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   5138 
   5139 	try
   5140 	{
   5141 		/* Prepare objects */
   5142 		if (GL_RENDERBUFFER == test_case.m_obj_target)
   5143 		{
   5144 			m_dst_name = Utils::prepareRenderBuffer(m_context, GL_RGBA8);
   5145 			m_src_name = Utils::prepareRenderBuffer(m_context, GL_RGBA8);
   5146 		}
   5147 		else
   5148 		{
   5149 			m_dst_name =
   5150 				Utils::prepareTex16x16x6(m_context, test_case.m_obj_target, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, temp);
   5151 			m_src_name =
   5152 				Utils::prepareTex16x16x6(m_context, test_case.m_obj_target, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, temp);
   5153 
   5154 			/* Make textures complete */
   5155 			Utils::makeTextureComplete(m_context, test_case.m_obj_target, m_dst_name, 0 /* base */, 0 /* max */);
   5156 			Utils::makeTextureComplete(m_context, test_case.m_obj_target, m_src_name, 0 /* base */, 0 /* max */);
   5157 		}
   5158 	}
   5159 	catch (tcu::Exception& exc)
   5160 	{
   5161 		clean();
   5162 		throw exc;
   5163 	}
   5164 
   5165 	/* Execute CopyImageSubData */
   5166 	gl.copyImageSubData(m_src_name, test_case.m_src_target, 0 /* srcLevel */, 0 /* srcX */, 0 /* srcY */, 0 /* srcZ */,
   5167 						m_dst_name, test_case.m_dst_target, 0 /* dstLevel */, 0 /* dstX */, 0 /* dstY */, 0 /* dstZ */,
   5168 						1 /* srcWidth */, 1 /* srcHeight */, 1 /* srcDepth */);
   5169 
   5170 	/* Verify generated error */
   5171 	error  = gl.getError();
   5172 	result = (test_case.m_expected_result == error);
   5173 
   5174 	/* Remove resources */
   5175 	clean();
   5176 
   5177 	if (true == result)
   5178 	{
   5179 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5180 
   5181 		/* Increase index */
   5182 		m_test_case_index += 1;
   5183 
   5184 		/* Are there any test cases left */
   5185 		if (m_test_cases.size() > m_test_case_index)
   5186 		{
   5187 			it_result = tcu::TestNode::CONTINUE;
   5188 		}
   5189 	}
   5190 	else
   5191 	{
   5192 		m_context.getTestContext().getLog()
   5193 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   5194 			<< " got: " << glu::getErrorStr(error)
   5195 			<< ". Object target: " << glu::getTextureTargetStr(test_case.m_obj_target)
   5196 			<< ". Source target: " << glu::getTextureTargetStr(test_case.m_src_target)
   5197 			<< ". Destination target: " << glu::getTextureTargetStr(test_case.m_dst_target) << tcu::TestLog::EndMessage;
   5198 
   5199 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5200 	}
   5201 
   5202 	/* Done */
   5203 	return it_result;
   5204 }
   5205 
   5206 /** Cleans resources
   5207  *
   5208  **/
   5209 void MissMatchObjectTest::clean()
   5210 {
   5211 	const Functions& gl		   = m_context.getRenderContext().getFunctions();
   5212 	const testCase&  test_case = m_test_cases[m_test_case_index];
   5213 
   5214 	/* Clean textures or renderbuffers. Errors ignored */
   5215 	if (GL_RENDERBUFFER == test_case.m_obj_target)
   5216 	{
   5217 		gl.deleteRenderbuffers(1, &m_dst_name);
   5218 		gl.deleteRenderbuffers(1, &m_src_name);
   5219 	}
   5220 	else
   5221 	{
   5222 		gl.deleteTextures(1, &m_dst_name);
   5223 		gl.deleteTextures(1, &m_src_name);
   5224 	}
   5225 
   5226 	m_dst_name = 0;
   5227 	m_src_name = 0;
   5228 }
   5229 
   5230 /* NonExistentMipMapTest */
   5231 /** Constructor
   5232  *
   5233  * @param context Text context
   5234  **/
   5235 NonExistentMipMapTest::NonExistentMipMapTest(deqp::Context& context)
   5236 	: TestCase(context, "non_existent_mipmap", "Test verifies if INVALID_VALUE is generated when CopySubImageData is "
   5237 											   "executed for mipmap that does not exist")
   5238 	, m_dst_tex_name(0)
   5239 	, m_src_tex_name(0)
   5240 	, m_test_case_index(0)
   5241 {
   5242 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   5243 	{
   5244 		const GLenum tex_target = s_valid_targets[target];
   5245 		testCase	 test_case  = { tex_target, 0, 0, GL_NO_ERROR };
   5246 
   5247 		if (GL_RENDERBUFFER == tex_target)
   5248 		{
   5249 			continue;
   5250 		}
   5251 
   5252 		m_test_cases.push_back(test_case);
   5253 
   5254 		/* Rest of cases is invalid */
   5255 		test_case.m_expected_result = GL_INVALID_VALUE;
   5256 
   5257 		test_case.m_dst_level = 1;
   5258 		test_case.m_src_level = 0;
   5259 		m_test_cases.push_back(test_case);
   5260 
   5261 		test_case.m_dst_level = 0;
   5262 		test_case.m_src_level = 1;
   5263 		m_test_cases.push_back(test_case);
   5264 
   5265 		test_case.m_dst_level = 1;
   5266 		test_case.m_src_level = 1;
   5267 		m_test_cases.push_back(test_case);
   5268 	}
   5269 }
   5270 
   5271 /** Execute test
   5272  *
   5273  * @return CONTINUE as long there are more test case, STOP otherwise
   5274  **/
   5275 tcu::TestNode::IterateResult NonExistentMipMapTest::iterate()
   5276 {
   5277 	GLenum						 error	 = GL_NO_ERROR;
   5278 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   5279 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   5280 	bool						 result	= false;
   5281 	GLuint						 temp	  = 0;
   5282 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   5283 
   5284 	try
   5285 	{
   5286 		/* Prepare textures */
   5287 		m_dst_tex_name =
   5288 			Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, temp);
   5289 		m_src_tex_name =
   5290 			Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, temp);
   5291 
   5292 		/* Make textures complete */
   5293 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_dst_tex_name, 0 /* base */, 0 /* max */);
   5294 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_src_tex_name, 0 /* base */, 0 /* max */);
   5295 	}
   5296 	catch (tcu::Exception& exc)
   5297 	{
   5298 		clean();
   5299 		throw exc;
   5300 	}
   5301 
   5302 	/* Execute CopyImageSubData */
   5303 	gl.copyImageSubData(m_src_tex_name, test_case.m_tex_target, test_case.m_src_level, 0 /* srcX */, 0 /* srcY */,
   5304 						0 /* srcZ */, m_dst_tex_name, test_case.m_tex_target, test_case.m_dst_level, 0 /* dstX */,
   5305 						0 /* dstY */, 0 /* dstZ */, 1 /* srcWidth */, 1 /* srcHeight */, 1 /* srcDepth */);
   5306 
   5307 	/* Verify generated error */
   5308 	error  = gl.getError();
   5309 	result = (test_case.m_expected_result == error);
   5310 
   5311 	/* Free resources */
   5312 	clean();
   5313 
   5314 	/* Set result */
   5315 	if (true == result)
   5316 	{
   5317 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5318 
   5319 		/* Increase index */
   5320 		m_test_case_index += 1;
   5321 
   5322 		/* Are there any test cases left */
   5323 		if (m_test_cases.size() > m_test_case_index)
   5324 		{
   5325 			it_result = tcu::TestNode::CONTINUE;
   5326 		}
   5327 	}
   5328 	else
   5329 	{
   5330 		m_context.getTestContext().getLog()
   5331 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   5332 			<< " got: " << glu::getErrorStr(error)
   5333 			<< ". Texture target: " << glu::getTextureTargetStr(test_case.m_tex_target)
   5334 			<< ", source level: " << test_case.m_src_level << ", destination level: " << test_case.m_dst_level
   5335 			<< tcu::TestLog::EndMessage;
   5336 
   5337 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5338 	}
   5339 
   5340 	/* Done */
   5341 	return it_result;
   5342 }
   5343 
   5344 /** Cleans resources
   5345  *
   5346  **/
   5347 void NonExistentMipMapTest::clean()
   5348 {
   5349 	const Functions& gl = m_context.getRenderContext().getFunctions();
   5350 
   5351 	/* Clean textures and buffers. Errors ignored */
   5352 	gl.deleteTextures(1, &m_dst_tex_name);
   5353 	gl.deleteTextures(1, &m_src_tex_name);
   5354 
   5355 	m_dst_tex_name = 0;
   5356 	m_src_tex_name = 0;
   5357 }
   5358 
   5359 /* ExceedingBoundariesTest */
   5360 const glw::GLuint ExceedingBoundariesTest::m_region_depth  = 4;
   5361 const glw::GLuint ExceedingBoundariesTest::m_region_height = 4;
   5362 const glw::GLuint ExceedingBoundariesTest::m_region_width  = 4;
   5363 
   5364 /** Constructor
   5365  *
   5366  * @param context Text context
   5367  **/
   5368 ExceedingBoundariesTest::ExceedingBoundariesTest(deqp::Context& context)
   5369 	: TestCase(context, "exceeding_boundaries", "Test verifies if INVALID_VALUE is generated when CopySubImageData is "
   5370 												"executed for regions exceeding image boundaries")
   5371 	, m_dst_tex_name(0)
   5372 	, m_src_tex_name(0)
   5373 	, m_test_case_index(0)
   5374 {
   5375 	/* 16x16x6 are values used by prepareTex16x16x6 */
   5376 	static const GLuint invalid_x = 16 - (m_region_width / 2);
   5377 	static const GLuint invalid_y = 16 - (m_region_height / 2);
   5378 	static const GLuint invalid_z = 6 - (m_region_depth / 2);
   5379 
   5380 	static const GLuint x_vals[] = { 0, invalid_x };
   5381 	static const GLuint y_vals[] = { 0, invalid_y };
   5382 	static const GLuint z_vals[] = { 0, invalid_z };
   5383 
   5384 	static const GLuint n_x_vals = sizeof(x_vals) / sizeof(x_vals[0]);
   5385 	static const GLuint n_y_vals = sizeof(y_vals) / sizeof(y_vals[0]);
   5386 	static const GLuint n_z_vals = sizeof(z_vals) / sizeof(z_vals[0]);
   5387 
   5388 	for (GLuint target = 0; target < s_n_valid_targets; ++target)
   5389 	{
   5390 		const GLenum tex_target = s_valid_targets[target];
   5391 		GLuint		 height		= m_region_height;
   5392 
   5393 		if (GL_TEXTURE_BUFFER == tex_target)
   5394 		{
   5395 			continue;
   5396 		}
   5397 
   5398 		if ((GL_TEXTURE_1D == tex_target) || (GL_TEXTURE_1D_ARRAY == tex_target))
   5399 		{
   5400 			height = 1;
   5401 		}
   5402 
   5403 		for (GLuint x = 0; x < n_x_vals; ++x)
   5404 		{
   5405 			for (GLuint y = 0; y < n_y_vals; ++y)
   5406 			{
   5407 				for (GLuint z = 0; z < n_z_vals; ++z)
   5408 				{
   5409 					const GLuint x_val = x_vals[x];
   5410 					const GLuint y_val = y_vals[y];
   5411 					const GLuint z_val = z_vals[z];
   5412 					const GLenum res = ((0 == x_val) && (0 == y_val) && (0 == z_val)) ? GL_NO_ERROR : GL_INVALID_VALUE;
   5413 					GLuint		 depth = 1;
   5414 
   5415 					if (0 != z_val)
   5416 					{
   5417 						if ((GL_TEXTURE_2D_ARRAY != tex_target) || (GL_TEXTURE_2D_MULTISAMPLE_ARRAY != tex_target) ||
   5418 							(GL_TEXTURE_3D != tex_target) || (GL_TEXTURE_CUBE_MAP_ARRAY != tex_target))
   5419 						{
   5420 							/* Skip z != 0 for 2d textures */
   5421 							continue;
   5422 						}
   5423 						else
   5424 						{
   5425 							/* Set depth so as to exceed boundary */
   5426 							depth = m_region_depth;
   5427 						}
   5428 					}
   5429 
   5430 					testCase src_test_case = { tex_target, depth, height, x_val, y_val, z_val, 0, 0, 0, res };
   5431 
   5432 					testCase dst_test_case = { tex_target, depth, height, 0, 0, 0, x_val, y_val, z_val, res };
   5433 
   5434 					m_test_cases.push_back(src_test_case);
   5435 					m_test_cases.push_back(dst_test_case);
   5436 				}
   5437 			}
   5438 		}
   5439 	}
   5440 }
   5441 
   5442 /** Execute test
   5443  *
   5444  * @return CONTINUE as long there are more test case, STOP otherwise
   5445  **/
   5446 tcu::TestNode::IterateResult ExceedingBoundariesTest::iterate()
   5447 {
   5448 	GLenum						 error	 = GL_NO_ERROR;
   5449 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   5450 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   5451 	bool						 result	= false;
   5452 	GLuint						 temp	  = 0;
   5453 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   5454 
   5455 	try
   5456 	{
   5457 		/* Prepare textures */
   5458 		m_dst_tex_name =
   5459 			Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, temp);
   5460 		m_src_tex_name =
   5461 			Utils::prepareTex16x16x6(m_context, test_case.m_tex_target, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, temp);
   5462 
   5463 		/* Make textures complete */
   5464 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_dst_tex_name, 0 /* base */, 0 /* max */);
   5465 		Utils::makeTextureComplete(m_context, test_case.m_tex_target, m_src_tex_name, 0 /* base */, 0 /* max */);
   5466 	}
   5467 	catch (tcu::Exception& exc)
   5468 	{
   5469 		clean();
   5470 		throw exc;
   5471 	}
   5472 
   5473 	/* Execute CopyImageSubData */
   5474 	gl.copyImageSubData(m_src_tex_name, test_case.m_tex_target, 0 /* level */, test_case.m_src_x /* srcX */,
   5475 						test_case.m_src_y /* srcY */, test_case.m_src_z /* srcZ */, m_dst_tex_name,
   5476 						test_case.m_tex_target, 0 /* level */, test_case.m_dst_x /* dstX */,
   5477 						test_case.m_dst_y /* dstY */, test_case.m_dst_z /* dstZ */, m_region_width /* srcWidth */,
   5478 						test_case.m_height /* srcHeight */, test_case.m_depth /* srcDepth */);
   5479 
   5480 	/* Verify generated error */
   5481 	error  = gl.getError();
   5482 	result = (test_case.m_expected_result == error);
   5483 
   5484 	/* Free resources */
   5485 	clean();
   5486 
   5487 	/* Set result */
   5488 	if (true == result)
   5489 	{
   5490 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5491 
   5492 		/* Increase index */
   5493 		m_test_case_index += 1;
   5494 
   5495 		/* Are there any test cases left */
   5496 		if (m_test_cases.size() > m_test_case_index)
   5497 		{
   5498 			it_result = tcu::TestNode::CONTINUE;
   5499 		}
   5500 	}
   5501 	else
   5502 	{
   5503 		m_context.getTestContext().getLog()
   5504 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   5505 			<< " got: " << glu::getErrorStr(error)
   5506 			<< ". Texture target: " << glu::getTextureTargetStr(test_case.m_tex_target) << ", source: ["
   5507 			<< test_case.m_src_x << ", " << test_case.m_src_y << ", " << test_case.m_src_z << "], destination: ["
   5508 			<< test_case.m_src_x << ", " << test_case.m_src_y << ", " << test_case.m_src_z
   5509 			<< "], depth: " << test_case.m_depth << tcu::TestLog::EndMessage;
   5510 
   5511 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5512 	}
   5513 
   5514 	/* Done */
   5515 	return it_result;
   5516 }
   5517 
   5518 /** Cleans resources
   5519  *
   5520  **/
   5521 void ExceedingBoundariesTest::clean()
   5522 {
   5523 	const testCase& test_case = m_test_cases[m_test_case_index];
   5524 
   5525 	/* Clean textures and buffers. Errors ignored */
   5526 	Utils::deleteTexture(m_context, test_case.m_tex_target, m_dst_tex_name);
   5527 	Utils::deleteTexture(m_context, test_case.m_tex_target, m_src_tex_name);
   5528 
   5529 	m_dst_tex_name = 0;
   5530 	m_src_tex_name = 0;
   5531 }
   5532 
   5533 /* InvalidAlignmentTest */
   5534 /** Constructor
   5535  *
   5536  * @param context Text context
   5537  **/
   5538 InvalidAlignmentTest::InvalidAlignmentTest(deqp::Context& context)
   5539 	: TestCase(context, "invalid_alignment", "Test verifies if INVALID_VALUE is generated when CopySubImageData is "
   5540 											 "executed for regions with invalid alignment")
   5541 	, m_dst_tex_name(0)
   5542 	, m_src_tex_name(0)
   5543 	, m_test_case_index(0)
   5544 {
   5545 	/* 16x16x6 are values used by prepareTex16x16x6 */
   5546 	static const GLuint invalid_h = 2;
   5547 	static const GLuint invalid_w = 2;
   5548 	static const GLuint invalid_x = 2;
   5549 	static const GLuint invalid_y = 2;
   5550 	static const GLuint valid_h   = 4;
   5551 	static const GLuint valid_w   = 4;
   5552 
   5553 	static const GLuint h_vals[] = { valid_h, invalid_h };
   5554 	static const GLuint w_vals[] = { valid_w, invalid_w };
   5555 	static const GLuint x_vals[] = { 0, invalid_x };
   5556 	static const GLuint y_vals[] = { 0, invalid_y };
   5557 
   5558 	static const GLuint n_h_vals = sizeof(h_vals) / sizeof(h_vals[0]);
   5559 	static const GLuint n_w_vals = sizeof(w_vals) / sizeof(w_vals[0]);
   5560 	static const GLuint n_x_vals = sizeof(x_vals) / sizeof(x_vals[0]);
   5561 	static const GLuint n_y_vals = sizeof(y_vals) / sizeof(y_vals[0]);
   5562 
   5563 	for (GLuint x = 0; x < n_x_vals; ++x)
   5564 	{
   5565 		for (GLuint y = 0; y < n_y_vals; ++y)
   5566 		{
   5567 			for (GLuint h = 0; h < n_h_vals; ++h)
   5568 			{
   5569 				for (GLuint w = 0; w < n_w_vals; ++w)
   5570 				{
   5571 					const GLuint h_val = h_vals[h];
   5572 					const GLuint w_val = w_vals[w];
   5573 					const GLuint x_val = x_vals[x];
   5574 					const GLuint y_val = y_vals[y];
   5575 					const GLenum res   = ((valid_h == h_val) && (valid_w == w_val) && (0 == x_val) && (0 == y_val)) ?
   5576 										   GL_NO_ERROR :
   5577 										   GL_INVALID_VALUE;
   5578 
   5579 					testCase dst_test_case = { h_val, w_val, 0, 0, x_val, y_val, res };
   5580 
   5581 					testCase src_test_case = { h_val, w_val, x_val, y_val, 0, 0, res };
   5582 
   5583 					m_test_cases.push_back(dst_test_case);
   5584 					m_test_cases.push_back(src_test_case);
   5585 				}
   5586 			}
   5587 		}
   5588 	}
   5589 }
   5590 
   5591 /** Execute test
   5592  *
   5593  * @return CONTINUE as long there are more test case, STOP otherwise
   5594  **/
   5595 tcu::TestNode::IterateResult InvalidAlignmentTest::iterate()
   5596 {
   5597 	GLenum						 error	 = GL_NO_ERROR;
   5598 	const Functions&			 gl		   = m_context.getRenderContext().getFunctions();
   5599 	tcu::TestNode::IterateResult it_result = tcu::TestNode::STOP;
   5600 	bool						 result	= false;
   5601 	GLuint						 temp	  = 0;
   5602 	const testCase&				 test_case = m_test_cases[m_test_case_index];
   5603 
   5604 	try
   5605 	{
   5606 		/* Prepare textures */
   5607 		m_dst_tex_name =
   5608 			Utils::prepareTex16x16x6(m_context, GL_TEXTURE_2D, GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, temp);
   5609 		m_src_tex_name =
   5610 			Utils::prepareTex16x16x6(m_context, GL_TEXTURE_2D, GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, temp);
   5611 
   5612 		/* Make textures complete */
   5613 		Utils::makeTextureComplete(m_context, GL_TEXTURE_2D, m_dst_tex_name, 0 /* base */, 0 /* max */);
   5614 		Utils::makeTextureComplete(m_context, GL_TEXTURE_2D, m_src_tex_name, 0 /* base */, 0 /* max */);
   5615 	}
   5616 	catch (tcu::Exception& exc)
   5617 	{
   5618 		clean();
   5619 		throw exc;
   5620 	}
   5621 
   5622 	/* Execute CopyImageSubData */
   5623 	gl.copyImageSubData(m_src_tex_name, GL_TEXTURE_2D, 0 /* level */, test_case.m_src_x /* srcX */,
   5624 						test_case.m_src_y /* srcY */, 0 /* srcZ */, m_dst_tex_name, GL_TEXTURE_2D, 0 /* level */,
   5625 						test_case.m_dst_x /* dstX */, test_case.m_dst_y /* dstY */, 0 /* dstZ */,
   5626 						test_case.m_width /* srcWidth */, test_case.m_height /* srcHeight */, 1 /* srcDepth */);
   5627 
   5628 	/* Verify generated error */
   5629 	error  = gl.getError();
   5630 	result = (test_case.m_expected_result == error);
   5631 
   5632 	/* Free resources */
   5633 	clean();
   5634 
   5635 	/* Set result */
   5636 	if (true == result)
   5637 	{
   5638 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5639 
   5640 		/* Increase index */
   5641 		m_test_case_index += 1;
   5642 
   5643 		/* Are there any test cases left */
   5644 		if (m_test_cases.size() > m_test_case_index)
   5645 		{
   5646 			it_result = tcu::TestNode::CONTINUE;
   5647 		}
   5648 	}
   5649 	else
   5650 	{
   5651 		m_context.getTestContext().getLog()
   5652 			<< tcu::TestLog::Message << "Failure. Expected result: " << glu::getErrorStr(test_case.m_expected_result)
   5653 			<< " got: " << glu::getErrorStr(error) << ". source: [" << test_case.m_src_x << ", " << test_case.m_src_y
   5654 			<< "], destination: [" << test_case.m_src_x << ", " << test_case.m_src_y << "], size: " << test_case.m_width
   5655 			<< " x " << test_case.m_height << tcu::TestLog::EndMessage;
   5656 
   5657 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5658 	}
   5659 
   5660 	/* Done */
   5661 	return it_result;
   5662 }
   5663 
   5664 /** Cleans resources
   5665  *
   5666  **/
   5667 void InvalidAlignmentTest::clean()
   5668 {
   5669 	const Functions& gl = m_context.getRenderContext().getFunctions();
   5670 
   5671 	/* Clean textures and buffers. Errors ignored */
   5672 	gl.deleteTextures(1, &m_dst_tex_name);
   5673 	gl.deleteTextures(1, &m_src_tex_name);
   5674 
   5675 	m_dst_tex_name = 0;
   5676 	m_src_tex_name = 0;
   5677 }
   5678 } /* namespace CopyImage */
   5679 
   5680 CopyImageTests::CopyImageTests(deqp::Context& context) : TestCaseGroup(context, "copy_image", "")
   5681 {
   5682 }
   5683 
   5684 CopyImageTests::~CopyImageTests(void)
   5685 {
   5686 }
   5687 
   5688 void CopyImageTests::init()
   5689 {
   5690 	addChild(new CopyImage::FunctionalTest(m_context));
   5691 	addChild(new CopyImage::IncompleteTexTest(m_context));
   5692 	addChild(new CopyImage::MissMatchObjectTest(m_context));
   5693 	addChild(new CopyImage::SmokeTest(m_context));
   5694 	addChild(new CopyImage::InvalidTargetTest(m_context));
   5695 	addChild(new CopyImage::TargetMissMatchTest(m_context));
   5696 	addChild(new CopyImage::IncompatibleFormatsTest(m_context));
   5697 	addChild(new CopyImage::SamplesMissMatchTest(m_context));
   5698 	addChild(new CopyImage::IncompatibleFormatsCompressionTest(m_context));
   5699 	addChild(new CopyImage::NonExistentMipMapTest(m_context));
   5700 	addChild(new CopyImage::ExceedingBoundariesTest(m_context));
   5701 	addChild(new CopyImage::InvalidAlignmentTest(m_context));
   5702 }
   5703 } /* namespace gl4cts */
   5704