Home | History | Annotate | Download | only in gl
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2014-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 /**
     25  * \file  gl4cTextureViewTests.cpp
     26  * \brief Implements conformance tests for "texture view" functionality.
     27  */ /*-------------------------------------------------------------------*/
     28 
     29 #include "gl4cTextureViewTests.hpp"
     30 #include "deFloat16.h"
     31 #include "deMath.h"
     32 #include "gluContextInfo.hpp"
     33 #include "glwFunctions.hpp"
     34 #include "tcuFloat.hpp"
     35 #include "tcuTestLog.hpp"
     36 #include <algorithm>
     37 
     38 /* Type definitions needed to handle GL_R11F_G11F_B10F internal format */
     39 typedef tcu::Float<deUint32, 5, 5, 15, 0> Float10;
     40 typedef tcu::Float<deUint32, 5, 6, 15, 0> Float11;
     41 
     42 namespace gl4cts
     43 {
     44 using namespace TextureView;
     45 
     46 /** Stores internalformat->view class associations */
     47 const int internalformat_view_compatibility_array[] = {
     48 	/*      [internalformat]                       [view class]        */
     49 	GL_RGBA32F, VIEW_CLASS_128_BITS, GL_RGBA32UI, VIEW_CLASS_128_BITS, GL_RGBA32I, VIEW_CLASS_128_BITS, GL_RGB32F,
     50 	VIEW_CLASS_96_BITS, GL_RGB32UI, VIEW_CLASS_96_BITS, GL_RGB32I, VIEW_CLASS_96_BITS, GL_RGBA16F, VIEW_CLASS_64_BITS,
     51 	GL_RG32F, VIEW_CLASS_64_BITS, GL_RGBA16UI, VIEW_CLASS_64_BITS, GL_RG32UI, VIEW_CLASS_64_BITS, GL_RGBA16I,
     52 	VIEW_CLASS_64_BITS, GL_RG32I, VIEW_CLASS_64_BITS, GL_RGBA16, VIEW_CLASS_64_BITS, GL_RGBA16_SNORM,
     53 	VIEW_CLASS_64_BITS, GL_RGB16, VIEW_CLASS_48_BITS, GL_RGB16_SNORM, VIEW_CLASS_48_BITS, GL_RGB16F, VIEW_CLASS_48_BITS,
     54 	GL_RGB16UI, VIEW_CLASS_48_BITS, GL_RGB16I, VIEW_CLASS_48_BITS, GL_RG16F, VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F,
     55 	VIEW_CLASS_32_BITS, GL_R32F, VIEW_CLASS_32_BITS, GL_RGB10_A2UI, VIEW_CLASS_32_BITS, GL_RGBA8UI, VIEW_CLASS_32_BITS,
     56 	GL_RG16UI, VIEW_CLASS_32_BITS, GL_R32UI, VIEW_CLASS_32_BITS, GL_RGBA8I, VIEW_CLASS_32_BITS, GL_RG16I,
     57 	VIEW_CLASS_32_BITS, GL_R32I, VIEW_CLASS_32_BITS, GL_RGB10_A2, VIEW_CLASS_32_BITS, GL_RGBA8, VIEW_CLASS_32_BITS,
     58 	GL_RG16, VIEW_CLASS_32_BITS, GL_RGBA8_SNORM, VIEW_CLASS_32_BITS, GL_RG16_SNORM, VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8,
     59 	VIEW_CLASS_32_BITS, GL_RGB9_E5, VIEW_CLASS_32_BITS, GL_RGB8, VIEW_CLASS_24_BITS, GL_RGB8_SNORM, VIEW_CLASS_24_BITS,
     60 	GL_SRGB8, VIEW_CLASS_24_BITS, GL_RGB8UI, VIEW_CLASS_24_BITS, GL_RGB8I, VIEW_CLASS_24_BITS, GL_R16F,
     61 	VIEW_CLASS_16_BITS, GL_RG8UI, VIEW_CLASS_16_BITS, GL_R16UI, VIEW_CLASS_16_BITS, GL_RG8I, VIEW_CLASS_16_BITS,
     62 	GL_R16I, VIEW_CLASS_16_BITS, GL_RG8, VIEW_CLASS_16_BITS, GL_R16, VIEW_CLASS_16_BITS, GL_RG8_SNORM,
     63 	VIEW_CLASS_16_BITS, GL_R16_SNORM, VIEW_CLASS_16_BITS, GL_R8UI, VIEW_CLASS_8_BITS, GL_R8I, VIEW_CLASS_8_BITS, GL_R8,
     64 	VIEW_CLASS_8_BITS, GL_R8_SNORM, VIEW_CLASS_8_BITS,
     65 
     66 	/* Compressed texture formats. */
     67 	GL_COMPRESSED_RED_RGTC1, VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1, VIEW_CLASS_RGTC1_RED,
     68 	GL_COMPRESSED_RG_RGTC2, VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2, VIEW_CLASS_RGTC2_RG,
     69 	GL_COMPRESSED_RGBA_BPTC_UNORM, VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, VIEW_CLASS_BPTC_UNORM,
     70 	GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
     71 	VIEW_CLASS_BPTC_FLOAT
     72 };
     73 
     74 const int n_internalformat_view_compatibility_array_entries =
     75 	sizeof(internalformat_view_compatibility_array) / sizeof(internalformat_view_compatibility_array[0]);
     76 
     77 /** Stores all internalformats valid in OpenGL 4.x. Information whether particular internalformat
     78  *  can be considered supported can be retrieved by calling TextureViewTests::isInternalformatSupported()
     79  *  function.
     80  */
     81 const glw::GLenum valid_gl_internalformats[] = {
     82 	/* Section 8.5.1 */
     83 	GL_RGBA32F,		   /* >= GL 4.0 */
     84 	GL_RGBA32I,		   /* >= GL 4.0 */
     85 	GL_RGBA32UI,	   /* >= GL 4.0 */
     86 	GL_RGBA16,		   /* >= GL 4.0 */
     87 	GL_RGBA16F,		   /* >= GL 4.0 */
     88 	GL_RGBA16I,		   /* >= GL 4.0 */
     89 	GL_RGBA16UI,	   /* >= GL 4.0 */
     90 	GL_RGBA8,		   /* >= GL 4.0 */
     91 	GL_RGBA8I,		   /* >= GL 4.0 */
     92 	GL_RGBA8UI,		   /* >= GL 4.0 */
     93 	GL_SRGB8_ALPHA8,   /* >= GL 4.0 */
     94 	GL_RGB10_A2,	   /* >= GL 4.0 */
     95 	GL_RGB10_A2UI,	 /* >= GL 4.0 */
     96 	GL_RGB5_A1,		   /* >= GL 4.0 */
     97 	GL_RGBA4,		   /* >= GL 4.0 */
     98 	GL_R11F_G11F_B10F, /* >= GL 4.0 */
     99 	GL_RGB565,		   /* >= GL 4.2 */
    100 	GL_RG32F,		   /* >= GL 4.0 */
    101 	GL_RG32I,		   /* >= GL 4.0 */
    102 	GL_RG32UI,		   /* >= GL 4.0 */
    103 	GL_RG16,		   /* >= GL 4.0 */
    104 	GL_RG16F,		   /* >= GL 4.0 */
    105 	GL_RG16I,		   /* >= GL 4.0 */
    106 	GL_RG16UI,		   /* >= GL 4.0 */
    107 	GL_RG8,			   /* >= GL 4.0 */
    108 	GL_RG8I,		   /* >= GL 4.0 */
    109 	GL_RG8UI,		   /* >= GL 4.0 */
    110 	GL_R32F,		   /* >= GL 4.0 */
    111 	GL_R32I,		   /* >= GL 4.0 */
    112 	GL_R32UI,		   /* >= GL 4.0 */
    113 	GL_R16F,		   /* >= GL 4.0 */
    114 	GL_R16I,		   /* >= GL 4.0 */
    115 	GL_R16UI,		   /* >= GL 4.0 */
    116 	GL_R16,			   /* >= GL 4.0 */
    117 	GL_R8,			   /* >= GL 4.0 */
    118 	GL_R8I,			   /* >= GL 4.0 */
    119 	GL_R8UI,		   /* >= GL 4.0 */
    120 	GL_RGBA16_SNORM,   /* >= GL 4.0 */
    121 	GL_RGBA8_SNORM,	/* >= GL 4.0 */
    122 	GL_RGB32F,		   /* >= GL 4.0 */
    123 	GL_RGB32I,		   /* >= GL 4.0 */
    124 	GL_RGB32UI,		   /* >= GL 4.0 */
    125 	GL_RGB16_SNORM,	/* >= GL 4.0 */
    126 	GL_RGB16F,		   /* >= GL 4.0 */
    127 	GL_RGB16I,		   /* >= GL 4.0 */
    128 	GL_RGB16UI,		   /* >= GL 4.0 */
    129 	GL_RGB16,		   /* >= GL 4.0 */
    130 	GL_RGB8_SNORM,	 /* >= GL 4.0 */
    131 	GL_RGB8,		   /* >= GL 4.0 */
    132 	GL_RGB8I,		   /* >= GL 4.0 */
    133 	GL_RGB8UI,		   /* >= GL 4.0 */
    134 	GL_SRGB8,		   /* >= GL 4.0 */
    135 	GL_RGB9_E5,		   /* >= GL 4.0 */
    136 	GL_RG16_SNORM,	 /* >= GL 4.0 */
    137 	GL_RG8_SNORM,	  /* >= GL 4.0 */
    138 	GL_R16_SNORM,	  /* >= GL 4.0 */
    139 	GL_R8_SNORM,	   /* >= GL 4.0 */
    140 
    141 	GL_DEPTH_COMPONENT32F, /* >= GL 4.0 */
    142 	GL_DEPTH_COMPONENT24,  /* >= GL 4.0 */
    143 	GL_DEPTH_COMPONENT16,  /* >= GL 4.0 */
    144 
    145 	GL_DEPTH32F_STENCIL8, /* >= GL 4.0 */
    146 	GL_DEPTH24_STENCIL8,  /* >= GL 4.0 */
    147 
    148 	/* Table 8.14: generic compressed internalformats have been removed */
    149 	GL_COMPRESSED_RED_RGTC1,					  /* >= GL 4.0 */
    150 	GL_COMPRESSED_SIGNED_RED_RGTC1,				  /* >= GL 4.0 */
    151 	GL_COMPRESSED_RG_RGTC2,						  /* >= GL 4.0 */
    152 	GL_COMPRESSED_SIGNED_RG_RGTC2,				  /* >= GL 4.0 */
    153 	GL_COMPRESSED_RGBA_BPTC_UNORM,				  /* >= GL 4.2 */
    154 	GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM,		  /* >= GL 4.2 */
    155 	GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT,		  /* >= GL 4.2 */
    156 	GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,		  /* >= GL 4.2 */
    157 	GL_COMPRESSED_RGB8_ETC2,					  /* >= GL 4.3 */
    158 	GL_COMPRESSED_SRGB8_ETC2,					  /* >= GL 4.3 */
    159 	GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  /* >= GL 4.3 */
    160 	GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, /* >= GL 4.3 */
    161 	GL_COMPRESSED_RGBA8_ETC2_EAC,				  /* >= GL 4.3 */
    162 	GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,		  /* >= GL 4.3 */
    163 	GL_COMPRESSED_R11_EAC,						  /* >= GL 4.3 */
    164 	GL_COMPRESSED_SIGNED_R11_EAC,				  /* >= GL 4.3 */
    165 	GL_COMPRESSED_RG11_EAC,						  /* >= GL 4.3 */
    166 	GL_COMPRESSED_SIGNED_RG11_EAC,				  /* >= GL 4.3 */
    167 };
    168 
    169 const int n_valid_gl_internalformats = sizeof(valid_gl_internalformats) / sizeof(valid_gl_internalformats[0]);
    170 
    171 /** An array of texture targets that is used by a number of TextureViewUtilities methods. */
    172 static glw::GLenum valid_texture_targets[] = { GL_TEXTURE_1D,
    173 											   GL_TEXTURE_1D_ARRAY,
    174 											   GL_TEXTURE_2D,
    175 											   GL_TEXTURE_2D_ARRAY,
    176 											   GL_TEXTURE_2D_MULTISAMPLE,
    177 											   GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
    178 											   GL_TEXTURE_3D,
    179 											   GL_TEXTURE_BUFFER,
    180 											   GL_TEXTURE_CUBE_MAP,
    181 											   GL_TEXTURE_CUBE_MAP_ARRAY,
    182 											   GL_TEXTURE_RECTANGLE };
    183 const unsigned int n_valid_texture_targets = sizeof(valid_texture_targets) / sizeof(valid_texture_targets[0]);
    184 
    185 /** Retrieves amount of components defined by user-specified internalformat.
    186  *
    187  *  This function throws TestError exception if @param internalformat is not recognized.
    188  *
    189  *  @param internalformat Internalformat to use for the query.
    190  *
    191  *  @return Requested value.
    192  **/
    193 unsigned int TextureViewUtilities::getAmountOfComponentsForInternalformat(const glw::GLenum internalformat)
    194 {
    195 	unsigned int result = 0;
    196 
    197 	switch (internalformat)
    198 	{
    199 	case GL_COMPRESSED_RGBA_BPTC_UNORM:
    200 	case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
    201 	case GL_RGB10_A2:
    202 	case GL_RGB10_A2UI:
    203 	case GL_RGB5_A1:
    204 	case GL_RGBA16F:
    205 	case GL_RGBA16I:
    206 	case GL_RGBA16UI:
    207 	case GL_RGBA16:
    208 	case GL_RGBA16_SNORM:
    209 	case GL_RGBA32F:
    210 	case GL_RGBA32I:
    211 	case GL_RGBA32UI:
    212 	case GL_RGBA4:
    213 	case GL_RGBA8I:
    214 	case GL_RGBA8UI:
    215 	case GL_RGBA8:
    216 	case GL_RGBA8_SNORM:
    217 	case GL_SRGB8_ALPHA8:
    218 	{
    219 		result = 4;
    220 
    221 		break;
    222 	}
    223 
    224 	case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
    225 	case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
    226 	case GL_R11F_G11F_B10F:
    227 	case GL_RGB16_SNORM:
    228 	case GL_RGB16F:
    229 	case GL_RGB16I:
    230 	case GL_RGB16UI:
    231 	case GL_RGB16:
    232 	case GL_RGB32F:
    233 	case GL_RGB32I:
    234 	case GL_RGB32UI:
    235 	case GL_RGB565:
    236 	case GL_RGB8:
    237 	case GL_RGB8_SNORM:
    238 	case GL_RGB8I:
    239 	case GL_RGB8UI:
    240 	case GL_RGB9_E5:
    241 	case GL_SRGB8:
    242 	{
    243 		result = 3;
    244 
    245 		break;
    246 	}
    247 
    248 	case GL_COMPRESSED_RG_RGTC2:
    249 	case GL_COMPRESSED_SIGNED_RG_RGTC2:
    250 	case GL_RG16:
    251 	case GL_RG16F:
    252 	case GL_RG16I:
    253 	case GL_RG16UI:
    254 	case GL_RG16_SNORM:
    255 	case GL_RG32F:
    256 	case GL_RG32I:
    257 	case GL_RG32UI:
    258 	case GL_RG8:
    259 	case GL_RG8_SNORM:
    260 	case GL_RG8I:
    261 	case GL_RG8UI:
    262 	{
    263 		result = 2;
    264 
    265 		break;
    266 	}
    267 
    268 	case GL_COMPRESSED_RED_RGTC1:
    269 	case GL_COMPRESSED_SIGNED_RED_RGTC1:
    270 	case GL_DEPTH_COMPONENT16:
    271 	case GL_DEPTH_COMPONENT24:
    272 	case GL_DEPTH32F_STENCIL8: /* only one piece of information can be retrieved at a time */
    273 	case GL_DEPTH24_STENCIL8:  /* only one piece of information can be retrieved at a time */
    274 	case GL_R16:
    275 	case GL_R16_SNORM:
    276 	case GL_R16F:
    277 	case GL_R16I:
    278 	case GL_R16UI:
    279 	case GL_R32F:
    280 	case GL_R32I:
    281 	case GL_R32UI:
    282 	case GL_R8_SNORM:
    283 	case GL_R8:
    284 	case GL_R8I:
    285 	case GL_R8UI:
    286 	{
    287 		result = 1;
    288 
    289 		break;
    290 	}
    291 
    292 	default:
    293 	{
    294 		TCU_FAIL("Unrecognized internalformat");
    295 	}
    296 	} /* switch (interalformat) */
    297 
    298 	return result;
    299 }
    300 
    301 /** Retrieves block size used by user-specified compressed internalformat.
    302  *
    303  *  Throws TestError exception if @param internalformat is not recognized.
    304  *
    305  *  @param internalformat Compressed internalformat to use for the query.
    306  *
    307  *  @return Requested information (in bytes).
    308  **/
    309 unsigned int TextureViewUtilities::getBlockSizeForCompressedInternalformat(const glw::GLenum internalformat)
    310 {
    311 	unsigned int result = 0;
    312 
    313 	switch (internalformat)
    314 	{
    315 	case GL_COMPRESSED_RED_RGTC1:
    316 	case GL_COMPRESSED_SIGNED_RED_RGTC1:
    317 	{
    318 		result = 8;
    319 
    320 		break;
    321 	}
    322 
    323 	case GL_COMPRESSED_RG_RGTC2:
    324 	case GL_COMPRESSED_SIGNED_RG_RGTC2:
    325 	case GL_COMPRESSED_RGBA_BPTC_UNORM:
    326 	case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
    327 	case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
    328 	case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
    329 	{
    330 		result = 16;
    331 
    332 		break;
    333 	}
    334 
    335 	default:
    336 	{
    337 		TCU_FAIL("Unrecognized internalformat");
    338 	}
    339 	} /* switch (internalformat) */
    340 
    341 	return result;
    342 }
    343 
    344 /** Retrieves amount of bits used for R/G/B/A components by user-specified
    345  *  *non-compressed* internalformat.
    346  *
    347  *  Throws TestError exception if @param internalformat is not recognized.
    348  *
    349  *  @param internalformat Internalformat to use for the query. Must not describe
    350  *                        compressed internalformat.
    351  *  @param out_rgba_size  Must be spacious enough to hold 4 ints. Deref will be
    352  *                        used to store requested information for R/G/B/A channels.
    353  *                        Must not be NULL.
    354  **/
    355 void TextureViewUtilities::getComponentSizeForInternalformat(const glw::GLenum internalformat,
    356 															 unsigned int*	 out_rgba_size)
    357 {
    358 	/* Note: Compressed textures are not supported by this function */
    359 
    360 	/* Reset all the values before we continue. */
    361 	memset(out_rgba_size, 0, 4 /* rgba */ * sizeof(unsigned int));
    362 
    363 	/* Depending on the user-specified internalformat, update relevant arguments */
    364 	switch (internalformat)
    365 	{
    366 	case GL_RGBA32F:
    367 	case GL_RGBA32I:
    368 	case GL_RGBA32UI:
    369 	{
    370 		out_rgba_size[0] = 32;
    371 		out_rgba_size[1] = 32;
    372 		out_rgba_size[2] = 32;
    373 		out_rgba_size[3] = 32;
    374 
    375 		break;
    376 	}
    377 
    378 	case GL_RGBA16F:
    379 	case GL_RGBA16I:
    380 	case GL_RGBA16UI:
    381 	case GL_RGBA16:
    382 	case GL_RGBA16_SNORM:
    383 	{
    384 		out_rgba_size[0] = 16;
    385 		out_rgba_size[1] = 16;
    386 		out_rgba_size[2] = 16;
    387 		out_rgba_size[3] = 16;
    388 
    389 		break;
    390 	}
    391 
    392 	case GL_RGBA8I:
    393 	case GL_RGBA8UI:
    394 	case GL_RGBA8:
    395 	case GL_RGBA8_SNORM:
    396 	case GL_SRGB8_ALPHA8:
    397 	{
    398 		out_rgba_size[0] = 8;
    399 		out_rgba_size[1] = 8;
    400 		out_rgba_size[2] = 8;
    401 		out_rgba_size[3] = 8;
    402 
    403 		break;
    404 	}
    405 
    406 	case GL_RGB10_A2:
    407 	case GL_RGB10_A2UI:
    408 	{
    409 		out_rgba_size[0] = 10;
    410 		out_rgba_size[1] = 10;
    411 		out_rgba_size[2] = 10;
    412 		out_rgba_size[3] = 2;
    413 
    414 		break;
    415 	}
    416 
    417 	case GL_RGB5_A1:
    418 	{
    419 		out_rgba_size[0] = 5;
    420 		out_rgba_size[1] = 5;
    421 		out_rgba_size[2] = 5;
    422 		out_rgba_size[3] = 1;
    423 
    424 		break;
    425 	}
    426 
    427 	case GL_RGBA4:
    428 	{
    429 		out_rgba_size[0] = 4;
    430 		out_rgba_size[1] = 4;
    431 		out_rgba_size[2] = 4;
    432 		out_rgba_size[3] = 4;
    433 
    434 		break;
    435 	}
    436 
    437 	case GL_RGB9_E5:
    438 	{
    439 		out_rgba_size[0] = 9;
    440 		out_rgba_size[1] = 9;
    441 		out_rgba_size[2] = 9;
    442 		out_rgba_size[3] = 5;
    443 
    444 		break;
    445 	}
    446 
    447 	case GL_R11F_G11F_B10F:
    448 	{
    449 		out_rgba_size[0] = 11;
    450 		out_rgba_size[1] = 11;
    451 		out_rgba_size[2] = 10;
    452 
    453 		break;
    454 	}
    455 
    456 	case GL_RGB565:
    457 	{
    458 		out_rgba_size[0] = 5;
    459 		out_rgba_size[1] = 6;
    460 		out_rgba_size[2] = 5;
    461 
    462 		break;
    463 	}
    464 
    465 	case GL_RGB32F:
    466 	case GL_RGB32I:
    467 	case GL_RGB32UI:
    468 	{
    469 		out_rgba_size[0] = 32;
    470 		out_rgba_size[1] = 32;
    471 		out_rgba_size[2] = 32;
    472 
    473 		break;
    474 	}
    475 
    476 	case GL_RGB16_SNORM:
    477 	case GL_RGB16F:
    478 	case GL_RGB16I:
    479 	case GL_RGB16UI:
    480 	case GL_RGB16:
    481 	{
    482 		out_rgba_size[0] = 16;
    483 		out_rgba_size[1] = 16;
    484 		out_rgba_size[2] = 16;
    485 
    486 		break;
    487 	}
    488 
    489 	case GL_RGB8_SNORM:
    490 	case GL_RGB8:
    491 	case GL_RGB8I:
    492 	case GL_RGB8UI:
    493 	case GL_SRGB8:
    494 	{
    495 		out_rgba_size[0] = 8;
    496 		out_rgba_size[1] = 8;
    497 		out_rgba_size[2] = 8;
    498 
    499 		break;
    500 	}
    501 
    502 	case GL_RG32F:
    503 	case GL_RG32I:
    504 	case GL_RG32UI:
    505 	{
    506 		out_rgba_size[0] = 32;
    507 		out_rgba_size[1] = 32;
    508 
    509 		break;
    510 	}
    511 
    512 	case GL_RG16:
    513 	case GL_RG16F:
    514 	case GL_RG16I:
    515 	case GL_RG16UI:
    516 	case GL_RG16_SNORM:
    517 	{
    518 		out_rgba_size[0] = 16;
    519 		out_rgba_size[1] = 16;
    520 
    521 		break;
    522 	}
    523 
    524 	case GL_RG8:
    525 	case GL_RG8I:
    526 	case GL_RG8UI:
    527 	case GL_RG8_SNORM:
    528 	{
    529 		out_rgba_size[0] = 8;
    530 		out_rgba_size[1] = 8;
    531 
    532 		break;
    533 	}
    534 
    535 	case GL_R32F:
    536 	case GL_R32I:
    537 	case GL_R32UI:
    538 	{
    539 		out_rgba_size[0] = 32;
    540 
    541 		break;
    542 	}
    543 
    544 	case GL_R16F:
    545 	case GL_R16I:
    546 	case GL_R16UI:
    547 	case GL_R16:
    548 	case GL_R16_SNORM:
    549 	case GL_DEPTH_COMPONENT16:
    550 	{
    551 		out_rgba_size[0] = 16;
    552 
    553 		break;
    554 	}
    555 
    556 	case GL_R8:
    557 	case GL_R8I:
    558 	case GL_R8UI:
    559 	case GL_R8_SNORM:
    560 	{
    561 		out_rgba_size[0] = 8;
    562 
    563 		break;
    564 	}
    565 
    566 	case GL_DEPTH_COMPONENT24:
    567 	{
    568 		out_rgba_size[0] = 24;
    569 
    570 		break;
    571 	}
    572 
    573 	case GL_DEPTH32F_STENCIL8:
    574 	{
    575 		out_rgba_size[0] = 32;
    576 		out_rgba_size[1] = 8;
    577 
    578 		break;
    579 	}
    580 
    581 	case GL_DEPTH24_STENCIL8:
    582 	{
    583 		out_rgba_size[0] = 24;
    584 		out_rgba_size[1] = 8;
    585 
    586 		break;
    587 	}
    588 
    589 	default:
    590 	{
    591 		TCU_FAIL("Unrecognized internalformat");
    592 	}
    593 	} /* switch (interalformat) */
    594 }
    595 
    596 /** Tells how many bits per components should be used to define input data with
    597  *  user-specified type.
    598  *
    599  *  Throws TestError exception if @param type is not recognized.
    600  *
    601  *  @param type          Type to use for the query.
    602  *  @param out_rgba_size Deref will be used to store requested information. Must
    603  *                       not be NULL. Must be capacious enough to hold 4 ints.
    604  *
    605  **/
    606 void TextureViewUtilities::getComponentSizeForType(const glw::GLenum type, unsigned int* out_rgba_size)
    607 {
    608 	memset(out_rgba_size, 0, sizeof(unsigned int) * 4 /* rgba */);
    609 
    610 	switch (type)
    611 	{
    612 	case GL_BYTE:
    613 	case GL_UNSIGNED_BYTE:
    614 	{
    615 		out_rgba_size[0] = 8;
    616 		out_rgba_size[1] = 8;
    617 		out_rgba_size[2] = 8;
    618 		out_rgba_size[3] = 8;
    619 
    620 		break;
    621 	}
    622 
    623 	case GL_FLOAT:
    624 	case GL_UNSIGNED_INT:
    625 	case GL_INT:
    626 	{
    627 		out_rgba_size[0] = 32;
    628 		out_rgba_size[1] = 32;
    629 		out_rgba_size[2] = 32;
    630 		out_rgba_size[3] = 32;
    631 
    632 		break;
    633 	}
    634 
    635 	case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
    636 	{
    637 		out_rgba_size[0] = 8;
    638 		out_rgba_size[1] = 24;
    639 		out_rgba_size[2] = 32;
    640 		out_rgba_size[3] = 0;
    641 
    642 		break;
    643 	}
    644 
    645 	case GL_HALF_FLOAT:
    646 	case GL_UNSIGNED_SHORT:
    647 	case GL_SHORT:
    648 	{
    649 		out_rgba_size[0] = 16;
    650 		out_rgba_size[1] = 16;
    651 		out_rgba_size[2] = 16;
    652 		out_rgba_size[3] = 16;
    653 
    654 		break;
    655 	}
    656 
    657 	case GL_UNSIGNED_INT_10_10_10_2:
    658 	{
    659 		out_rgba_size[0] = 10;
    660 		out_rgba_size[1] = 10;
    661 		out_rgba_size[2] = 10;
    662 		out_rgba_size[3] = 2;
    663 
    664 		break;
    665 	}
    666 
    667 	case GL_UNSIGNED_INT_10F_11F_11F_REV:
    668 	{
    669 		out_rgba_size[0] = 11;
    670 		out_rgba_size[1] = 11;
    671 		out_rgba_size[2] = 10;
    672 
    673 		break;
    674 	}
    675 
    676 	case GL_UNSIGNED_INT_24_8:
    677 	{
    678 		out_rgba_size[0] = 24;
    679 		out_rgba_size[1] = 8;
    680 		out_rgba_size[2] = 0;
    681 		out_rgba_size[3] = 0;
    682 
    683 		break;
    684 	}
    685 
    686 	case GL_UNSIGNED_INT_2_10_10_10_REV:
    687 	{
    688 		out_rgba_size[0] = 10;
    689 		out_rgba_size[1] = 10;
    690 		out_rgba_size[2] = 10;
    691 		out_rgba_size[3] = 2;
    692 
    693 		break;
    694 	}
    695 
    696 	case GL_UNSIGNED_INT_5_9_9_9_REV:
    697 	{
    698 		out_rgba_size[0] = 9;
    699 		out_rgba_size[1] = 9;
    700 		out_rgba_size[2] = 9;
    701 		out_rgba_size[3] = 5;
    702 
    703 		break;
    704 	}
    705 
    706 	default:
    707 	{
    708 		TCU_FAIL("Unrecognized type");
    709 	}
    710 	} /* switch (type) */
    711 }
    712 
    713 /** Returns strings naming GL error codes.
    714  *
    715  *  @param error_code GL error code.
    716  *
    717  *  @return Requested strings or "[?]" if @param error_code was not
    718  *          recognized.
    719  **/
    720 const char* TextureViewUtilities::getErrorCodeString(const glw::GLint error_code)
    721 {
    722 	switch (error_code)
    723 	{
    724 	case GL_INVALID_ENUM:
    725 		return "GL_INVALID_ENUM";
    726 	case GL_INVALID_FRAMEBUFFER_OPERATION:
    727 		return "GL_INVALID_FRAMEBUFFER_OPERATION";
    728 	case GL_INVALID_OPERATION:
    729 		return "GL_INVALID_OPERATION";
    730 	case GL_INVALID_VALUE:
    731 		return "GL_INVALID_VALUE";
    732 	case GL_NO_ERROR:
    733 		return "GL_NO_ERROR";
    734 	case GL_OUT_OF_MEMORY:
    735 		return "GL_OUT_OF_MEMORY";
    736 	case GL_STACK_OVERFLOW:
    737 		return "GL_STACK_OVERFLOW";
    738 	case GL_STACK_UNDERFLOW:
    739 		return "GL_STACK_UNDERFLOW";
    740 	default:
    741 		return "[?]";
    742 	}
    743 }
    744 
    745 /** Tells what the format of user-specified internalformat is (eg. whether it's a FP,
    746  *  unorm, snorm, etc.). Note: this is NOT the GL-speak format.
    747  *
    748  *  Supports both compressed and non-compressed internalformats.
    749  *  Throws TestError exception if @param internalformat is not recognized.
    750  *
    751  *  @param internalformat Internalformat to use for the query.
    752  *
    753  *  @return Requested information.
    754  *
    755  **/
    756 _format TextureViewUtilities::getFormatOfInternalformat(const glw::GLenum internalformat)
    757 {
    758 	_format result = FORMAT_UNDEFINED;
    759 
    760 	switch (internalformat)
    761 	{
    762 	case GL_COMPRESSED_RG_RGTC2:
    763 	case GL_COMPRESSED_RGBA_BPTC_UNORM:
    764 	case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
    765 	case GL_COMPRESSED_RED_RGTC1:
    766 	case GL_RGBA16:
    767 	case GL_RGBA4:
    768 	case GL_RGBA8:
    769 	case GL_RGB10_A2:
    770 	case GL_RGB16:
    771 	case GL_RGB5_A1:
    772 	case GL_RGB565:
    773 	case GL_RGB8:
    774 	case GL_RG16:
    775 	case GL_RG8:
    776 	case GL_R16:
    777 	case GL_R8:
    778 	case GL_SRGB8:
    779 	case GL_SRGB8_ALPHA8:
    780 	{
    781 		result = FORMAT_UNORM;
    782 
    783 		break;
    784 	}
    785 
    786 	case GL_COMPRESSED_SIGNED_RED_RGTC1:
    787 	case GL_COMPRESSED_SIGNED_RG_RGTC2:
    788 	case GL_RGBA16_SNORM:
    789 	case GL_RGBA8_SNORM:
    790 	case GL_RGB16_SNORM:
    791 	case GL_RGB8_SNORM:
    792 	case GL_RG16_SNORM:
    793 	case GL_RG8_SNORM:
    794 	case GL_R16_SNORM:
    795 	case GL_R8_SNORM:
    796 	{
    797 		result = FORMAT_SNORM;
    798 
    799 		break;
    800 	}
    801 
    802 	case GL_RGB10_A2UI:
    803 	case GL_RGBA16UI:
    804 	case GL_RGBA32UI:
    805 	case GL_RGBA8UI:
    806 	case GL_RGB16UI:
    807 	case GL_RGB32UI:
    808 	case GL_RGB8UI:
    809 	case GL_RG16UI:
    810 	case GL_RG32UI:
    811 	case GL_RG8UI:
    812 	case GL_R16UI:
    813 	case GL_R32UI:
    814 	case GL_R8UI:
    815 	{
    816 		result = FORMAT_UNSIGNED_INTEGER;
    817 
    818 		break;
    819 	}
    820 
    821 	case GL_RGB9_E5:
    822 	{
    823 		result = FORMAT_RGBE;
    824 
    825 		break;
    826 	}
    827 
    828 	case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
    829 	case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
    830 	case GL_DEPTH_COMPONENT16:
    831 	case GL_DEPTH_COMPONENT24:
    832 	case GL_DEPTH_COMPONENT32F:
    833 	case GL_R11F_G11F_B10F:
    834 	case GL_RGBA16F:
    835 	case GL_RGBA32F:
    836 	case GL_RGB16F:
    837 	case GL_RGB32F:
    838 	case GL_RG16F:
    839 	case GL_RG32F:
    840 	case GL_R16F:
    841 	case GL_R32F:
    842 	{
    843 		result = FORMAT_FLOAT;
    844 
    845 		break;
    846 	}
    847 
    848 	case GL_RGBA16I:
    849 	case GL_RGBA32I:
    850 	case GL_RGBA8I:
    851 	case GL_RGB16I:
    852 	case GL_RGB32I:
    853 	case GL_RGB8I:
    854 	case GL_RG16I:
    855 	case GL_RG32I:
    856 	case GL_RG8I:
    857 	case GL_R16I:
    858 	case GL_R32I:
    859 	case GL_R8I:
    860 	{
    861 		result = FORMAT_SIGNED_INTEGER;
    862 
    863 		break;
    864 	}
    865 
    866 	default:
    867 	{
    868 		TCU_FAIL("Unrecognized internalformat");
    869 	}
    870 	} /* switch (interalformat) */
    871 
    872 	return result;
    873 }
    874 
    875 /** Returns GL format that is compatible with user-specified internalformat.
    876  *
    877  *  Throws TestError exception if @param internalformat is not recognized.
    878  *
    879  *  @param internalformat Internalformat to use for the query.
    880  *
    881  *  @return Requested information.
    882  **/
    883 glw::GLenum TextureViewUtilities::getGLFormatOfInternalformat(const glw::GLenum internalformat)
    884 {
    885 	glw::GLenum result = FORMAT_UNDEFINED;
    886 
    887 	switch (internalformat)
    888 	{
    889 	case GL_COMPRESSED_RGBA_BPTC_UNORM:
    890 	case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
    891 	case GL_COMPRESSED_RGBA8_ETC2_EAC:
    892 	case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
    893 	case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
    894 	case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
    895 	{
    896 		result = GL_COMPRESSED_RGBA;
    897 
    898 		break;
    899 	}
    900 
    901 	case GL_RGB10_A2:
    902 	case GL_RGB5_A1:
    903 	case GL_RGBA16:
    904 	case GL_RGBA16F:
    905 	case GL_RGBA16_SNORM:
    906 	case GL_RGBA32F:
    907 	case GL_RGBA4:
    908 	case GL_RGBA8:
    909 	case GL_RGBA8_SNORM:
    910 	case GL_SRGB8_ALPHA8:
    911 	{
    912 		result = GL_RGBA;
    913 
    914 		break;
    915 	}
    916 
    917 	case GL_RGB10_A2UI:
    918 	case GL_RGBA16I:
    919 	case GL_RGBA16UI:
    920 	case GL_RGBA32I:
    921 	case GL_RGBA32UI:
    922 	case GL_RGBA8I:
    923 	case GL_RGBA8UI:
    924 	{
    925 		result = GL_RGBA_INTEGER;
    926 
    927 		break;
    928 	}
    929 
    930 	case GL_COMPRESSED_RGB8_ETC2:
    931 	case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
    932 	case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
    933 	case GL_COMPRESSED_SRGB8_ETC2:
    934 	{
    935 		result = GL_COMPRESSED_RGB;
    936 
    937 		break;
    938 	}
    939 
    940 	case GL_R11F_G11F_B10F:
    941 	case GL_RGB16:
    942 	case GL_RGB16_SNORM:
    943 	case GL_RGB16F:
    944 	case GL_RGB32F:
    945 	case GL_RGB565:
    946 	case GL_RGB8:
    947 	case GL_RGB8_SNORM:
    948 	case GL_RGB9_E5:
    949 	case GL_SRGB8:
    950 	{
    951 		result = GL_RGB;
    952 
    953 		break;
    954 	}
    955 
    956 	case GL_RGB16I:
    957 	case GL_RGB16UI:
    958 	case GL_RGB32I:
    959 	case GL_RGB32UI:
    960 	case GL_RGB8I:
    961 	case GL_RGB8UI:
    962 	{
    963 		result = GL_RGB_INTEGER;
    964 
    965 		break;
    966 	}
    967 
    968 	case GL_COMPRESSED_RG_RGTC2:
    969 	case GL_COMPRESSED_RG11_EAC:
    970 	case GL_COMPRESSED_SIGNED_RG_RGTC2:
    971 	case GL_COMPRESSED_SIGNED_RG11_EAC:
    972 	{
    973 		result = GL_COMPRESSED_RG;
    974 
    975 		break;
    976 	}
    977 
    978 	case GL_RG16:
    979 	case GL_RG16_SNORM:
    980 	case GL_RG16F:
    981 	case GL_RG32F:
    982 	case GL_RG8:
    983 	case GL_RG8_SNORM:
    984 	{
    985 		result = GL_RG;
    986 
    987 		break;
    988 	}
    989 
    990 	case GL_RG16I:
    991 	case GL_RG16UI:
    992 	case GL_RG32I:
    993 	case GL_RG32UI:
    994 	case GL_RG8I:
    995 	case GL_RG8UI:
    996 	{
    997 		result = GL_RG_INTEGER;
    998 
    999 		break;
   1000 	}
   1001 
   1002 	case GL_COMPRESSED_R11_EAC:
   1003 	case GL_COMPRESSED_RED_RGTC1:
   1004 	case GL_COMPRESSED_SIGNED_R11_EAC:
   1005 	case GL_COMPRESSED_SIGNED_RED_RGTC1:
   1006 	{
   1007 		result = GL_COMPRESSED_RED;
   1008 
   1009 		break;
   1010 	}
   1011 
   1012 	case GL_R16:
   1013 	case GL_R16F:
   1014 	case GL_R16_SNORM:
   1015 	case GL_R32F:
   1016 	case GL_R8:
   1017 	case GL_R8_SNORM:
   1018 	{
   1019 		result = GL_RED;
   1020 
   1021 		break;
   1022 	}
   1023 
   1024 	case GL_R16I:
   1025 	case GL_R16UI:
   1026 	case GL_R32I:
   1027 	case GL_R32UI:
   1028 	case GL_R8I:
   1029 	case GL_R8UI:
   1030 	{
   1031 		result = GL_RED_INTEGER;
   1032 
   1033 		break;
   1034 	}
   1035 
   1036 	case GL_DEPTH_COMPONENT16:
   1037 	case GL_DEPTH_COMPONENT24:
   1038 	case GL_DEPTH_COMPONENT32F:
   1039 	{
   1040 		result = GL_DEPTH_COMPONENT;
   1041 
   1042 		break;
   1043 	}
   1044 
   1045 	case GL_DEPTH24_STENCIL8:
   1046 	case GL_DEPTH32F_STENCIL8:
   1047 	{
   1048 		result = GL_DEPTH_STENCIL;
   1049 
   1050 		break;
   1051 	}
   1052 
   1053 	default:
   1054 	{
   1055 		TCU_FAIL("Unrecognized internalformat");
   1056 	}
   1057 	} /* switch (internalformat) */
   1058 
   1059 	return result;
   1060 }
   1061 
   1062 /** Returns a string that corresponds to a GLSL type that can act as input to user-specified
   1063  *  sampler type, and which can hold user-specified amount of components.
   1064  *
   1065  *  Throws TestError exception if either of the arguments was found invalid.
   1066  *
   1067  *  @param sampler_type Type of the sampler to use for the query.
   1068  *  @param n_components Amount of components to use for the query.
   1069  *
   1070  *  @return Requested string.
   1071  **/
   1072 const char* TextureViewUtilities::getGLSLDataTypeForSamplerType(const _sampler_type sampler_type,
   1073 																const unsigned int  n_components)
   1074 {
   1075 	const char* result = "";
   1076 
   1077 	switch (sampler_type)
   1078 	{
   1079 	case SAMPLER_TYPE_FLOAT:
   1080 	{
   1081 		switch (n_components)
   1082 		{
   1083 		case 1:
   1084 			result = "float";
   1085 			break;
   1086 		case 2:
   1087 			result = "vec2";
   1088 			break;
   1089 		case 3:
   1090 			result = "vec3";
   1091 			break;
   1092 		case 4:
   1093 			result = "vec4";
   1094 			break;
   1095 
   1096 		default:
   1097 		{
   1098 			TCU_FAIL("Unsupported number of components");
   1099 		}
   1100 		} /* switch (n_components) */
   1101 
   1102 		break;
   1103 	}
   1104 
   1105 	case SAMPLER_TYPE_SIGNED_INTEGER:
   1106 	{
   1107 		switch (n_components)
   1108 		{
   1109 		case 1:
   1110 			result = "int";
   1111 			break;
   1112 		case 2:
   1113 			result = "ivec2";
   1114 			break;
   1115 		case 3:
   1116 			result = "ivec3";
   1117 			break;
   1118 		case 4:
   1119 			result = "ivec4";
   1120 			break;
   1121 
   1122 		default:
   1123 		{
   1124 			TCU_FAIL("Unsupported number of components");
   1125 		}
   1126 		} /* switch (n_components) */
   1127 
   1128 		break;
   1129 	}
   1130 
   1131 	case SAMPLER_TYPE_UNSIGNED_INTEGER:
   1132 	{
   1133 		switch (n_components)
   1134 		{
   1135 		case 1:
   1136 			result = "uint";
   1137 			break;
   1138 		case 2:
   1139 			result = "uvec2";
   1140 			break;
   1141 		case 3:
   1142 			result = "uvec3";
   1143 			break;
   1144 		case 4:
   1145 			result = "uvec4";
   1146 			break;
   1147 
   1148 		default:
   1149 		{
   1150 			TCU_FAIL("Unsupported number of components");
   1151 		}
   1152 		} /* switch (n_components) */
   1153 
   1154 		break;
   1155 	}
   1156 
   1157 	default:
   1158 	{
   1159 		TCU_FAIL("Unrecognized sampler type");
   1160 	}
   1161 	} /* switch (sampler_type) */
   1162 
   1163 	return result;
   1164 }
   1165 
   1166 /** Retrieves a string defining a sampler type in GLSL which corresponds to user-specified internal
   1167  *  sampler type.
   1168  *
   1169  *  Throws TestError exception if @param sampler_type was not recognized.
   1170  *
   1171  *  @param sampler_type Internal sampler type to use for the query.
   1172  *
   1173  *  @return Requested string.
   1174  **/
   1175 const char* TextureViewUtilities::getGLSLTypeForSamplerType(const _sampler_type sampler_type)
   1176 {
   1177 	const char* result = "";
   1178 
   1179 	switch (sampler_type)
   1180 	{
   1181 	case SAMPLER_TYPE_FLOAT:
   1182 		result = "sampler2D";
   1183 		break;
   1184 	case SAMPLER_TYPE_SIGNED_INTEGER:
   1185 		result = "isampler2D";
   1186 		break;
   1187 	case SAMPLER_TYPE_UNSIGNED_INTEGER:
   1188 		result = "usampler2D";
   1189 		break;
   1190 
   1191 	default:
   1192 	{
   1193 		TCU_FAIL("Unrecognized sampler type");
   1194 	}
   1195 	} /* switch (sampler_type) */
   1196 
   1197 	return result;
   1198 }
   1199 
   1200 /** Returns a vector of texture+view internalformat combinations that are known to be incompatible.
   1201  *
   1202  *  @return Requested information.
   1203  **/
   1204 TextureViewUtilities::_incompatible_internalformat_pairs TextureViewUtilities::
   1205 	getIllegalTextureAndViewInternalformatCombinations()
   1206 {
   1207 	TextureViewUtilities::_incompatible_internalformat_pairs result;
   1208 
   1209 	/* Iterate in two loops over the set of supported internalformats */
   1210 	for (int n_texture_internalformat = 0;
   1211 		 n_texture_internalformat <
   1212 		 (n_internalformat_view_compatibility_array_entries / 2); /* the array stores two values per entry */
   1213 		 ++n_texture_internalformat)
   1214 	{
   1215 		glw::GLenum src_internalformat = internalformat_view_compatibility_array[(n_texture_internalformat * 2) + 0];
   1216 		_view_class src_view_class =
   1217 			(_view_class)internalformat_view_compatibility_array[(n_texture_internalformat * 2) + 1];
   1218 
   1219 		for (int n_view_internalformat = n_texture_internalformat + 1;
   1220 			 n_view_internalformat < (n_internalformat_view_compatibility_array_entries >> 1); ++n_view_internalformat)
   1221 		{
   1222 			glw::GLenum view_internalformat = internalformat_view_compatibility_array[(n_view_internalformat * 2) + 0];
   1223 			_view_class view_view_class =
   1224 				(_view_class)internalformat_view_compatibility_array[(n_view_internalformat * 2) + 1];
   1225 
   1226 			if (src_view_class != view_view_class)
   1227 			{
   1228 				result.push_back(_internalformat_pair(src_internalformat, view_internalformat));
   1229 			}
   1230 		} /* for (all internalformats we can use for the texture view) */
   1231 	}	 /* for (all internalformats we can use for the parent texture) */
   1232 
   1233 	return result;
   1234 }
   1235 
   1236 /** Returns a vector of texture+view target texture combinations that are known to be incompatible.
   1237  *
   1238  *  @return Requested information.
   1239  **/
   1240 TextureViewUtilities::_incompatible_texture_target_pairs TextureViewUtilities::
   1241 	getIllegalTextureAndViewTargetCombinations()
   1242 {
   1243 	_incompatible_texture_target_pairs result;
   1244 
   1245 	/* Iterate through all combinations of texture targets and store those that are
   1246 	 * reported as invalid
   1247 	 */
   1248 	for (unsigned int n_parent_texture_target = 0; n_parent_texture_target < n_valid_texture_targets;
   1249 		 ++n_parent_texture_target)
   1250 	{
   1251 		glw::GLenum parent_texture_target = valid_texture_targets[n_parent_texture_target];
   1252 
   1253 		for (unsigned int n_view_texture_target = 0; n_view_texture_target < n_valid_texture_targets;
   1254 			 ++n_view_texture_target)
   1255 		{
   1256 			glw::GLenum view_texture_target = valid_texture_targets[n_view_texture_target];
   1257 
   1258 			if (!isLegalTextureTargetForTextureView(parent_texture_target, view_texture_target))
   1259 			{
   1260 				result.push_back(_internalformat_pair(parent_texture_target, view_texture_target));
   1261 			}
   1262 		} /* for (all texture targets considered for views) */
   1263 	}	 /* for (all texture targets considered for parent texture) */
   1264 
   1265 	return result;
   1266 }
   1267 
   1268 /** Returns internalformats associated with user-specified view class.
   1269  *
   1270  *  @param view_class View class to use for the query.
   1271  *
   1272  *  @return Requested information.
   1273  **/
   1274 TextureViewUtilities::_internalformats TextureViewUtilities::getInternalformatsFromViewClass(_view_class view_class)
   1275 {
   1276 	_internalformats result;
   1277 
   1278 	/* Iterate over the data array and push those internalformats that match the requested view class */
   1279 	const unsigned int n_array_elements = n_internalformat_view_compatibility_array_entries;
   1280 
   1281 	for (unsigned int n_array_pair = 0; n_array_pair < (n_array_elements >> 1); ++n_array_pair)
   1282 	{
   1283 		const glw::GLenum internalformat = internalformat_view_compatibility_array[n_array_pair * 2 + 0];
   1284 		const _view_class current_view_class =
   1285 			(_view_class)internalformat_view_compatibility_array[n_array_pair * 2 + 1];
   1286 
   1287 		if (current_view_class == view_class)
   1288 		{
   1289 			result.push_back(internalformat);
   1290 		}
   1291 	} /* for (all pairs in the data array) */
   1292 
   1293 	return result;
   1294 }
   1295 
   1296 /** Returns a string defining user-specified internalformat.
   1297  *
   1298  *  Throws a TestError exception if @param internalformat was not recognized.
   1299  *
   1300  *  @param internalformat Internalformat to use for the query.
   1301  *
   1302  *  @return Requested string.
   1303  **/
   1304 const char* TextureViewUtilities::getInternalformatString(const glw::GLenum internalformat)
   1305 {
   1306 	const char* result = "[?]";
   1307 
   1308 	switch (internalformat)
   1309 	{
   1310 	case GL_RGBA32F:
   1311 		result = "GL_RGBA32F";
   1312 		break;
   1313 	case GL_RGBA32I:
   1314 		result = "GL_RGBA32I";
   1315 		break;
   1316 	case GL_RGBA32UI:
   1317 		result = "GL_RGBA32UI";
   1318 		break;
   1319 	case GL_RGBA16:
   1320 		result = "GL_RGBA16";
   1321 		break;
   1322 	case GL_RGBA16F:
   1323 		result = "GL_RGBA16F";
   1324 		break;
   1325 	case GL_RGBA16I:
   1326 		result = "GL_RGBA16I";
   1327 		break;
   1328 	case GL_RGBA16UI:
   1329 		result = "GL_RGBA16UI";
   1330 		break;
   1331 	case GL_RGBA8:
   1332 		result = "GL_RGBA8";
   1333 		break;
   1334 	case GL_RGBA8I:
   1335 		result = "GL_RGBA8I";
   1336 		break;
   1337 	case GL_RGBA8UI:
   1338 		result = "GL_RGBA8UI";
   1339 		break;
   1340 	case GL_SRGB8_ALPHA8:
   1341 		result = "GL_SRGB8_ALPHA8";
   1342 		break;
   1343 	case GL_RGB10_A2:
   1344 		result = "GL_RGB10_A2";
   1345 		break;
   1346 	case GL_RGB10_A2UI:
   1347 		result = "GL_RGB10_A2UI";
   1348 		break;
   1349 	case GL_RGB5_A1:
   1350 		result = "GL_RGB5_A1";
   1351 		break;
   1352 	case GL_RGBA4:
   1353 		result = "GL_RGBA4";
   1354 		break;
   1355 	case GL_R11F_G11F_B10F:
   1356 		result = "GL_R11F_G11F_B10F";
   1357 		break;
   1358 	case GL_RGB565:
   1359 		result = "GL_RGB565";
   1360 		break;
   1361 	case GL_RG32F:
   1362 		result = "GL_RG32F";
   1363 		break;
   1364 	case GL_RG32I:
   1365 		result = "GL_RG32I";
   1366 		break;
   1367 	case GL_RG32UI:
   1368 		result = "GL_RG32UI";
   1369 		break;
   1370 	case GL_RG16:
   1371 		result = "GL_RG16";
   1372 		break;
   1373 	case GL_RG16F:
   1374 		result = "GL_RG16F";
   1375 		break;
   1376 	case GL_RG16I:
   1377 		result = "GL_RG16I";
   1378 		break;
   1379 	case GL_RG16UI:
   1380 		result = "GL_RG16UI";
   1381 		break;
   1382 	case GL_RG8:
   1383 		result = "GL_RG8";
   1384 		break;
   1385 	case GL_RG8I:
   1386 		result = "GL_RG8I";
   1387 		break;
   1388 	case GL_RG8UI:
   1389 		result = "GL_RG8UI";
   1390 		break;
   1391 	case GL_R32F:
   1392 		result = "GL_R32F";
   1393 		break;
   1394 	case GL_R32I:
   1395 		result = "GL_R32I";
   1396 		break;
   1397 	case GL_R32UI:
   1398 		result = "GL_R32UI";
   1399 		break;
   1400 	case GL_R16F:
   1401 		result = "GL_R16F";
   1402 		break;
   1403 	case GL_R16I:
   1404 		result = "GL_R16I";
   1405 		break;
   1406 	case GL_R16UI:
   1407 		result = "GL_R16UI";
   1408 		break;
   1409 	case GL_R16:
   1410 		result = "GL_R16";
   1411 		break;
   1412 	case GL_R8:
   1413 		result = "GL_R8";
   1414 		break;
   1415 	case GL_R8I:
   1416 		result = "GL_R8I";
   1417 		break;
   1418 	case GL_R8UI:
   1419 		result = "GL_R8UI";
   1420 		break;
   1421 	case GL_RGBA16_SNORM:
   1422 		result = "GL_RGBA16_SNORM";
   1423 		break;
   1424 	case GL_RGBA8_SNORM:
   1425 		result = "GL_RGBA8_SNORM";
   1426 		break;
   1427 	case GL_RGB32F:
   1428 		result = "GL_RGB32F";
   1429 		break;
   1430 	case GL_RGB32I:
   1431 		result = "GL_RGB32I";
   1432 		break;
   1433 	case GL_RGB32UI:
   1434 		result = "GL_RGB32UI";
   1435 		break;
   1436 	case GL_RGB16_SNORM:
   1437 		result = "GL_RGB16_SNORM";
   1438 		break;
   1439 	case GL_RGB16F:
   1440 		result = "GL_RGB16F";
   1441 		break;
   1442 	case GL_RGB16I:
   1443 		result = "GL_RGB16I";
   1444 		break;
   1445 	case GL_RGB16UI:
   1446 		result = "GL_RGB16UI";
   1447 		break;
   1448 	case GL_RGB16:
   1449 		result = "GL_RGB16";
   1450 		break;
   1451 	case GL_RGB8_SNORM:
   1452 		result = "GL_RGB8_SNORM";
   1453 		break;
   1454 	case GL_RGB8:
   1455 		result = "GL_RGB8";
   1456 		break;
   1457 	case GL_RGB8I:
   1458 		result = "GL_RGB8I";
   1459 		break;
   1460 	case GL_RGB8UI:
   1461 		result = "GL_RGB8UI";
   1462 		break;
   1463 	case GL_SRGB8:
   1464 		result = "GL_SRGB8";
   1465 		break;
   1466 	case GL_RGB9_E5:
   1467 		result = "GL_RGB9_E5";
   1468 		break;
   1469 	case GL_RG16_SNORM:
   1470 		result = "GL_RG16_SNORM";
   1471 		break;
   1472 	case GL_RG8_SNORM:
   1473 		result = "GL_RG8_SNORM";
   1474 		break;
   1475 	case GL_R16_SNORM:
   1476 		result = "GL_R16_SNORM";
   1477 		break;
   1478 	case GL_R8_SNORM:
   1479 		result = "GL_R8_SNORM";
   1480 		break;
   1481 	case GL_DEPTH_COMPONENT32F:
   1482 		result = "GL_DEPTH_COMPONENT32F";
   1483 		break;
   1484 	case GL_DEPTH_COMPONENT24:
   1485 		result = "GL_DEPTH_COMPONENT24";
   1486 		break;
   1487 	case GL_DEPTH_COMPONENT16:
   1488 		result = "GL_DEPTH_COMPONENT16";
   1489 		break;
   1490 	case GL_DEPTH32F_STENCIL8:
   1491 		result = "GL_DEPTH32F_STENCIL8";
   1492 		break;
   1493 	case GL_DEPTH24_STENCIL8:
   1494 		result = "GL_DEPTH24_STENCIL8";
   1495 		break;
   1496 	case GL_COMPRESSED_RED_RGTC1:
   1497 		result = "GL_COMPRESSED_RED_RGTC1";
   1498 		break;
   1499 	case GL_COMPRESSED_SIGNED_RED_RGTC1:
   1500 		result = "GL_COMPRESSED_SIGNED_RED_RGTC1";
   1501 		break;
   1502 	case GL_COMPRESSED_RG_RGTC2:
   1503 		result = "GL_COMPRESSED_RG_RGTC2";
   1504 		break;
   1505 	case GL_COMPRESSED_SIGNED_RG_RGTC2:
   1506 		result = "GL_COMPRESSED_SIGNED_RG_RGTC2";
   1507 		break;
   1508 	case GL_COMPRESSED_RGBA_BPTC_UNORM:
   1509 		result = "GL_COMPRESSED_RGBA_BPTC_UNORM";
   1510 		break;
   1511 	case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
   1512 		result = "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM";
   1513 		break;
   1514 	case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
   1515 		result = "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT";
   1516 		break;
   1517 	case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
   1518 		result = "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT";
   1519 		break;
   1520 	case GL_COMPRESSED_RGB8_ETC2:
   1521 		result = "GL_COMPRESSED_RGB8_ETC2";
   1522 		break;
   1523 	case GL_COMPRESSED_SRGB8_ETC2:
   1524 		result = "GL_COMPRESSED_SRGB8_ETC2";
   1525 		break;
   1526 	case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
   1527 		result = "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2";
   1528 		break;
   1529 	case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
   1530 		result = "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2";
   1531 		break;
   1532 	case GL_COMPRESSED_RGBA8_ETC2_EAC:
   1533 		result = "GL_COMPRESSED_RGBA8_ETC2_EAC";
   1534 		break;
   1535 	case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
   1536 		result = "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC";
   1537 		break;
   1538 	case GL_COMPRESSED_R11_EAC:
   1539 		result = "GL_COMPRESSED_R11_EAC";
   1540 		break;
   1541 	case GL_COMPRESSED_SIGNED_R11_EAC:
   1542 		result = "GL_COMPRESSED_SIGNED_R11_EAC";
   1543 		break;
   1544 	case GL_COMPRESSED_RG11_EAC:
   1545 		result = "GL_COMPRESSED_RG11_EAC";
   1546 		break;
   1547 	case GL_COMPRESSED_SIGNED_RG11_EAC:
   1548 		result = "GL_COMPRESSED_SIGNED_RG11_EAC";
   1549 		break;
   1550 
   1551 	default:
   1552 		TCU_FAIL("Unrecognized internalformat");
   1553 	}
   1554 
   1555 	return result;
   1556 }
   1557 
   1558 /** Returns all texture+view internalformat pairs that are valid in light of GL_ARB_texture_view specification.
   1559  *
   1560  *  @return As described.
   1561  **/
   1562 TextureViewUtilities::_compatible_internalformat_pairs TextureViewUtilities::
   1563 	getLegalTextureAndViewInternalformatCombinations()
   1564 {
   1565 	_compatible_internalformat_pairs result;
   1566 
   1567 	/* Iterate over all view classes */
   1568 	for (int current_view_class_it = static_cast<int>(VIEW_CLASS_FIRST);
   1569 		 current_view_class_it != static_cast<int>(VIEW_CLASS_COUNT); current_view_class_it++)
   1570 	{
   1571 		_view_class		 current_view_class			= static_cast<_view_class>(current_view_class_it);
   1572 		_internalformats view_class_internalformats = getInternalformatsFromViewClass(current_view_class);
   1573 
   1574 		/* Store all combinations in the result vector */
   1575 		for (_internalformats_const_iterator left_iterator = view_class_internalformats.begin();
   1576 			 left_iterator != view_class_internalformats.end(); left_iterator++)
   1577 		{
   1578 			for (_internalformats_const_iterator right_iterator = view_class_internalformats.begin();
   1579 				 right_iterator != view_class_internalformats.end(); ++right_iterator)
   1580 			{
   1581 				result.push_back(_internalformat_pair(*left_iterator, *right_iterator));
   1582 			} /* for (all internalformats to be used as right-side values) */
   1583 		}	 /* for (all internalformats to be used as left-side values) */
   1584 	}		  /* for (all view classes) */
   1585 
   1586 	return result;
   1587 }
   1588 
   1589 /** Returns all valid texture+view texture targets pairs.
   1590  *
   1591  *  @return As per description.
   1592  **/
   1593 TextureViewUtilities::_compatible_texture_target_pairs TextureViewUtilities::getLegalTextureAndViewTargetCombinations()
   1594 {
   1595 	_compatible_texture_target_pairs result;
   1596 
   1597 	/* Iterate over all texture targets valid for a glTextureView() call. Consider each one of them as
   1598 	 * original texture target.
   1599 	 */
   1600 	for (unsigned int n_original_texture_target = 0; n_original_texture_target < n_valid_texture_targets;
   1601 		 ++n_original_texture_target)
   1602 	{
   1603 		const glw::GLenum original_texture_target = valid_texture_targets[n_original_texture_target];
   1604 
   1605 		/* Iterate again, but this time consider each texture target as a valid new target */
   1606 		for (unsigned int n_compatible_texture_target = 0; n_compatible_texture_target < n_valid_texture_targets;
   1607 			 ++n_compatible_texture_target)
   1608 		{
   1609 			const glw::GLenum view_texture_target = valid_texture_targets[n_compatible_texture_target];
   1610 
   1611 			if (TextureViewUtilities::isLegalTextureTargetForTextureView(original_texture_target, view_texture_target))
   1612 			{
   1613 				result.push_back(_texture_target_pair(original_texture_target, view_texture_target));
   1614 			}
   1615 		} /* for (all texture targets that are potentially compatible) */
   1616 	}	 /* for (all original texture targets) */
   1617 
   1618 	return result;
   1619 }
   1620 
   1621 /** Returns major & minor version for user-specified CTS rendering context type.
   1622  *
   1623  *  @param context_type      CTS rendering context type.
   1624  *  @param out_major_version Deref will be used to store major version. Must not be NULL.
   1625  *  @param out_minor_version Deref will be used to store minor version. Must not be NULL.
   1626  *
   1627  **/
   1628 void TextureViewUtilities::getMajorMinorVersionFromContextVersion(const glu::ContextType& context_type,
   1629 																  glw::GLint*			  out_major_version,
   1630 																  glw::GLint*			  out_minor_version)
   1631 {
   1632 	if (context_type.getAPI() == glu::ApiType::core(4, 0))
   1633 	{
   1634 		*out_major_version = 4;
   1635 		*out_minor_version = 0;
   1636 	}
   1637 	else if (context_type.getAPI() == glu::ApiType::core(4, 1))
   1638 	{
   1639 		*out_major_version = 4;
   1640 		*out_minor_version = 1;
   1641 	}
   1642 	else if (context_type.getAPI() == glu::ApiType::core(4, 2))
   1643 	{
   1644 		*out_major_version = 4;
   1645 		*out_minor_version = 2;
   1646 	}
   1647 	else if (context_type.getAPI() == glu::ApiType::core(4, 3))
   1648 	{
   1649 		*out_major_version = 4;
   1650 		*out_minor_version = 3;
   1651 	}
   1652 	else if (context_type.getAPI() == glu::ApiType::core(4, 4))
   1653 	{
   1654 		*out_major_version = 4;
   1655 		*out_minor_version = 4;
   1656 	}
   1657 	else if (context_type.getAPI() == glu::ApiType::core(4, 5))
   1658 	{
   1659 		*out_major_version = 4;
   1660 		*out_minor_version = 5;
   1661 	}
   1662 	else if (context_type.getAPI() == glu::ApiType::core(4, 6))
   1663 	{
   1664 		*out_major_version = 4;
   1665 		*out_minor_version = 6;
   1666 	}
   1667 	else
   1668 	{
   1669 		TCU_FAIL("Unrecognized rendering context version");
   1670 	}
   1671 }
   1672 
   1673 /** Tells which sampler can be used to sample a texture defined with user-specified
   1674  *  internalformat.
   1675  *
   1676  *  Supports both compressed and non-compressed internalformats.
   1677  *  Throws TestError exception if @param internalformat was not recognized.
   1678  *
   1679  *  @param internalformat Internalformat to use for the query.
   1680  *
   1681  *  @return Requested information.
   1682  **/
   1683 _sampler_type TextureViewUtilities::getSamplerTypeForInternalformat(const glw::GLenum internalformat)
   1684 {
   1685 	_sampler_type result = SAMPLER_TYPE_UNDEFINED;
   1686 
   1687 	/* Compressed internalformats not supported at the moment */
   1688 
   1689 	switch (internalformat)
   1690 	{
   1691 	case GL_COMPRESSED_RED_RGTC1:
   1692 	case GL_COMPRESSED_SIGNED_RED_RGTC1:
   1693 	case GL_COMPRESSED_RG_RGTC2:
   1694 	case GL_COMPRESSED_SIGNED_RG_RGTC2:
   1695 	case GL_COMPRESSED_RGBA_BPTC_UNORM:
   1696 	case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
   1697 	case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
   1698 	case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
   1699 	case GL_DEPTH_COMPONENT16:
   1700 	case GL_DEPTH_COMPONENT24:
   1701 	case GL_DEPTH_COMPONENT32F:
   1702 	case GL_RGBA16:
   1703 	case GL_RGBA16_SNORM:
   1704 	case GL_RGBA16F:
   1705 	case GL_RGBA32F:
   1706 	case GL_RGBA4:
   1707 	case GL_RGBA8:
   1708 	case GL_RGBA8_SNORM:
   1709 	case GL_RGB10_A2:
   1710 	case GL_RGB16:
   1711 	case GL_RGB16_SNORM:
   1712 	case GL_RGB16F:
   1713 	case GL_RGB32F:
   1714 	case GL_RGB5_A1:
   1715 	case GL_RGB565:
   1716 	case GL_RGB8:
   1717 	case GL_RGB8_SNORM:
   1718 	case GL_RGB9_E5:
   1719 	case GL_RG16:
   1720 	case GL_RG16_SNORM:
   1721 	case GL_RG16F:
   1722 	case GL_RG32F:
   1723 	case GL_RG8:
   1724 	case GL_RG8_SNORM:
   1725 	case GL_R11F_G11F_B10F:
   1726 	case GL_R16:
   1727 	case GL_R16F:
   1728 	case GL_R16_SNORM:
   1729 	case GL_R32F:
   1730 	case GL_R8:
   1731 	case GL_R8_SNORM:
   1732 	case GL_SRGB8_ALPHA8:
   1733 	case GL_SRGB8:
   1734 	{
   1735 		result = SAMPLER_TYPE_FLOAT;
   1736 
   1737 		break;
   1738 	}
   1739 
   1740 	case GL_RGB10_A2UI:
   1741 	case GL_RGBA32UI:
   1742 	case GL_RGBA16UI:
   1743 	case GL_RGBA8UI:
   1744 	case GL_RGB16UI:
   1745 	case GL_RGB32UI:
   1746 	case GL_RGB8UI:
   1747 	case GL_RG16UI:
   1748 	case GL_RG32UI:
   1749 	case GL_RG8UI:
   1750 	case GL_R16UI:
   1751 	case GL_R32UI:
   1752 	case GL_R8UI:
   1753 	{
   1754 		result = SAMPLER_TYPE_UNSIGNED_INTEGER;
   1755 
   1756 		break;
   1757 	}
   1758 
   1759 	case GL_RGBA16I:
   1760 	case GL_RGBA32I:
   1761 	case GL_RGBA8I:
   1762 	case GL_RGB16I:
   1763 	case GL_RGB32I:
   1764 	case GL_RGB8I:
   1765 	case GL_RG16I:
   1766 	case GL_RG32I:
   1767 	case GL_RG8I:
   1768 	case GL_R16I:
   1769 	case GL_R32I:
   1770 	case GL_R8I:
   1771 	{
   1772 		result = SAMPLER_TYPE_SIGNED_INTEGER;
   1773 
   1774 		break;
   1775 	}
   1776 
   1777 	default:
   1778 	{
   1779 		TCU_FAIL("Unrecognized internalformat");
   1780 	}
   1781 	} /* switch (interalformat) */
   1782 
   1783 	return result;
   1784 }
   1785 
   1786 /** Tells how many bytes are required to define a texture mip-map using
   1787  *  user-specified internalformat and type, assuming user-defined mip-map
   1788  *  resolution. Compressed internalformats are NOT supported.
   1789  *
   1790  *  Throws TestError exception if @param internalformat or @param type are
   1791  *  found invalid.
   1792  *
   1793  *  @param internalformat Internalformat to use for the query.
   1794  *  @param type           Type to use for the query.
   1795  *  @param width          Mip-map width to use for the query.
   1796  *  @param height         Mip-map height to use for the query.
   1797  *
   1798  *  @return Requested information.
   1799  **/
   1800 unsigned int TextureViewUtilities::getTextureDataSize(const glw::GLenum internalformat, const glw::GLenum type,
   1801 													  const unsigned int width, const unsigned int height)
   1802 {
   1803 	unsigned int internalformat_rgba_size[4] = { 0 };
   1804 	unsigned int type_rgba_size[4]			 = { 0 };
   1805 	unsigned int texel_size					 = 0;
   1806 
   1807 	TextureViewUtilities::getComponentSizeForInternalformat(internalformat, internalformat_rgba_size);
   1808 	TextureViewUtilities::getComponentSizeForType(type, type_rgba_size);
   1809 
   1810 	if (internalformat_rgba_size[0] == 0)
   1811 	{
   1812 		type_rgba_size[0] = 0;
   1813 	}
   1814 
   1815 	if (internalformat_rgba_size[1] == 0)
   1816 	{
   1817 		type_rgba_size[1] = 0;
   1818 	}
   1819 
   1820 	if (internalformat_rgba_size[2] == 0)
   1821 	{
   1822 		type_rgba_size[2] = 0;
   1823 	}
   1824 
   1825 	if (internalformat_rgba_size[3] == 0)
   1826 	{
   1827 		type_rgba_size[3] = 0;
   1828 	}
   1829 
   1830 	texel_size = type_rgba_size[0] + type_rgba_size[1] + type_rgba_size[2] + type_rgba_size[3];
   1831 
   1832 	/* Current implementation assumes we do not need to use bit resolution when
   1833 	 * preparing texel data. Make extra sure we're not wrong. */
   1834 	DE_ASSERT((texel_size % 8) == 0);
   1835 
   1836 	texel_size /= 8; /* bits per byte */
   1837 
   1838 	return texel_size * width * height;
   1839 }
   1840 
   1841 /** Returns a string corresponding to a GL enum describing a texture target.
   1842  *
   1843  *  @return As per description or "[?]" if the enum was not recognized.
   1844  **/
   1845 const char* TextureViewUtilities::getTextureTargetString(const glw::GLenum texture_target)
   1846 {
   1847 	const char* result = "[?]";
   1848 
   1849 	switch (texture_target)
   1850 	{
   1851 	case GL_TEXTURE_1D:
   1852 		result = "GL_TEXTURE_1D";
   1853 		break;
   1854 	case GL_TEXTURE_1D_ARRAY:
   1855 		result = "GL_TEXTURE_1D_ARRAY";
   1856 		break;
   1857 	case GL_TEXTURE_2D:
   1858 		result = "GL_TEXTURE_2D";
   1859 		break;
   1860 	case GL_TEXTURE_2D_ARRAY:
   1861 		result = "GL_TEXTURE_2D_ARRAY";
   1862 		break;
   1863 	case GL_TEXTURE_2D_MULTISAMPLE:
   1864 		result = "GL_TEXTURE_2D_MULTISAMPLE";
   1865 		break;
   1866 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1867 		result = "GL_TEXTURE_2D_MULTISAMPLE_ARRAY";
   1868 		break;
   1869 	case GL_TEXTURE_3D:
   1870 		result = "GL_TEXTURE_3D";
   1871 		break;
   1872 	case GL_TEXTURE_BUFFER:
   1873 		result = "GL_TEXTURE_BUFFER";
   1874 		break;
   1875 	case GL_TEXTURE_CUBE_MAP:
   1876 		result = "GL_TEXTURE_CUBE_MAP";
   1877 		break;
   1878 	case GL_TEXTURE_CUBE_MAP_ARRAY:
   1879 		result = "GL_TEXTURE_CUBE_MAP_ARRAY";
   1880 		break;
   1881 	case GL_TEXTURE_RECTANGLE:
   1882 		result = "GL_TEXTURE_RECTANGLE";
   1883 		break;
   1884 	}
   1885 
   1886 	return result;
   1887 }
   1888 
   1889 /** Returns GL type that can be used to define a texture mip-map defined
   1890  *  with an internalformat of @param internalformat.
   1891  *
   1892  *  Throws TestError exception if @param internalformat was found to be invalid.
   1893  *
   1894  *  @param internalformat Internalformat to use for the query.
   1895  *
   1896  *  @return Requested information.
   1897  **/
   1898 glw::GLenum TextureViewUtilities::getTypeCompatibleWithInternalformat(const glw::GLenum internalformat)
   1899 {
   1900 	glw::GLenum result = GL_NONE;
   1901 
   1902 	/* Compressed internalformats not supported at the moment */
   1903 
   1904 	switch (internalformat)
   1905 	{
   1906 	case GL_RGBA8_SNORM:
   1907 	case GL_RGB8_SNORM:
   1908 	case GL_RG8_SNORM:
   1909 	case GL_R8_SNORM:
   1910 	case GL_RGBA8I:
   1911 	case GL_RGB8I:
   1912 	case GL_RG8I:
   1913 	case GL_R8I:
   1914 	{
   1915 		result = GL_BYTE;
   1916 
   1917 		break;
   1918 	}
   1919 
   1920 	case GL_DEPTH24_STENCIL8:
   1921 	{
   1922 		result = GL_UNSIGNED_INT_24_8;
   1923 
   1924 		break;
   1925 	}
   1926 
   1927 	case GL_DEPTH32F_STENCIL8:
   1928 	{
   1929 		result = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
   1930 
   1931 		break;
   1932 	}
   1933 
   1934 	case GL_RGBA16F:
   1935 	case GL_RGB16F:
   1936 	case GL_RG16F:
   1937 	case GL_R16F:
   1938 	{
   1939 		result = GL_HALF_FLOAT;
   1940 
   1941 		break;
   1942 	}
   1943 
   1944 	case GL_DEPTH_COMPONENT32F:
   1945 	case GL_RGBA32F:
   1946 	case GL_RGB32F:
   1947 	case GL_RG32F:
   1948 	case GL_R11F_G11F_B10F:
   1949 	case GL_R32F:
   1950 	{
   1951 		result = GL_FLOAT;
   1952 
   1953 		break;
   1954 	}
   1955 
   1956 	case GL_RGBA16_SNORM:
   1957 	case GL_RGB16_SNORM:
   1958 	case GL_RG16_SNORM:
   1959 	case GL_R16_SNORM:
   1960 	{
   1961 		result = GL_SHORT;
   1962 
   1963 		break;
   1964 	}
   1965 
   1966 	case GL_RGBA4:
   1967 	case GL_RGBA8:
   1968 	case GL_RGB10_A2:
   1969 	case GL_RGB5_A1:
   1970 	case GL_RGB565:
   1971 	case GL_RGB8:
   1972 	case GL_RGB9_E5:
   1973 	case GL_RG8:
   1974 	case GL_R8:
   1975 	case GL_SRGB8_ALPHA8:
   1976 	case GL_SRGB8:
   1977 	case GL_RGBA8UI:
   1978 	case GL_RGB8UI:
   1979 	case GL_RG8UI:
   1980 	case GL_R8UI:
   1981 	{
   1982 		result = GL_UNSIGNED_BYTE;
   1983 
   1984 		break;
   1985 	}
   1986 
   1987 	case GL_R16I:
   1988 	case GL_RGBA16I:
   1989 	case GL_RGB16I:
   1990 	case GL_RG16I:
   1991 	{
   1992 		result = GL_SHORT;
   1993 
   1994 		break;
   1995 	}
   1996 
   1997 	case GL_DEPTH_COMPONENT16:
   1998 	case GL_RGBA16:
   1999 	case GL_RGB16:
   2000 	case GL_RG16:
   2001 	case GL_R16:
   2002 	case GL_RGBA16UI:
   2003 	case GL_RGB16UI:
   2004 	case GL_RG16UI:
   2005 	case GL_R16UI:
   2006 	{
   2007 		result = GL_UNSIGNED_SHORT;
   2008 
   2009 		break;
   2010 	}
   2011 
   2012 	case GL_RGBA32I:
   2013 	case GL_RGB32I:
   2014 	case GL_RG32I:
   2015 	case GL_R32I:
   2016 	{
   2017 		result = GL_INT;
   2018 
   2019 		break;
   2020 	}
   2021 
   2022 	case GL_DEPTH_COMPONENT24:
   2023 	case GL_RGBA32UI:
   2024 	case GL_RGB32UI:
   2025 	case GL_RG32UI:
   2026 	case GL_R32UI:
   2027 	{
   2028 		result = GL_UNSIGNED_INT;
   2029 
   2030 		break;
   2031 	}
   2032 
   2033 	case GL_RGB10_A2UI:
   2034 	{
   2035 		result = GL_UNSIGNED_INT_2_10_10_10_REV;
   2036 
   2037 		break;
   2038 	}
   2039 
   2040 	default:
   2041 	{
   2042 		TCU_FAIL("Unrecognized internalformat");
   2043 	}
   2044 	} /* switch (interalformat) */
   2045 
   2046 	return result;
   2047 }
   2048 
   2049 /** Tells what view class is the user-specified internalformat associated with.
   2050  *
   2051  *  Implements Table 8.21 from OpenGL Specification 4.3
   2052  *
   2053  *  @param internalformat Internalformat to use for the query.
   2054  *
   2055  *  @return Requested information or VIEW_CLASS_UNDEFINED if @param internalformat
   2056  *          has not been recognized.
   2057  **/
   2058 _view_class TextureViewUtilities::getViewClassForInternalformat(const glw::GLenum internalformat)
   2059 {
   2060 	_view_class result = VIEW_CLASS_UNDEFINED;
   2061 
   2062 	/* Note that n_internalformat_view_compatibility_array_entries needs to be divided by 2
   2063 	 * because the value refers to a total number of entries in the array, not to the number
   2064 	 * of pairs that can be read.
   2065 	 */
   2066 	for (int n_entry = 0; n_entry < (n_internalformat_view_compatibility_array_entries >> 1); n_entry++)
   2067 	{
   2068 		glw::GLenum array_internalformat = internalformat_view_compatibility_array[(n_entry * 2) + 0];
   2069 		_view_class view_class			 = (_view_class)internalformat_view_compatibility_array[(n_entry * 2) + 1];
   2070 
   2071 		if (array_internalformat == internalformat)
   2072 		{
   2073 			result = view_class;
   2074 
   2075 			break;
   2076 		}
   2077 	} /* for (all pairs in data array) */
   2078 
   2079 	return result;
   2080 }
   2081 
   2082 /** Initializes texture storage for either an immutable or mutable texture object,
   2083  *  depending on configuration of the test run the storage is to be initialized for.
   2084  *
   2085  *  @param gl                          GL entry-points to use for storage initialization.
   2086  *  @param init_mutable_to             true if a mutable texture storage should be initialized,
   2087  *                                     false to initialize immutable texture storage.
   2088  *  @param texture_target              Texture target to be used.
   2089  *  @param texture_depth               Depth to be used for texture storage. Only used
   2090  *                                     for texture targets that use the depth information.
   2091  *  @param texture_height              Height to be used for texture storage. Only used
   2092  *                                     for texture targets that use the height information.
   2093  *  @param texture_width               Width to be used for texture storage.
   2094  *  @param texture_internalformat      Internalformat to be used for texture storage.
   2095  *  @param texture_format              Format to be used for texture storage.
   2096  *  @param texture_type                Type to be used for texture storage.
   2097  *  @param n_levels_needed             Amount of mip-map levels that should be used for texture storage.
   2098  *                                     Only used for texture targets that support mip-maps.
   2099  *  @param n_cubemaps_needed           Amount of cube-maps to be used for initialization of cube map
   2100  *                                     array texture storage. Only used if @param texture_internalformat
   2101  *                                     is set to GL_TEXTURE_CUBE_MAP_ARRAY.
   2102  *  @param bo_id                       ID of a buffer object to be used for initialization of
   2103  *                                     buffer texture storage. Only used if @param texture_internalformat
   2104  *                                     is set to GL_TEXTURE_BUFFEER.
   2105  *
   2106  **/
   2107 void TextureViewUtilities::initTextureStorage(const glw::Functions& gl, bool init_mutable_to,
   2108 											  glw::GLenum texture_target, glw::GLint texture_depth,
   2109 											  glw::GLint texture_height, glw::GLint texture_width,
   2110 											  glw::GLenum texture_internalformat, glw::GLenum texture_format,
   2111 											  glw::GLenum texture_type, unsigned int n_levels_needed,
   2112 											  unsigned int n_cubemaps_needed, glw::GLint bo_id)
   2113 {
   2114 	const glw::GLenum cubemap_texture_targets[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
   2115 													GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
   2116 													GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
   2117 	const unsigned int n_cubemap_texture_targets = sizeof(cubemap_texture_targets) / sizeof(cubemap_texture_targets[0]);
   2118 
   2119 	/* If we're going to be initializing a multisample texture object,
   2120 	 * determine how many samples can be used for GL_RGBA8 internalformat,
   2121 	 * given texture target that is of our interest */
   2122 	glw::GLint gl_max_color_texture_samples_value = 0;
   2123 
   2124 	gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &gl_max_color_texture_samples_value);
   2125 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES");
   2126 
   2127 	if (texture_target == GL_TEXTURE_BUFFER)
   2128 	{
   2129 		gl.texBuffer(GL_TEXTURE_BUFFER, texture_internalformat, bo_id);
   2130 
   2131 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexBuffer() call failed for GL_TEXTURE_BUFFER target");
   2132 	}
   2133 	else if (init_mutable_to)
   2134 	{
   2135 		for (unsigned int n_level = 0; n_level < n_levels_needed; ++n_level)
   2136 		{
   2137 			/* If level != 0 and we're trying to initialize a texture target which
   2138 			 * only accepts a single level, leave now
   2139 			 */
   2140 			if (n_level != 0 &&
   2141 				(texture_target == GL_TEXTURE_RECTANGLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
   2142 				 texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || texture_target == GL_TEXTURE_BUFFER))
   2143 			{
   2144 				break;
   2145 			}
   2146 
   2147 			/* Initialize mutable texture storage */
   2148 			switch (texture_target)
   2149 			{
   2150 			case GL_TEXTURE_1D:
   2151 			{
   2152 				gl.texImage1D(texture_target, n_level, texture_internalformat, texture_width >> n_level, 0, /* border */
   2153 							  texture_format, texture_type, DE_NULL);										/* pixels */
   2154 
   2155 				GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D() call failed for GL_TEXTURE_1D texture target");
   2156 
   2157 				break;
   2158 			}
   2159 
   2160 			case GL_TEXTURE_1D_ARRAY:
   2161 			case GL_TEXTURE_2D:
   2162 			case GL_TEXTURE_RECTANGLE:
   2163 			{
   2164 				gl.texImage2D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
   2165 							  texture_height >> n_level, 0,			  /* border */
   2166 							  texture_format, texture_type, DE_NULL); /* pixels */
   2167 
   2168 				GLU_EXPECT_NO_ERROR(gl.getError(),
   2169 									(texture_target == GL_TEXTURE_1D_ARRAY) ?
   2170 										"glTexImage2D() call failed for GL_TEXTURE_1D_ARRAY texture target" :
   2171 										(texture_target == GL_TEXTURE_2D) ?
   2172 										"glTexImage2D() call failed for GL_TEXTURE_2D texture target" :
   2173 										"glTexImage2D() call failed for GL_TEXTURE_RECTANGLE texture target");
   2174 
   2175 				break;
   2176 			}
   2177 
   2178 			case GL_TEXTURE_2D_ARRAY:
   2179 			case GL_TEXTURE_3D:
   2180 			{
   2181 				gl.texImage3D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
   2182 							  texture_height >> n_level, texture_depth >> n_level, 0, /* border */
   2183 							  texture_format, texture_type, DE_NULL);				  /* pixels */
   2184 
   2185 				GLU_EXPECT_NO_ERROR(gl.getError(),
   2186 									(texture_target == GL_TEXTURE_2D_ARRAY) ?
   2187 										"glTexImage3D() call failed for GL_TEXTURE_2D_ARRAY texture target" :
   2188 										"glTexImage3D() call failed for GL_TEXTURE_3D texture target");
   2189 
   2190 				break;
   2191 			}
   2192 
   2193 			case GL_TEXTURE_2D_MULTISAMPLE:
   2194 			{
   2195 				gl.texImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_color_texture_samples_value,
   2196 										 texture_internalformat, texture_width >> n_level, texture_height >> n_level,
   2197 										 GL_TRUE); /* fixedsamplelocations */
   2198 
   2199 				GLU_EXPECT_NO_ERROR(
   2200 					gl.getError(),
   2201 					"glTexImage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
   2202 
   2203 				break;
   2204 			}
   2205 
   2206 			case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   2207 			{
   2208 				gl.texImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, gl_max_color_texture_samples_value,
   2209 										 texture_internalformat, texture_width >> n_level, texture_height >> n_level,
   2210 										 texture_depth >> n_level, GL_TRUE); /* fixedsamplelocations */
   2211 
   2212 				GLU_EXPECT_NO_ERROR(
   2213 					gl.getError(),
   2214 					"glTexImage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY texture target");
   2215 
   2216 				break;
   2217 			}
   2218 
   2219 			case GL_TEXTURE_CUBE_MAP:
   2220 			{
   2221 				for (unsigned int n_cubemap_texture_target = 0; n_cubemap_texture_target < n_cubemap_texture_targets;
   2222 					 ++n_cubemap_texture_target)
   2223 				{
   2224 					glw::GLenum cubemap_texture_target = cubemap_texture_targets[n_cubemap_texture_target];
   2225 
   2226 					gl.texImage2D(cubemap_texture_target, n_level, texture_internalformat, texture_width >> n_level,
   2227 								  texture_height >> n_level, 0,			  /* border */
   2228 								  texture_format, texture_type, DE_NULL); /* pixels */
   2229 
   2230 					GLU_EXPECT_NO_ERROR(gl.getError(),
   2231 										"glTexImage2D() call failed for one of the cube-map texture targets");
   2232 
   2233 					break;
   2234 				} /* for (all cube-map texture targets) */
   2235 
   2236 				break;
   2237 			}
   2238 
   2239 			case GL_TEXTURE_CUBE_MAP_ARRAY:
   2240 			{
   2241 				gl.texImage3D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
   2242 							  texture_height >> n_level, 6 /* layer-faces */ * n_cubemaps_needed, 0, /* border */
   2243 							  texture_format, texture_type, DE_NULL);								 /* pixels */
   2244 
   2245 				GLU_EXPECT_NO_ERROR(gl.getError(),
   2246 									"glTexImage3D() call failed for GL_TEXTURE_CUBE_MAP_ARRAY texture target");
   2247 
   2248 				break;
   2249 			}
   2250 
   2251 			default:
   2252 			{
   2253 				TCU_FAIL("Unrecognized texture target");
   2254 			}
   2255 			} /* switch (texture_target) */
   2256 		}	 /* for (all levels) */
   2257 	}		  /* if (texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT) */
   2258 	else
   2259 	{
   2260 		/* Initialize immutable texture storage */
   2261 		switch (texture_target)
   2262 		{
   2263 		case GL_TEXTURE_1D:
   2264 		{
   2265 			gl.texStorage1D(texture_target, n_levels_needed, texture_internalformat, texture_width);
   2266 
   2267 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed for GL_TEXTURE_1D texture target");
   2268 
   2269 			break;
   2270 		}
   2271 
   2272 		case GL_TEXTURE_1D_ARRAY:
   2273 		case GL_TEXTURE_2D:
   2274 		case GL_TEXTURE_CUBE_MAP:
   2275 		case GL_TEXTURE_RECTANGLE:
   2276 		{
   2277 			const unsigned n_levels = (texture_target == GL_TEXTURE_RECTANGLE) ? 1 : n_levels_needed;
   2278 
   2279 			gl.texStorage2D(texture_target, n_levels, texture_internalformat, texture_width, texture_height);
   2280 
   2281 			GLU_EXPECT_NO_ERROR(gl.getError(),
   2282 								(texture_target == GL_TEXTURE_1D_ARRAY) ?
   2283 									"glTexStorage2D() call failed for GL_TEXTURE_1D_ARRAY texture target" :
   2284 									(texture_target == GL_TEXTURE_2D) ?
   2285 									"glTexStorage2D() call failed for GL_TEXTURE_2D texture target" :
   2286 									(texture_target == GL_TEXTURE_CUBE_MAP) ?
   2287 									"glTexStorage2D() call failed for GL_TEXTURE_CUBE_MAP texture target" :
   2288 									"glTexStorage2D() call failed for GL_TEXTURE_RECTANGLE texture target");
   2289 
   2290 			break;
   2291 		}
   2292 
   2293 		case GL_TEXTURE_2D_ARRAY:
   2294 		case GL_TEXTURE_3D:
   2295 		{
   2296 			gl.texStorage3D(texture_target, n_levels_needed, texture_internalformat, texture_width, texture_height,
   2297 							texture_depth);
   2298 
   2299 			GLU_EXPECT_NO_ERROR(gl.getError(),
   2300 								(texture_target == GL_TEXTURE_2D_ARRAY) ?
   2301 									"glTexStorage3D() call failed for GL_TEXTURE_2D_ARRAY texture target" :
   2302 									"glTexStorage3D() call failed for GL_TEXTURE_3D texture target");
   2303 
   2304 			break;
   2305 		}
   2306 
   2307 		case GL_TEXTURE_2D_MULTISAMPLE:
   2308 		{
   2309 			gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_color_texture_samples_value,
   2310 									   texture_internalformat, texture_width, texture_height,
   2311 									   GL_TRUE); /* fixedsamplelocations */
   2312 
   2313 			GLU_EXPECT_NO_ERROR(gl.getError(),
   2314 								"glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
   2315 
   2316 			break;
   2317 		}
   2318 
   2319 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   2320 		{
   2321 			gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, gl_max_color_texture_samples_value,
   2322 									   texture_internalformat, texture_width, texture_height, texture_depth,
   2323 									   GL_TRUE); /* fixedsamplelocations */
   2324 
   2325 			GLU_EXPECT_NO_ERROR(
   2326 				gl.getError(),
   2327 				"glTexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY texture target");
   2328 
   2329 			break;
   2330 		}
   2331 
   2332 		case GL_TEXTURE_CUBE_MAP_ARRAY:
   2333 		{
   2334 			const unsigned int actual_texture_depth = 6 /* layer-faces */ * n_cubemaps_needed;
   2335 
   2336 			gl.texStorage3D(texture_target, n_levels_needed, texture_internalformat, texture_width, texture_height,
   2337 							actual_texture_depth);
   2338 
   2339 			GLU_EXPECT_NO_ERROR(gl.getError(),
   2340 								"glTexStorage3D() call failed for GL_TEXTURE_CUBE_MAP_ARRAY texture target");
   2341 
   2342 			break;
   2343 		}
   2344 
   2345 		default:
   2346 		{
   2347 			TCU_FAIL("Unrecognized texture target");
   2348 		}
   2349 		} /* switch (texture_target) */
   2350 	}
   2351 }
   2352 
   2353 /** Tells whether a parent texture object, storage of which uses @param original_internalformat
   2354  *  internalformat, can be used to generate a texture view using @param view_internalformat
   2355  *  internalformat.
   2356  *
   2357  *  @param original_internalformat Internalformat used for parent texture object storage.
   2358  *  @param view_internalformat     Internalformat to be used for view texture object storage.
   2359  *
   2360  *  @return true if the internalformats are compatible, false otherwise.
   2361  **/
   2362 bool TextureViewUtilities::isInternalformatCompatibleForTextureView(glw::GLenum original_internalformat,
   2363 																	glw::GLenum view_internalformat)
   2364 {
   2365 	const _view_class original_internalformat_view_class = getViewClassForInternalformat(original_internalformat);
   2366 	const _view_class view_internalformat_view_class	 = getViewClassForInternalformat(view_internalformat);
   2367 
   2368 	return (original_internalformat_view_class == view_internalformat_view_class);
   2369 }
   2370 
   2371 /** Tells whether user-specified internalformat is compressed.
   2372  *
   2373  *  @param internalformat Internalformat to use for the query.
   2374  *
   2375  *  @return true if @param internalformat is a known compressed internalformat,
   2376  *          false otherwise.
   2377  **/
   2378 bool TextureViewUtilities::isInternalformatCompressed(const glw::GLenum internalformat)
   2379 {
   2380 	bool result = false;
   2381 
   2382 	switch (internalformat)
   2383 	{
   2384 	case GL_COMPRESSED_RED_RGTC1:
   2385 	case GL_COMPRESSED_SIGNED_RED_RGTC1:
   2386 	case GL_COMPRESSED_RG_RGTC2:
   2387 	case GL_COMPRESSED_SIGNED_RG_RGTC2:
   2388 	case GL_COMPRESSED_RGBA_BPTC_UNORM:
   2389 	case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
   2390 	case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
   2391 	case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
   2392 	case GL_COMPRESSED_RGB8_ETC2:
   2393 	case GL_COMPRESSED_SRGB8_ETC2:
   2394 	case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
   2395 	case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
   2396 	case GL_COMPRESSED_RGBA8_ETC2_EAC:
   2397 	case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
   2398 	case GL_COMPRESSED_R11_EAC:
   2399 	case GL_COMPRESSED_SIGNED_R11_EAC:
   2400 	case GL_COMPRESSED_RG11_EAC:
   2401 	case GL_COMPRESSED_SIGNED_RG11_EAC:
   2402 	{
   2403 		result = true;
   2404 
   2405 		break;
   2406 	}
   2407 	} /* switch (internalformat) */
   2408 
   2409 	return result;
   2410 }
   2411 
   2412 /** Tells whether user-specified internalformat operates in sRGB color space.
   2413  *
   2414  *  @param internalformat Internalformat to use for the query.
   2415  *
   2416  *  @return true if @param internalformat is a known sRGB internalformat,
   2417  *          false otherwise.
   2418  **/
   2419 bool TextureViewUtilities::isInternalformatSRGB(const glw::GLenum internalformat)
   2420 {
   2421 	return (internalformat == GL_SRGB8 || internalformat == GL_SRGB8_ALPHA8 ||
   2422 			internalformat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM);
   2423 }
   2424 
   2425 /** Tells whether user-specified internalformat is supported by OpenGL of a given version.
   2426  *
   2427  *  @param internalformat Internalformat to use for the query.
   2428  *  @param major_version  Major version of the rendering context.
   2429  *  @param minor_version  Minor version of the rendering context.
   2430  *
   2431  *  @return true if the internalformat is supported, false otherwise.
   2432  **/
   2433 bool TextureViewUtilities::isInternalformatSupported(glw::GLenum internalformat, const glw::GLint major_version,
   2434 													 const glw::GLint minor_version)
   2435 {
   2436 	(void)major_version;
   2437 	/* NOTE: This function, as it stands right now, does not consider OpenGL contexts
   2438 	 *       lesser than 4.
   2439 	 **/
   2440 	glw::GLint minimum_minor_version = 0;
   2441 
   2442 	DE_ASSERT(major_version >= 4);
   2443 
   2444 	switch (internalformat)
   2445 	{
   2446 	/* >= OpenGL 4.0 */
   2447 	case GL_RGBA32F:
   2448 	case GL_RGBA32I:
   2449 	case GL_RGBA32UI:
   2450 	case GL_RGBA16:
   2451 	case GL_RGBA16F:
   2452 	case GL_RGBA16I:
   2453 	case GL_RGBA16UI:
   2454 	case GL_RGBA8:
   2455 	case GL_RGBA8I:
   2456 	case GL_RGBA8UI:
   2457 	case GL_SRGB8_ALPHA8:
   2458 	case GL_RGB10_A2:
   2459 	case GL_RGB10_A2UI:
   2460 	case GL_RGB5_A1:
   2461 	case GL_RGBA4:
   2462 	case GL_R11F_G11F_B10F:
   2463 	case GL_RG32F:
   2464 	case GL_RG32I:
   2465 	case GL_RG32UI:
   2466 	case GL_RG16:
   2467 	case GL_RG16F:
   2468 	case GL_RG16I:
   2469 	case GL_RG16UI:
   2470 	case GL_RG8:
   2471 	case GL_RG8I:
   2472 	case GL_RG8UI:
   2473 	case GL_R32F:
   2474 	case GL_R32I:
   2475 	case GL_R32UI:
   2476 	case GL_R16F:
   2477 	case GL_R16I:
   2478 	case GL_R16UI:
   2479 	case GL_R16:
   2480 	case GL_R8:
   2481 	case GL_R8I:
   2482 	case GL_R8UI:
   2483 	case GL_RGBA16_SNORM:
   2484 	case GL_RGBA8_SNORM:
   2485 	case GL_RGB32F:
   2486 	case GL_RGB32I:
   2487 	case GL_RGB32UI:
   2488 	case GL_RGB16_SNORM:
   2489 	case GL_RGB16F:
   2490 	case GL_RGB16I:
   2491 	case GL_RGB16UI:
   2492 	case GL_RGB16:
   2493 	case GL_RGB8_SNORM:
   2494 	case GL_RGB8:
   2495 	case GL_RGB8I:
   2496 	case GL_RGB8UI:
   2497 	case GL_SRGB8:
   2498 	case GL_RGB9_E5:
   2499 	case GL_RG16_SNORM:
   2500 	case GL_RG8_SNORM:
   2501 	case GL_R16_SNORM:
   2502 	case GL_R8_SNORM:
   2503 	case GL_DEPTH_COMPONENT32F:
   2504 	case GL_DEPTH_COMPONENT24:
   2505 	case GL_DEPTH_COMPONENT16:
   2506 	case GL_DEPTH32F_STENCIL8:
   2507 	case GL_DEPTH24_STENCIL8:
   2508 	case GL_COMPRESSED_RED_RGTC1:
   2509 	case GL_COMPRESSED_SIGNED_RED_RGTC1:
   2510 	case GL_COMPRESSED_RG_RGTC2:
   2511 	case GL_COMPRESSED_SIGNED_RG_RGTC2:
   2512 	{
   2513 		/* Already covered by default value of minimum_minor_version */
   2514 
   2515 		break;
   2516 	}
   2517 
   2518 	/* >= OpenGL 4.2 */
   2519 	case GL_RGB565:
   2520 	case GL_COMPRESSED_RGBA_BPTC_UNORM:
   2521 	case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
   2522 	case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
   2523 	case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
   2524 	{
   2525 		minimum_minor_version = 2;
   2526 
   2527 		break;
   2528 	}
   2529 
   2530 	/* >= OpenGL 4.3 */
   2531 	case GL_COMPRESSED_RGB8_ETC2:
   2532 	case GL_COMPRESSED_SRGB8_ETC2:
   2533 	case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
   2534 	case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
   2535 	case GL_COMPRESSED_RGBA8_ETC2_EAC:
   2536 	case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
   2537 	case GL_COMPRESSED_R11_EAC:
   2538 	case GL_COMPRESSED_SIGNED_R11_EAC:
   2539 	case GL_COMPRESSED_RG11_EAC:
   2540 	case GL_COMPRESSED_SIGNED_RG11_EAC:
   2541 	{
   2542 		minimum_minor_version = 3;
   2543 
   2544 		break;
   2545 	}
   2546 
   2547 	default:
   2548 		TCU_FAIL("Unrecognized internalformat");
   2549 	}
   2550 
   2551 	return (minor_version >= minimum_minor_version);
   2552 }
   2553 
   2554 /** Tells whether a parent texture object using @param original_texture_target texture target
   2555  *  can be used to generate a texture view of @param view_texture_target texture target.
   2556  *
   2557  *  @param original_texture_target Texture target used by parent texture;
   2558  *  @param view_texture_target     Texture target to be used for view texture;
   2559  *
   2560  *  @return true if the texture targets are compatible, false otherwise.
   2561  **/
   2562 bool TextureViewUtilities::isLegalTextureTargetForTextureView(glw::GLenum original_texture_target,
   2563 															  glw::GLenum view_texture_target)
   2564 {
   2565 	bool result = false;
   2566 
   2567 	switch (original_texture_target)
   2568 	{
   2569 	case GL_TEXTURE_1D:
   2570 	{
   2571 		result = (view_texture_target == GL_TEXTURE_1D || view_texture_target == GL_TEXTURE_1D_ARRAY);
   2572 
   2573 		break;
   2574 	}
   2575 
   2576 	case GL_TEXTURE_2D:
   2577 	{
   2578 		result = (view_texture_target == GL_TEXTURE_2D || view_texture_target == GL_TEXTURE_2D_ARRAY);
   2579 
   2580 		break;
   2581 	}
   2582 
   2583 	case GL_TEXTURE_3D:
   2584 	{
   2585 		result = (view_texture_target == GL_TEXTURE_3D);
   2586 
   2587 		break;
   2588 	}
   2589 
   2590 	case GL_TEXTURE_CUBE_MAP:
   2591 	{
   2592 		result = (view_texture_target == GL_TEXTURE_CUBE_MAP || view_texture_target == GL_TEXTURE_2D ||
   2593 				  view_texture_target == GL_TEXTURE_2D_ARRAY || view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   2594 
   2595 		break;
   2596 	}
   2597 
   2598 	case GL_TEXTURE_RECTANGLE:
   2599 	{
   2600 		result = (view_texture_target == GL_TEXTURE_RECTANGLE);
   2601 
   2602 		break;
   2603 	}
   2604 
   2605 	case GL_TEXTURE_BUFFER:
   2606 	{
   2607 		/* No targets supported */
   2608 
   2609 		break;
   2610 	}
   2611 
   2612 	case GL_TEXTURE_1D_ARRAY:
   2613 	{
   2614 		result = (view_texture_target == GL_TEXTURE_1D_ARRAY || view_texture_target == GL_TEXTURE_1D);
   2615 
   2616 		break;
   2617 	}
   2618 
   2619 	case GL_TEXTURE_2D_ARRAY:
   2620 	{
   2621 		result = (view_texture_target == GL_TEXTURE_2D_ARRAY || view_texture_target == GL_TEXTURE_2D ||
   2622 				  view_texture_target == GL_TEXTURE_CUBE_MAP || view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   2623 
   2624 		break;
   2625 	}
   2626 
   2627 	case GL_TEXTURE_CUBE_MAP_ARRAY:
   2628 	{
   2629 		result = (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY || view_texture_target == GL_TEXTURE_2D_ARRAY ||
   2630 				  view_texture_target == GL_TEXTURE_2D || view_texture_target == GL_TEXTURE_CUBE_MAP);
   2631 
   2632 		break;
   2633 	}
   2634 
   2635 	case GL_TEXTURE_2D_MULTISAMPLE:
   2636 	{
   2637 		result = (view_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
   2638 				  view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
   2639 
   2640 		break;
   2641 	}
   2642 
   2643 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   2644 	{
   2645 		result = (view_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
   2646 				  view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
   2647 
   2648 		break;
   2649 	}
   2650 	} /* switch (original_texture_target) */
   2651 
   2652 	return result;
   2653 }
   2654 
   2655 /** Constructor.
   2656  *
   2657  *  @param context Rendering context.
   2658  **/
   2659 TextureViewTestGetTexParameter::TextureViewTestGetTexParameter(deqp::Context& context)
   2660 	: TestCase(context, "gettexparameter", "Verifies glGetTexParameterfv() and glGetTexParameteriv() "
   2661 										   "work as specified")
   2662 {
   2663 	/* Left blank on purpose */
   2664 }
   2665 
   2666 /** De-initializes all GL objects created for the test. */
   2667 void TextureViewTestGetTexParameter::deinit()
   2668 {
   2669 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2670 
   2671 	/* Deinitialize all test runs */
   2672 	for (_test_runs_iterator it = m_test_runs.begin(); it != m_test_runs.end(); ++it)
   2673 	{
   2674 		_test_run& test_run = *it;
   2675 
   2676 		if (test_run.parent_texture_object_id != 0)
   2677 		{
   2678 			gl.deleteTextures(1, &test_run.parent_texture_object_id);
   2679 
   2680 			test_run.parent_texture_object_id = 0;
   2681 		}
   2682 
   2683 		if (test_run.texture_view_object_created_from_immutable_to_id != 0)
   2684 		{
   2685 			gl.deleteTextures(1, &test_run.texture_view_object_created_from_immutable_to_id);
   2686 
   2687 			test_run.texture_view_object_created_from_immutable_to_id = 0;
   2688 		}
   2689 
   2690 		if (test_run.texture_view_object_created_from_view_to_id != 0)
   2691 		{
   2692 			gl.deleteTextures(1, &test_run.texture_view_object_created_from_view_to_id);
   2693 
   2694 			test_run.texture_view_object_created_from_view_to_id = 0;
   2695 		}
   2696 	}
   2697 	m_test_runs.clear();
   2698 }
   2699 
   2700 /** Initializes test run descriptors used by the test. This also includes
   2701  *  all GL objects used by all the iterations.
   2702  **/
   2703 void TextureViewTestGetTexParameter::initTestRuns()
   2704 {
   2705 	const glw::Functions& gl				= m_context.getRenderContext().getFunctions();
   2706 	const int			  n_cubemaps_needed = 4; /* only used for GL_TEXTURE_CUBE_MAP_ARRAY */
   2707 	const int			  texture_depth		= 16;
   2708 	const int			  texture_height	= 32;
   2709 	const int			  texture_width		= 64;
   2710 
   2711 	const glw::GLenum texture_targets[] = {
   2712 		GL_TEXTURE_1D,		 GL_TEXTURE_1D_ARRAY,		GL_TEXTURE_2D,
   2713 		GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
   2714 		GL_TEXTURE_3D,		 GL_TEXTURE_CUBE_MAP,		GL_TEXTURE_CUBE_MAP_ARRAY,
   2715 		GL_TEXTURE_RECTANGLE
   2716 	};
   2717 	const _test_texture_type texture_types[] = { TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED,
   2718 												 TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT,
   2719 												 TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT,
   2720 												 TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT,
   2721 												 TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW };
   2722 	const unsigned int n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
   2723 	const unsigned int n_texture_types   = sizeof(texture_types) / sizeof(texture_types[0]);
   2724 
   2725 	/* Iterate through all texture types supported by the test */
   2726 	for (unsigned int n_texture_type = 0; n_texture_type < n_texture_types; ++n_texture_type)
   2727 	{
   2728 		const _test_texture_type texture_type = texture_types[n_texture_type];
   2729 
   2730 		/* Iterate through all texture targets supported by the test */
   2731 		for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
   2732 		{
   2733 			_test_run		  new_test_run;
   2734 			const glw::GLenum texture_target = texture_targets[n_texture_target];
   2735 
   2736 			/* Texture buffers are neither immutable nor mutable. In order to avoid testing
   2737 			 * them in both cases, let's assume they are immutable objects */
   2738 			if (texture_target == GL_TEXTURE_BUFFER && texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT)
   2739 			{
   2740 				continue;
   2741 			}
   2742 
   2743 			/* Set up test run properties. Since we're only testing a single
   2744 			 * configuration, we can set these to predefined values..
   2745 			 */
   2746 			const int  n_levels_needed		 = 6;
   2747 			glw::GLint n_min_layer			 = 1;
   2748 			glw::GLint n_num_layers			 = 2;
   2749 			glw::GLint n_min_level			 = 2;
   2750 			glw::GLint n_num_levels			 = 3;
   2751 			int		   parent_texture_depth  = texture_depth;
   2752 			int		   parent_texture_height = texture_height;
   2753 			int		   parent_texture_width  = texture_width;
   2754 
   2755 			new_test_run.texture_target = texture_target;
   2756 			new_test_run.texture_type   = texture_type;
   2757 
   2758 			/* Take note of target-specific restrictions */
   2759 			if (texture_target == GL_TEXTURE_CUBE_MAP || texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
   2760 			{
   2761 				n_num_layers = 6 /* layer-faces */ * 2; /* as per spec */
   2762 
   2763 				/* Make sure that cube face width matches its height */
   2764 				parent_texture_height = 64;
   2765 				parent_texture_width  = 64;
   2766 
   2767 				/* Also change the depth so that there's at least a few layers
   2768 				 * we can use in the test for GL_TEXTURE_CUBE_MAP_ARRAY case
   2769 				 */
   2770 				parent_texture_depth = 64;
   2771 			}
   2772 
   2773 			if (texture_target == GL_TEXTURE_CUBE_MAP)
   2774 			{
   2775 				/* Texture views created from a cube map texture should always
   2776 				 * use a minimum layer of zero
   2777 				 */
   2778 				n_min_layer  = 0;
   2779 				n_num_layers = 6;
   2780 			}
   2781 
   2782 			if (texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
   2783 			{
   2784 				/* Slightly modify the values we'll use for <minlayer>
   2785 				 * and <numlayers> arguments passed to glTextureView() calls
   2786 				 * so that we can test the "view from view from texture" case
   2787 				 */
   2788 				n_min_layer = 0;
   2789 			}
   2790 
   2791 			if (texture_target == GL_TEXTURE_1D || texture_target == GL_TEXTURE_2D ||
   2792 				texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_3D ||
   2793 				texture_target == GL_TEXTURE_RECTANGLE)
   2794 			{
   2795 				/* All these texture targets are single-layer only. glTextureView()
   2796 				 * also requires <numlayers> argument to be set to 1 for them, so
   2797 				 * take this into account.
   2798 				 **/
   2799 				n_min_layer  = 0;
   2800 				n_num_layers = 1;
   2801 			}
   2802 
   2803 			if (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
   2804 				texture_target == GL_TEXTURE_RECTANGLE)
   2805 			{
   2806 				/* All these texture targets do not support mip-maps */
   2807 				n_min_level = 0;
   2808 			}
   2809 
   2810 			/* Initialize parent texture object */
   2811 			gl.genTextures(1, &new_test_run.parent_texture_object_id);
   2812 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
   2813 
   2814 			gl.bindTexture(texture_target, new_test_run.parent_texture_object_id);
   2815 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   2816 
   2817 			if (texture_type != TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED)
   2818 			{
   2819 				TextureViewUtilities::initTextureStorage(gl, (texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT),
   2820 														 texture_target, parent_texture_depth, parent_texture_height,
   2821 														 parent_texture_width, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
   2822 														 n_levels_needed, n_cubemaps_needed, 0); /* bo_id */
   2823 			}
   2824 
   2825 			/* Update expected view-specific property values to include interactions
   2826 			 * with immutable textures. */
   2827 			if (texture_type == TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT ||
   2828 				texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
   2829 				texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW)
   2830 			{
   2831 				/* Set expected GL_TEXTURE_IMMUTABLE_LEVELS property value to the number
   2832 				 * of levels we'll be using for the immutable texture storage. For selected
   2833 				 * texture targets that do no take <levels> argument, we'll change this
   2834 				 * value on a case-by-case basis.
   2835 				 */
   2836 				new_test_run.expected_n_immutable_levels = n_levels_needed;
   2837 
   2838 				/* Set expected GL_TEXTURE_VIEW_NUM_LAYERS property value to 1, as per GL spec.
   2839 				 * This value will be modified for selected texture targets */
   2840 				new_test_run.expected_n_num_layers = 1;
   2841 
   2842 				/* Configured expected GL_TEXTURE_VIEW_NUM_LEVELS value as per GL spec */
   2843 				new_test_run.expected_n_num_levels = n_levels_needed;
   2844 
   2845 				/* Initialize immutable texture storage */
   2846 				switch (texture_target)
   2847 				{
   2848 				case GL_TEXTURE_1D_ARRAY:
   2849 				{
   2850 					/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
   2851 					new_test_run.expected_n_num_layers = texture_height;
   2852 
   2853 					break;
   2854 				}
   2855 
   2856 				case GL_TEXTURE_CUBE_MAP:
   2857 				{
   2858 					/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
   2859 					new_test_run.expected_n_num_layers = 6;
   2860 
   2861 					break;
   2862 				}
   2863 
   2864 				case GL_TEXTURE_RECTANGLE:
   2865 				{
   2866 					new_test_run.expected_n_immutable_levels = 1;
   2867 					new_test_run.expected_n_num_levels		 = 1;
   2868 
   2869 					break;
   2870 				}
   2871 
   2872 				case GL_TEXTURE_2D_ARRAY:
   2873 				{
   2874 					/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
   2875 					new_test_run.expected_n_num_layers = texture_depth;
   2876 
   2877 					break;
   2878 				}
   2879 
   2880 				case GL_TEXTURE_2D_MULTISAMPLE:
   2881 				{
   2882 					/* 2D multisample texture are not mip-mapped, so update
   2883 					 * expected GL_TEXTURE_IMMUTABLE_LEVELS and GL_TEXTURE_VIEW_NUM_LEVELS
   2884 					 * value accordingly */
   2885 					new_test_run.expected_n_immutable_levels = 1;
   2886 					new_test_run.expected_n_num_levels		 = 1;
   2887 
   2888 					break;
   2889 				}
   2890 
   2891 				case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   2892 				{
   2893 					/* 2D multisample array textures are not mip-mapped, so update
   2894 					 * expected GL_TEXTURE_IMMUTABLE_LEVELS and GL_TEXTURE_VIEW_NUM_LEVELS
   2895 					 * values accordingly */
   2896 					new_test_run.expected_n_immutable_levels = 1;
   2897 					new_test_run.expected_n_num_levels		 = 1;
   2898 
   2899 					/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
   2900 					new_test_run.expected_n_num_layers = texture_depth;
   2901 
   2902 					break;
   2903 				}
   2904 
   2905 				case GL_TEXTURE_CUBE_MAP_ARRAY:
   2906 				{
   2907 					const unsigned int actual_texture_depth = 6 /* layer-faces */ * n_cubemaps_needed;
   2908 
   2909 					/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
   2910 					new_test_run.expected_n_num_layers = actual_texture_depth;
   2911 
   2912 					break;
   2913 				}
   2914 				} /* switch (texture_target) */
   2915 			}
   2916 
   2917 			/* Initialize the view(s) */
   2918 			if (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
   2919 				texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW)
   2920 			{
   2921 				const unsigned int n_iterations =
   2922 					(texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) ? 2 : 1;
   2923 
   2924 				for (unsigned int n_iteration = 0; n_iteration < n_iterations; ++n_iteration)
   2925 				{
   2926 					glw::GLuint* parent_id_ptr = (n_iteration == 0) ?
   2927 													 &new_test_run.parent_texture_object_id :
   2928 													 &new_test_run.texture_view_object_created_from_immutable_to_id;
   2929 					glw::GLuint* view_id_ptr = (n_iteration == 0) ?
   2930 												   &new_test_run.texture_view_object_created_from_immutable_to_id :
   2931 												   &new_test_run.texture_view_object_created_from_view_to_id;
   2932 
   2933 					gl.genTextures(1, view_id_ptr);
   2934 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
   2935 
   2936 					gl.textureView(*view_id_ptr, new_test_run.texture_target, *parent_id_ptr,
   2937 								   GL_RGBA8, /* use the parent texture object's internalformat */
   2938 								   n_min_level, n_num_levels, n_min_layer, n_num_layers);
   2939 					GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
   2940 
   2941 					/* Query parent object's properties */
   2942 					glw::GLint parent_min_level			 = -1;
   2943 					glw::GLint parent_min_layer			 = -1;
   2944 					glw::GLint parent_num_layers		 = -1;
   2945 					glw::GLint parent_num_levels		 = -1;
   2946 					glw::GLint parent_n_immutable_levels = -1;
   2947 
   2948 					gl.bindTexture(texture_target, *parent_id_ptr);
   2949 					GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   2950 
   2951 					gl.getTexParameteriv(texture_target, GL_TEXTURE_IMMUTABLE_LEVELS, &parent_n_immutable_levels);
   2952 					GLU_EXPECT_NO_ERROR(
   2953 						gl.getError(),
   2954 						"glGetTexParameteriv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname queried for parent object");
   2955 
   2956 					gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_MIN_LAYER, &parent_min_layer);
   2957 					GLU_EXPECT_NO_ERROR(
   2958 						gl.getError(),
   2959 						"glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname queried for parent object");
   2960 
   2961 					gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_MIN_LEVEL, &parent_min_level);
   2962 					GLU_EXPECT_NO_ERROR(
   2963 						gl.getError(),
   2964 						"glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname queried for parent object");
   2965 
   2966 					gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_NUM_LAYERS, &parent_num_layers);
   2967 					GLU_EXPECT_NO_ERROR(
   2968 						gl.getError(),
   2969 						"glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname queried for parent object");
   2970 
   2971 					gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_NUM_LEVELS, &parent_num_levels);
   2972 					GLU_EXPECT_NO_ERROR(
   2973 						gl.getError(),
   2974 						"glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname queried for parent object");
   2975 
   2976 					/* Update test run-specific expected values as per GL_ARB_texture_view extension specification */
   2977 					/*
   2978 					 * - TEXTURE_IMMUTABLE_LEVELS is set to the value of TEXTURE_IMMUTABLE_LEVELS
   2979 					 *   from the original texture.
   2980 					 */
   2981 					new_test_run.expected_n_immutable_levels = parent_n_immutable_levels;
   2982 
   2983 					/*
   2984 					 * - TEXTURE_VIEW_MIN_LEVEL is set to <minlevel> plus the value of
   2985 					 *   TEXTURE_VIEW_MIN_LEVEL from the original texture.
   2986 					 */
   2987 					new_test_run.expected_n_min_level = n_min_level + parent_min_level;
   2988 
   2989 					/*
   2990 					 * - TEXTURE_VIEW_MIN_LAYER is set to <minlayer> plus the value of
   2991 					 *   TEXTURE_VIEW_MIN_LAYER from the original texture.
   2992 					 */
   2993 					new_test_run.expected_n_min_layer = n_min_layer + parent_min_layer;
   2994 
   2995 					/*
   2996 					 * - TEXTURE_VIEW_NUM_LAYERS is set to the lesser of <numlayers> and the
   2997 					 *   value of TEXTURE_VIEW_NUM_LAYERS from the original texture minus
   2998 					 *   <minlayer>.
   2999 					 *
   3000 					 */
   3001 					if ((parent_num_layers - n_min_layer) < n_num_layers)
   3002 					{
   3003 						new_test_run.expected_n_num_layers = parent_num_layers - n_min_layer;
   3004 					}
   3005 					else
   3006 					{
   3007 						new_test_run.expected_n_num_layers = n_num_layers;
   3008 					}
   3009 
   3010 					/*
   3011 					 * - TEXTURE_VIEW_NUM_LEVELS is set to the lesser of <numlevels> and the
   3012 					 *   value of TEXTURE_VIEW_NUM_LEVELS from the original texture minus
   3013 					 *   <minlevels>.
   3014 					 *
   3015 					 */
   3016 					if ((parent_num_levels - n_min_level) < n_num_levels)
   3017 					{
   3018 						new_test_run.expected_n_num_levels = parent_num_levels - n_min_level;
   3019 					}
   3020 					else
   3021 					{
   3022 						new_test_run.expected_n_num_levels = n_num_levels;
   3023 					}
   3024 				} /* for (all iterations) */
   3025 			}	 /* if (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
   3026 			 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) */
   3027 
   3028 			/* Store the descriptor */
   3029 			m_test_runs.push_back(new_test_run);
   3030 		} /* for (all texture targets) */
   3031 	}	 /* for (all texture types) */
   3032 }
   3033 
   3034 /** Executes test iteration.
   3035  *
   3036  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   3037  */
   3038 tcu::TestNode::IterateResult TextureViewTestGetTexParameter::iterate()
   3039 {
   3040 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3041 
   3042 	/* Make sure GL_ARB_texture_view is reported as supported before carrying on
   3043 	 * with actual execution */
   3044 	const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
   3045 
   3046 	if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
   3047 	{
   3048 		throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
   3049 	}
   3050 
   3051 	/* Initialize all objects necessary to execute the test */
   3052 	initTestRuns();
   3053 
   3054 	/* Iterate through all test runs and issue the queries */
   3055 	for (_test_runs_const_iterator test_run_iterator = m_test_runs.begin(); test_run_iterator != m_test_runs.end();
   3056 		 test_run_iterator++)
   3057 	{
   3058 		glw::GLfloat	 query_texture_immutable_levels_value_float = -1.0f;
   3059 		glw::GLint		 query_texture_immutable_levels_value_int   = -1;
   3060 		glw::GLfloat	 query_texture_view_min_layer_value_float   = -1.0f;
   3061 		glw::GLint		 query_texture_view_min_layer_value_int		= -1;
   3062 		glw::GLfloat	 query_texture_view_min_level_value_float   = -1.0f;
   3063 		glw::GLint		 query_texture_view_min_level_value_int		= -1;
   3064 		glw::GLfloat	 query_texture_view_num_layers_value_float  = -1.0f;
   3065 		glw::GLint		 query_texture_view_num_layers_value_int	= -1;
   3066 		glw::GLfloat	 query_texture_view_num_levels_value_float  = -1.0f;
   3067 		glw::GLint		 query_texture_view_num_levels_value_int	= -1;
   3068 		const _test_run& test_run									= *test_run_iterator;
   3069 		glw::GLint		 texture_object_id							= 0;
   3070 
   3071 		switch (test_run.texture_type)
   3072 		{
   3073 		case TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT:
   3074 			texture_object_id = test_run.parent_texture_object_id;
   3075 			break;
   3076 		case TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT:
   3077 			texture_object_id = test_run.parent_texture_object_id;
   3078 			break;
   3079 		case TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED:
   3080 			texture_object_id = test_run.parent_texture_object_id;
   3081 			break;
   3082 		case TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT:
   3083 			texture_object_id = test_run.texture_view_object_created_from_immutable_to_id;
   3084 			break;
   3085 		case TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW:
   3086 			texture_object_id = test_run.texture_view_object_created_from_view_to_id;
   3087 			break;
   3088 
   3089 		default:
   3090 		{
   3091 			TCU_FAIL("Unrecognized texture type");
   3092 		}
   3093 		}
   3094 
   3095 		/* Bind the texture object of our interest to the target */
   3096 		gl.bindTexture(test_run.texture_target, texture_object_id);
   3097 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3098 
   3099 		/* Run all the queries */
   3100 		gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_IMMUTABLE_LEVELS,
   3101 							 &query_texture_immutable_levels_value_float);
   3102 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname");
   3103 
   3104 		gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_IMMUTABLE_LEVELS,
   3105 							 &query_texture_immutable_levels_value_int);
   3106 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexPrameteriv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname");
   3107 
   3108 		gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LAYER,
   3109 							 &query_texture_view_min_layer_value_float);
   3110 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname");
   3111 
   3112 		gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LAYER,
   3113 							 &query_texture_view_min_layer_value_int);
   3114 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname");
   3115 
   3116 		gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LEVEL,
   3117 							 &query_texture_view_min_level_value_float);
   3118 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname");
   3119 
   3120 		gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LEVEL,
   3121 							 &query_texture_view_min_level_value_int);
   3122 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname");
   3123 
   3124 		gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LAYERS,
   3125 							 &query_texture_view_num_layers_value_float);
   3126 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname");
   3127 
   3128 		gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LAYERS,
   3129 							 &query_texture_view_num_layers_value_int);
   3130 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname");
   3131 
   3132 		gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LEVELS,
   3133 							 &query_texture_view_num_levels_value_float);
   3134 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname");
   3135 
   3136 		gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LEVELS,
   3137 							 &query_texture_view_num_levels_value_int);
   3138 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname");
   3139 
   3140 		/* Verify the results */
   3141 		const float epsilon = 1e-5f;
   3142 
   3143 		if (de::abs(query_texture_immutable_levels_value_float - (float)test_run.expected_n_immutable_levels) > epsilon)
   3144 		{
   3145 			m_testCtx.getLog() << tcu::TestLog::Message
   3146 							   << "Invalid floating-point value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname "
   3147 							   << "(expected: " << test_run.expected_n_immutable_levels
   3148 							   << " found: " << query_texture_immutable_levels_value_float << ")."
   3149 							   << tcu::TestLog::EndMessage;
   3150 
   3151 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname");
   3152 		}
   3153 
   3154 		if (query_texture_immutable_levels_value_int != test_run.expected_n_immutable_levels)
   3155 		{
   3156 			m_testCtx.getLog() << tcu::TestLog::Message
   3157 							   << "Invalid integer value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname "
   3158 							   << "(expected: " << test_run.expected_n_immutable_levels
   3159 							   << " found: " << query_texture_immutable_levels_value_int << ")."
   3160 							   << tcu::TestLog::EndMessage;
   3161 
   3162 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname");
   3163 		}
   3164 
   3165 		if (de::abs(query_texture_view_min_layer_value_float - (float)test_run.expected_n_min_layer) > epsilon)
   3166 		{
   3167 			m_testCtx.getLog() << tcu::TestLog::Message
   3168 							   << "Invalid floating-point value reported for GL_TEXTURE_VIEW_MIN_LAYER pname "
   3169 							   << "(expected: " << test_run.expected_n_min_layer
   3170 							   << " found: " << query_texture_view_min_layer_value_float << ")."
   3171 							   << tcu::TestLog::EndMessage;
   3172 
   3173 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LAYER pname");
   3174 		}
   3175 
   3176 		if (query_texture_view_min_layer_value_int != test_run.expected_n_min_layer)
   3177 		{
   3178 			m_testCtx.getLog() << tcu::TestLog::Message
   3179 							   << "Invalid integer value reported for GL_TEXTURE_VIEW_MIN_LAYER pname "
   3180 							   << "(expected: " << test_run.expected_n_min_layer
   3181 							   << " found: " << query_texture_view_min_layer_value_int << ")."
   3182 							   << tcu::TestLog::EndMessage;
   3183 
   3184 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LAYER pname");
   3185 		}
   3186 
   3187 		if (de::abs(query_texture_view_min_level_value_float - (float)test_run.expected_n_min_level) > epsilon)
   3188 		{
   3189 			m_testCtx.getLog() << tcu::TestLog::Message
   3190 							   << "Invalid floating-point value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname "
   3191 							   << "(expected: " << test_run.expected_n_min_level
   3192 							   << " found: " << query_texture_view_min_level_value_float << ")."
   3193 							   << tcu::TestLog::EndMessage;
   3194 
   3195 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname");
   3196 		}
   3197 
   3198 		if (query_texture_view_min_level_value_int != test_run.expected_n_min_level)
   3199 		{
   3200 			m_testCtx.getLog() << tcu::TestLog::Message
   3201 							   << "Invalid integer value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname "
   3202 							   << "(expected: " << test_run.expected_n_min_level
   3203 							   << " found: " << query_texture_view_min_level_value_int << ")."
   3204 							   << tcu::TestLog::EndMessage;
   3205 
   3206 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname");
   3207 		}
   3208 
   3209 		if (de::abs(query_texture_view_num_layers_value_float - (float)test_run.expected_n_num_layers) > epsilon)
   3210 		{
   3211 			m_testCtx.getLog() << tcu::TestLog::Message
   3212 							   << "Invalid floating-point value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname "
   3213 							   << "(expected: " << test_run.expected_n_num_layers
   3214 							   << " found: " << query_texture_view_num_layers_value_float << ")."
   3215 							   << tcu::TestLog::EndMessage;
   3216 
   3217 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname");
   3218 		}
   3219 
   3220 		if (query_texture_view_num_layers_value_int != test_run.expected_n_num_layers)
   3221 		{
   3222 			m_testCtx.getLog() << tcu::TestLog::Message
   3223 							   << "Invalid integer value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname "
   3224 							   << "(expected: " << test_run.expected_n_num_layers
   3225 							   << " found: " << query_texture_view_num_layers_value_int << ")."
   3226 							   << tcu::TestLog::EndMessage;
   3227 
   3228 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname");
   3229 		}
   3230 
   3231 		if (de::abs(query_texture_view_num_levels_value_float - (float)test_run.expected_n_num_levels) > epsilon)
   3232 		{
   3233 			m_testCtx.getLog() << tcu::TestLog::Message
   3234 							   << "Invalid floating-point value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname "
   3235 							   << "(expected: " << test_run.expected_n_num_levels
   3236 							   << " found: " << query_texture_view_num_levels_value_float << ")."
   3237 							   << tcu::TestLog::EndMessage;
   3238 
   3239 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname");
   3240 		}
   3241 
   3242 		if (query_texture_view_num_levels_value_int != test_run.expected_n_num_levels)
   3243 		{
   3244 			m_testCtx.getLog() << tcu::TestLog::Message
   3245 							   << "Invalid integer value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname "
   3246 							   << "(expected: " << test_run.expected_n_num_levels
   3247 							   << " found: " << query_texture_view_num_levels_value_int << ")."
   3248 							   << tcu::TestLog::EndMessage;
   3249 
   3250 			TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname");
   3251 		}
   3252 	} /* for (all test runs) */
   3253 
   3254 	/* Test case passed */
   3255 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3256 
   3257 	return STOP;
   3258 }
   3259 
   3260 /** Constructor.
   3261  *
   3262  *  @param context Rendering context
   3263  **/
   3264 TextureViewTestErrors::TextureViewTestErrors(deqp::Context& context)
   3265 	: TestCase(context, "errors", "test_description")
   3266 	, m_bo_id(0)
   3267 	, m_reference_immutable_to_1d_id(0)
   3268 	, m_reference_immutable_to_2d_id(0)
   3269 	, m_reference_immutable_to_2d_array_id(0)
   3270 	, m_reference_immutable_to_2d_array_32_by_33_id(0)
   3271 	, m_reference_immutable_to_2d_multisample_id(0)
   3272 	, m_reference_immutable_to_3d_id(0)
   3273 	, m_reference_immutable_to_cube_map_id(0)
   3274 	, m_reference_immutable_to_cube_map_array_id(0)
   3275 	, m_reference_immutable_to_rectangle_id(0)
   3276 	, m_reference_mutable_to_2d_id(0)
   3277 	, m_test_modified_to_id_1(0)
   3278 	, m_test_modified_to_id_2(0)
   3279 	, m_test_modified_to_id_3(0)
   3280 	, m_view_bound_to_id(0)
   3281 	, m_view_never_bound_to_id(0)
   3282 {
   3283 	/* Left blank on purpose */
   3284 }
   3285 
   3286 /** Deinitializes all GL objects that may have been generated for the test. */
   3287 void TextureViewTestErrors::deinit()
   3288 {
   3289 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3290 
   3291 	if (m_bo_id != 0)
   3292 	{
   3293 		gl.deleteBuffers(1, &m_bo_id);
   3294 
   3295 		m_bo_id = 0;
   3296 	}
   3297 
   3298 	if (m_reference_immutable_to_1d_id != 0)
   3299 	{
   3300 		gl.deleteTextures(1, &m_reference_immutable_to_1d_id);
   3301 
   3302 		m_reference_immutable_to_1d_id = 0;
   3303 	}
   3304 
   3305 	if (m_reference_immutable_to_2d_id != 0)
   3306 	{
   3307 		gl.deleteTextures(1, &m_reference_immutable_to_2d_id);
   3308 
   3309 		m_reference_immutable_to_2d_id = 0;
   3310 	}
   3311 
   3312 	if (m_reference_immutable_to_2d_array_id != 0)
   3313 	{
   3314 		gl.deleteTextures(1, &m_reference_immutable_to_2d_array_id);
   3315 
   3316 		m_reference_immutable_to_2d_array_id = 0;
   3317 	}
   3318 
   3319 	if (m_reference_immutable_to_2d_array_32_by_33_id != 0)
   3320 	{
   3321 		gl.deleteTextures(1, &m_reference_immutable_to_2d_array_32_by_33_id);
   3322 
   3323 		m_reference_immutable_to_2d_array_32_by_33_id = 0;
   3324 	}
   3325 
   3326 	if (m_reference_immutable_to_2d_multisample_id != 0)
   3327 	{
   3328 		gl.deleteTextures(1, &m_reference_immutable_to_2d_multisample_id);
   3329 
   3330 		m_reference_immutable_to_2d_multisample_id = 0;
   3331 	}
   3332 
   3333 	if (m_reference_immutable_to_3d_id != 0)
   3334 	{
   3335 		gl.deleteTextures(1, &m_reference_immutable_to_3d_id);
   3336 
   3337 		m_reference_immutable_to_3d_id = 0;
   3338 	}
   3339 
   3340 	if (m_reference_immutable_to_cube_map_id != 0)
   3341 	{
   3342 		gl.deleteTextures(1, &m_reference_immutable_to_cube_map_id);
   3343 
   3344 		m_reference_immutable_to_cube_map_id = 0;
   3345 	}
   3346 
   3347 	if (m_reference_immutable_to_cube_map_array_id != 0)
   3348 	{
   3349 		gl.deleteTextures(1, &m_reference_immutable_to_cube_map_array_id);
   3350 
   3351 		m_reference_immutable_to_cube_map_array_id = 0;
   3352 	}
   3353 
   3354 	if (m_reference_immutable_to_rectangle_id != 0)
   3355 	{
   3356 		gl.deleteTextures(1, &m_reference_immutable_to_rectangle_id);
   3357 
   3358 		m_reference_immutable_to_rectangle_id = 0;
   3359 	}
   3360 
   3361 	if (m_reference_mutable_to_2d_id != 0)
   3362 	{
   3363 		gl.deleteTextures(1, &m_reference_mutable_to_2d_id);
   3364 
   3365 		m_reference_mutable_to_2d_id = 0;
   3366 	}
   3367 
   3368 	if (m_test_modified_to_id_1 != 0)
   3369 	{
   3370 		gl.deleteTextures(1, &m_test_modified_to_id_1);
   3371 
   3372 		m_test_modified_to_id_1 = 0;
   3373 	}
   3374 
   3375 	if (m_test_modified_to_id_2 != 0)
   3376 	{
   3377 		gl.deleteTextures(1, &m_test_modified_to_id_2);
   3378 
   3379 		m_test_modified_to_id_2 = 0;
   3380 	}
   3381 
   3382 	if (m_test_modified_to_id_3 != 0)
   3383 	{
   3384 		gl.deleteTextures(1, &m_test_modified_to_id_3);
   3385 
   3386 		m_test_modified_to_id_3 = 0;
   3387 	}
   3388 
   3389 	if (m_view_bound_to_id != 0)
   3390 	{
   3391 		gl.deleteTextures(1, &m_view_bound_to_id);
   3392 
   3393 		m_view_bound_to_id = 0;
   3394 	}
   3395 
   3396 	if (m_view_never_bound_to_id != 0)
   3397 	{
   3398 		gl.deleteTextures(1, &m_view_never_bound_to_id);
   3399 
   3400 		m_view_never_bound_to_id = 0;
   3401 	}
   3402 }
   3403 
   3404 /** Executes test iteration.
   3405  *
   3406  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   3407  */
   3408 tcu::TestNode::IterateResult TextureViewTestErrors::iterate()
   3409 {
   3410 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3411 
   3412 	/* Make sure GL_ARB_texture_view is reported as supported before carrying on
   3413 	 * with actual execution */
   3414 	const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
   3415 
   3416 	if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
   3417 	{
   3418 		throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
   3419 	}
   3420 
   3421 	/* Create a buffer object that we'll need to use to define storage of
   3422 	 * buffer textures */
   3423 	gl.genBuffers(1, &m_bo_id);
   3424 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed");
   3425 
   3426 	gl.bindBuffer(GL_TEXTURE_BUFFER, m_bo_id);
   3427 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed");
   3428 
   3429 	gl.bufferData(GL_TEXTURE_BUFFER, 123, /* arbitrary size */
   3430 				  DE_NULL,				  /* data */
   3431 				  GL_STATIC_DRAW);
   3432 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed");
   3433 
   3434 	/* Create reference texture objects */
   3435 	const glw::GLint  reference_bo_id			  = m_bo_id;
   3436 	const glw::GLint  reference_to_depth		  = 2;
   3437 	const glw::GLenum reference_to_format		  = GL_RGBA;
   3438 	const glw::GLint  reference_to_height		  = 64;
   3439 	const glw::GLenum reference_to_internalformat = GL_RGBA32F;
   3440 	const glw::GLint  reference_n_cubemaps		  = 1;
   3441 	const glw::GLint  reference_n_levels		  = 1;
   3442 	const glw::GLenum reference_to_type			  = GL_FLOAT;
   3443 	const glw::GLint  reference_to_width		  = 64;
   3444 
   3445 	gl.genTextures(1, &m_reference_immutable_to_1d_id);
   3446 	gl.genTextures(1, &m_reference_immutable_to_2d_id);
   3447 	gl.genTextures(1, &m_reference_immutable_to_2d_array_id);
   3448 	gl.genTextures(1, &m_reference_immutable_to_2d_array_32_by_33_id);
   3449 	gl.genTextures(1, &m_reference_immutable_to_2d_multisample_id);
   3450 	gl.genTextures(1, &m_reference_immutable_to_3d_id);
   3451 	gl.genTextures(1, &m_reference_immutable_to_cube_map_id);
   3452 	gl.genTextures(1, &m_reference_immutable_to_cube_map_array_id);
   3453 	gl.genTextures(1, &m_reference_immutable_to_rectangle_id);
   3454 	gl.genTextures(1, &m_reference_mutable_to_2d_id);
   3455 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
   3456 
   3457 	/* Retrieve GL_SAMPLES value - we'll need it to initialize multisample storage */
   3458 	glw::GLint gl_max_samples_value = 0;
   3459 
   3460 	gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, reference_to_internalformat, GL_SAMPLES,
   3461 						   1 /* bufSize - first result */, &gl_max_samples_value);
   3462 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_SAMPLES pname");
   3463 
   3464 	/* Set up texture storage for single-dimensional texture object */
   3465 	gl.bindTexture(GL_TEXTURE_1D, m_reference_immutable_to_1d_id);
   3466 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3467 
   3468 	gl.texStorage1D(GL_TEXTURE_1D, reference_n_levels, reference_to_internalformat, reference_to_width);
   3469 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed");
   3470 
   3471 	/* Set up immutable texture storage for two-dimensional texture object */
   3472 	gl.bindTexture(GL_TEXTURE_2D, m_reference_immutable_to_2d_id);
   3473 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3474 
   3475 	gl.texStorage2D(GL_TEXTURE_2D, reference_n_levels, reference_to_internalformat, reference_to_width,
   3476 					reference_to_height);
   3477 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
   3478 
   3479 	/* Set up immutable texture storage for two-dimensional array texture object */
   3480 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_id);
   3481 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3482 
   3483 	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, reference_n_levels, reference_to_internalformat, reference_to_width,
   3484 					reference_to_height, reference_to_depth);
   3485 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed");
   3486 
   3487 	/* Set up immutable texture storage for two-dimensional array texture object, base
   3488 	 * level of which uses a resolution of 32x33. We'll need it to check case r) */
   3489 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_32_by_33_id);
   3490 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3491 
   3492 	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, reference_n_levels, reference_to_internalformat, 32, /* width */
   3493 					33,																		  /* height */
   3494 					6); /* depth - 6 layers so that a cube-map/cube-map array view can be created from this texture */
   3495 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed");
   3496 
   3497 	/* Set up immutable texture storage for two-dimensional multisample texture object */
   3498 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_reference_immutable_to_2d_multisample_id);
   3499 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3500 
   3501 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_samples_value, reference_to_internalformat,
   3502 							   reference_to_width, reference_to_height, GL_TRUE); /* fixedsamplelocations */
   3503 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed");
   3504 
   3505 	/* Set up immutable texture storage for three-dimensional texture object */
   3506 	gl.bindTexture(GL_TEXTURE_3D, m_reference_immutable_to_3d_id);
   3507 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3508 
   3509 	gl.texStorage3D(GL_TEXTURE_3D, reference_n_levels, reference_to_internalformat, reference_to_width,
   3510 					reference_to_height, reference_to_depth);
   3511 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed");
   3512 
   3513 	/* Set up immutable texture storage for cube-map texture object */
   3514 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_cube_map_id);
   3515 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3516 
   3517 	gl.texStorage2D(GL_TEXTURE_CUBE_MAP, reference_n_levels, reference_to_internalformat, reference_to_width,
   3518 					reference_to_height);
   3519 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
   3520 
   3521 	/* Set up immutable texture storage for cube-map array texture object */
   3522 	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_cube_map_array_id);
   3523 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3524 
   3525 	gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, reference_n_levels, reference_to_internalformat, reference_to_width,
   3526 					reference_to_height, 6 /* layer-faces */ * reference_to_depth);
   3527 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
   3528 
   3529 	/* Set up immutable texture storage for rectangular texture object */
   3530 	gl.bindTexture(GL_TEXTURE_RECTANGLE, m_reference_immutable_to_rectangle_id);
   3531 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3532 
   3533 	gl.texStorage2D(GL_TEXTURE_RECTANGLE, reference_n_levels, reference_to_internalformat, reference_to_width,
   3534 					reference_to_height);
   3535 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
   3536 
   3537 	/* Set up mutable texture storage for two-dimensional texture object */
   3538 	gl.bindTexture(GL_TEXTURE_2D, m_reference_mutable_to_2d_id);
   3539 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3540 
   3541 	for (glw::GLint n_level = 0; n_level < reference_n_levels; ++n_level)
   3542 	{
   3543 		gl.texImage2D(GL_TEXTURE_2D, n_level, reference_to_internalformat, reference_to_width << n_level,
   3544 					  reference_to_height << n_level, 0,				/* border */
   3545 					  reference_to_format, reference_to_type, DE_NULL); /* pixels */
   3546 
   3547 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() call failed");
   3548 	}
   3549 
   3550 	/* Create texture objects we'll be attempting to define as texture views */
   3551 	gl.genTextures(1, &m_view_bound_to_id);
   3552 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
   3553 
   3554 	gl.genTextures(1, &m_view_never_bound_to_id);
   3555 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
   3556 
   3557 	gl.bindTexture(GL_TEXTURE_2D, m_view_bound_to_id);
   3558 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3559 
   3560 	/* a) GL_INVALID_VALUE should be generated if <texture> is 0. */
   3561 	glw::GLint error_code = GL_NO_ERROR;
   3562 
   3563 	gl.textureView(0,																			  /* texture */
   3564 				   GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat, 0, /* minlevel */
   3565 				   reference_n_levels, 0,														  /* minlayer */
   3566 				   1);																			  /* numlayers */
   3567 
   3568 	error_code = gl.getError();
   3569 	if (error_code != GL_INVALID_VALUE)
   3570 	{
   3571 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3572 						   << "]"
   3573 							  " error generated when passing <texture> argument of 0"
   3574 							  " to a glTextureView(), whereas GL_INVALID_VALUE was "
   3575 							  "expected."
   3576 						   << tcu::TestLog::EndMessage;
   3577 
   3578 		TCU_FAIL("GL_INVALID_VALUE not generated when passing 0 as <texture> argument to a "
   3579 				 "glTextureView() call.");
   3580 	}
   3581 
   3582 	/* b) GL_INVALID_OPERATION should be generated if <texture> is not
   3583 	 *    a valid name returned by glGenTextures().
   3584 	 */
   3585 	const glw::GLint invalid_to_id = 0xFFFFFFFF;
   3586 
   3587 	gl.textureView(invalid_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat,
   3588 				   0,					  /* minlevel */
   3589 				   reference_n_levels, 0, /* minlayer */
   3590 				   1);					  /* numlayers */
   3591 
   3592 	error_code = gl.getError();
   3593 	if (error_code != GL_INVALID_OPERATION)
   3594 	{
   3595 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3596 						   << "]"
   3597 							  " error generated when passing <texture> argument of"
   3598 							  " value that does not correspond to a valid texture "
   3599 							  "object ID, whereas GL_INVALID_OPERATION was expected."
   3600 						   << tcu::TestLog::EndMessage;
   3601 
   3602 		TCU_FAIL("GL_INVALID_OPERATION not generated when passing 0xFFFFFFFF as <texture> "
   3603 				 "argument to a glTextureView() call.");
   3604 	}
   3605 
   3606 	/* c) GL_INVALID_OPERATION should be generated if <texture> has
   3607 	 *    already been bound and given a target.
   3608 	 */
   3609 	gl.textureView(m_view_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat,
   3610 				   0,					  /* minlevel */
   3611 				   reference_n_levels, 0, /* minlayer */
   3612 				   1);					  /* numlayers */
   3613 
   3614 	error_code = gl.getError();
   3615 	if (error_code != GL_INVALID_OPERATION)
   3616 	{
   3617 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3618 						   << "]"
   3619 							  " error generated when passing <texture> argument "
   3620 							  " that refers to an ID of a texture object that has "
   3621 							  "already been bound to a texture target, whereas "
   3622 							  "GL_INVALID_OPERATION was expected."
   3623 						   << tcu::TestLog::EndMessage;
   3624 
   3625 		TCU_FAIL("GL_INVALID_OPERATION not generated when passing <texture> set"
   3626 				 " to an ID of a texture object, that has already been bound to"
   3627 				 " a texture target, to a glTextureView() call.");
   3628 	}
   3629 
   3630 	/* d) GL_INVALID_VALUE should be generated if <origtexture> is not
   3631 	 *    the name of a texture object.
   3632 	 */
   3633 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, invalid_to_id, reference_to_internalformat,
   3634 				   0,					  /* minlevel */
   3635 				   reference_n_levels, 0, /* minlayer */
   3636 				   1);					  /* numlayers */
   3637 
   3638 	error_code = gl.getError();
   3639 	if (error_code != GL_INVALID_VALUE)
   3640 	{
   3641 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3642 						   << "]"
   3643 							  " error generated when passing <origtexture> argument "
   3644 							  " of value 0xFFFFFFFF, whereas GL_INVALID_VALUE was "
   3645 							  "expected."
   3646 						   << tcu::TestLog::EndMessage;
   3647 
   3648 		TCU_FAIL("GL_INVALID_VALUE not generated when passing an invalid ID of a texture "
   3649 				 "object to <origtexture> argument.");
   3650 	}
   3651 
   3652 	/* e) GL_INVALID_OPERATION error should be generated if <origtexture>
   3653 	 *    is a mutable texture object.
   3654 	 */
   3655 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_mutable_to_2d_id, reference_to_internalformat,
   3656 				   0,					  /* minlevel */
   3657 				   reference_n_levels, 0, /* minlayer */
   3658 				   1);					  /* numlayers */
   3659 
   3660 	error_code = gl.getError();
   3661 	if (error_code != GL_INVALID_OPERATION)
   3662 	{
   3663 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3664 						   << "]"
   3665 							  " error generated when passing <origtexture> argument "
   3666 							  " set to refer to a mutable texture object, whereas "
   3667 							  "GL_INVALID_OPERATION was expected."
   3668 						   << tcu::TestLog::EndMessage;
   3669 
   3670 		TCU_FAIL("GL_INVALID_OPERATION not generated when passing an ID of a mutable "
   3671 				 "texture object through <origtexture> argument.");
   3672 	}
   3673 
   3674 	/* f) GL_INVALID_OPERATION error should be generated whenever the
   3675 	 *    application tries to generate a texture view for a target
   3676 	 *    that is incompatible with original texture's target. (as per
   3677 	 *    table 8.20 from OpenGL 4.3 specification)
   3678 	 *
   3679 	 *   NOTE: All invalid original+view texture target combinations
   3680 	 *         should be checked.
   3681 	 */
   3682 	TextureViewUtilities::_incompatible_texture_target_pairs incompatible_texture_target_pairs =
   3683 		TextureViewUtilities::getIllegalTextureAndViewTargetCombinations();
   3684 
   3685 	for (TextureViewUtilities::_incompatible_texture_target_pairs_const_iterator pair_iterator =
   3686 			 incompatible_texture_target_pairs.begin();
   3687 		 pair_iterator != incompatible_texture_target_pairs.end(); pair_iterator++)
   3688 	{
   3689 		TextureViewUtilities::_internalformat_pair texture_target_pair	 = *pair_iterator;
   3690 		glw::GLenum								   original_texture_target = texture_target_pair.first;
   3691 		glw::GLenum								   view_texture_target	 = texture_target_pair.second;
   3692 
   3693 		/* Generate texture IDs */
   3694 		gl.genTextures(1, &m_test_modified_to_id_1);
   3695 		gl.genTextures(1, &m_test_modified_to_id_2);
   3696 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
   3697 
   3698 		/* Configure reference texture object storage */
   3699 		gl.bindTexture(original_texture_target, m_test_modified_to_id_1);
   3700 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3701 
   3702 		TextureViewUtilities::initTextureStorage(gl, true, /* create mutable parent texture */
   3703 												 original_texture_target, reference_to_depth, reference_to_height,
   3704 												 reference_to_width, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
   3705 												 reference_n_levels, reference_n_cubemaps, reference_bo_id);
   3706 
   3707 		/* Attempt to create the invalid view */
   3708 		gl.textureView(m_test_modified_to_id_2,						 /* texture */
   3709 					   view_texture_target, m_test_modified_to_id_1, /* origtexture */
   3710 					   reference_to_internalformat, 0,				 /* minlevel */
   3711 					   reference_n_levels, 0,						 /* minlayer */
   3712 					   1);											 /* numlayers */
   3713 
   3714 		error_code = gl.getError();
   3715 		if (error_code != GL_INVALID_OPERATION)
   3716 		{
   3717 			m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3718 							   << "]"
   3719 								  " error generated when passing <origtexture> argument "
   3720 								  " set to refer to a mutable texture object, whereas "
   3721 								  "GL_INVALID_OPERATION was expected."
   3722 							   << tcu::TestLog::EndMessage;
   3723 
   3724 			TCU_FAIL("GL_INVALID_OPERATION not generated when passing an ID of a mutable "
   3725 					 "texture object through <origtexture> argument.");
   3726 		}
   3727 
   3728 		/* Release the texture IDs */
   3729 		gl.deleteTextures(1, &m_test_modified_to_id_1);
   3730 		m_test_modified_to_id_1 = 0;
   3731 
   3732 		gl.deleteTextures(1, &m_test_modified_to_id_2);
   3733 		m_test_modified_to_id_2 = 0;
   3734 
   3735 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed");
   3736 	} /* for (all incompatible texture target pairs) */
   3737 
   3738 	/* g) GL_INVALID_OPERATION error should be generated whenever the
   3739 	 *    application tries to create a texture view, internal format
   3740 	 *    of which can be found in table 8.21 of OpenGL 4.4
   3741 	 *    specification, and the texture view's internal format is
   3742 	 *    incompatible with parent object's internal format. Both
   3743 	 *    textures and views should be used as parent objects for the
   3744 	 *    purpose of the test.
   3745 	 *
   3746 	 * NOTE: All invalid texture view internal formats should be
   3747 	 *       checked for all applicable original object's internal
   3748 	 *       formats
   3749 	 */
   3750 	glw::GLint context_major_version = 0;
   3751 	glw::GLint context_minor_version = 0;
   3752 
   3753 	TextureViewUtilities::getMajorMinorVersionFromContextVersion(m_context.getRenderContext().getType(),
   3754 																 &context_major_version, &context_minor_version);
   3755 
   3756 	TextureViewUtilities::_incompatible_internalformat_pairs internalformat_pairs =
   3757 		TextureViewUtilities::getIllegalTextureAndViewInternalformatCombinations();
   3758 
   3759 	for (TextureViewUtilities::_incompatible_internalformat_pairs::const_iterator pair_iterator =
   3760 			 internalformat_pairs.begin();
   3761 		 pair_iterator != internalformat_pairs.end(); pair_iterator++)
   3762 	{
   3763 		glw::GLenum src_internalformat  = pair_iterator->first;
   3764 		glw::GLenum view_internalformat = pair_iterator->second;
   3765 
   3766 		/* Only run the test for internalformats supported by the tested OpenGL implementation */
   3767 		if (!TextureViewUtilities::isInternalformatSupported(src_internalformat, context_major_version,
   3768 															 context_minor_version) ||
   3769 			!TextureViewUtilities::isInternalformatSupported(view_internalformat, context_major_version,
   3770 															 context_minor_version))
   3771 		{
   3772 			/* Next iteration, please */
   3773 			continue;
   3774 		}
   3775 
   3776 		/* Generate texture IDs */
   3777 		gl.genTextures(1, &m_test_modified_to_id_1);
   3778 		gl.genTextures(1, &m_test_modified_to_id_2);
   3779 		gl.genTextures(1, &m_test_modified_to_id_3);
   3780 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
   3781 
   3782 		/* Configure reference texture object storage */
   3783 		gl.bindTexture(GL_TEXTURE_2D, m_test_modified_to_id_1);
   3784 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3785 
   3786 		TextureViewUtilities::initTextureStorage(
   3787 			gl, false,		  /* views require immutable parent texture objects */
   3788 			GL_TEXTURE_2D, 0, /* texture_depth */
   3789 			reference_to_height, reference_to_width, src_internalformat,
   3790 			GL_NONE,			   /* texture_format - not needed for immutable texture objects */
   3791 			GL_NONE,			   /* texture_type   - not needed for immutable texture objects */
   3792 			reference_n_levels, 0, /* n_cubemaps_needed */
   3793 			0);					   /* bo_id */
   3794 
   3795 		/* Attempt to create an invalid view */
   3796 		gl.textureView(m_test_modified_to_id_2,				   /* texture */
   3797 					   GL_TEXTURE_2D, m_test_modified_to_id_1, /* origtexture */
   3798 					   view_internalformat, 0,				   /* minlevel */
   3799 					   reference_n_levels, 0,				   /* minlayer */
   3800 					   1);									   /* numlayers */
   3801 
   3802 		error_code = gl.getError();
   3803 		if (error_code != GL_INVALID_OPERATION)
   3804 		{
   3805 			m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3806 							   << "]"
   3807 								  " error generated when requesting a view that uses "
   3808 								  " an internalformat that is incompatible with parent "
   3809 								  " texture object's, whereas GL_INVALID_OPERATION was "
   3810 								  "expected."
   3811 							   << tcu::TestLog::EndMessage;
   3812 
   3813 			TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view that "
   3814 					 "uses an internalformat which is incompatible with parent texture's.");
   3815 		}
   3816 
   3817 		/* Create a valid view now */
   3818 		gl.textureView(m_test_modified_to_id_2,				   /* texture */
   3819 					   GL_TEXTURE_2D, m_test_modified_to_id_1, /* origtexture */
   3820 					   src_internalformat, 0,				   /* minlevel */
   3821 					   reference_n_levels, 0,				   /* minlayer */
   3822 					   1);									   /* numlayers */
   3823 
   3824 		GLU_EXPECT_NO_ERROR(gl.getError(), "A valid glTextureView() call failed");
   3825 
   3826 		/* Attempt to create an invalid view, using the view we've just created
   3827 		 * as a parent */
   3828 		gl.textureView(m_test_modified_to_id_3,				   /* texture */
   3829 					   GL_TEXTURE_2D, m_test_modified_to_id_2, /* origtexture */
   3830 					   view_internalformat, 0,				   /* minlevel */
   3831 					   reference_n_levels, 0,				   /* minlayer */
   3832 					   1);									   /* numlayers */
   3833 
   3834 		error_code = gl.getError();
   3835 		if (error_code != GL_INVALID_OPERATION)
   3836 		{
   3837 			m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3838 							   << "]"
   3839 								  " error generated when requesting a view that uses "
   3840 								  " an internalformat that is incompatible with parent "
   3841 								  " view's, whereas GL_INVALID_OPERATION was expected."
   3842 							   << tcu::TestLog::EndMessage;
   3843 
   3844 			TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view that "
   3845 					 "uses an internalformat which is incompatible with parent view's.");
   3846 		}
   3847 
   3848 		/* Release the texture IDs */
   3849 		gl.deleteTextures(1, &m_test_modified_to_id_1);
   3850 		m_test_modified_to_id_1 = 0;
   3851 
   3852 		gl.deleteTextures(1, &m_test_modified_to_id_2);
   3853 		m_test_modified_to_id_2 = 0;
   3854 
   3855 		gl.deleteTextures(1, &m_test_modified_to_id_3);
   3856 		m_test_modified_to_id_3 = 0;
   3857 
   3858 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed");
   3859 	} /* for (all incompatible texture+view internalformat pairs) */
   3860 
   3861 	/* h) GL_INVALID_OPERATION error should be generated whenever the
   3862 	 *    application tries to create a texture view using an internal
   3863 	 *    format that does not match the original texture's, and the
   3864 	 *    original texture's internalformat cannot be found in table
   3865 	 *    8.21 of OpenGL 4.3 specification.
   3866 	 *
   3867 	 *    NOTE: All required base, sized and compressed texture internal
   3868 	 *          formats (as described in section 8.5.1 and table 8.14
   3869 	 *          of OpenGL 4.3 specification) that cannot be found in
   3870 	 *          table 8.21 should be considered for the purpose of this
   3871 	 *          test.
   3872 	 */
   3873 	for (int n_gl_internalformat = 0; n_gl_internalformat < n_valid_gl_internalformats; ++n_gl_internalformat)
   3874 	{
   3875 		glw::GLenum parent_texture_internalformat = valid_gl_internalformats[n_gl_internalformat];
   3876 
   3877 		/* Only run the test for internalformats supported by the tested OpenGL implementation */
   3878 		if (!TextureViewUtilities::isInternalformatSupported(parent_texture_internalformat, context_major_version,
   3879 															 context_minor_version))
   3880 		{
   3881 			/* Iterate the loop */
   3882 			continue;
   3883 		}
   3884 
   3885 		/* For the purpose of the test, only consider internalformats that
   3886 		 * are not associated with any view class */
   3887 		if (TextureViewUtilities::getViewClassForInternalformat(parent_texture_internalformat) == VIEW_CLASS_UNDEFINED)
   3888 		{
   3889 			/* Initialize parent texture object */
   3890 			gl.genTextures(1, &m_test_modified_to_id_1);
   3891 			gl.genTextures(1, &m_test_modified_to_id_2);
   3892 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
   3893 
   3894 			/* Configure reference texture object storage */
   3895 			gl.bindTexture(GL_TEXTURE_2D, m_test_modified_to_id_1);
   3896 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   3897 
   3898 			TextureViewUtilities::initTextureStorage(
   3899 				gl, false,		  /* views require immutable parent texture objects */
   3900 				GL_TEXTURE_2D, 0, /* texture_depth */
   3901 				reference_to_height, reference_to_width, parent_texture_internalformat,
   3902 				GL_NONE,			   /* texture_format - not needed for immutable texture objects */
   3903 				GL_NONE,			   /* texture_type   - not needed for immutable texture objects */
   3904 				reference_n_levels, 0, /* n_cubemaps_needed */
   3905 				0);					   /* bo_id */
   3906 
   3907 			/* Attempt to create the invalid view */
   3908 			gl.textureView(m_test_modified_to_id_2,													  /* texture */
   3909 						   GL_TEXTURE_2D, m_test_modified_to_id_1,									  /* origtexture */
   3910 						   (parent_texture_internalformat != GL_RGBA32F) ? GL_RGBA32F : GL_RGB32F, 0, /* minlevel */
   3911 						   reference_n_levels, 0,													  /* minlayer */
   3912 						   1);																		  /* numlayers */
   3913 
   3914 			error_code = gl.getError();
   3915 			if (error_code != GL_INVALID_OPERATION)
   3916 			{
   3917 				m_testCtx.getLog() << tcu::TestLog::Message << "["
   3918 								   << TextureViewUtilities::getErrorCodeString(error_code)
   3919 								   << "]"
   3920 									  " error generated when requesting a view that uses "
   3921 									  " an internalformat different than the one used by "
   3922 									  "parent texture object: "
   3923 									  "["
   3924 								   << parent_texture_internalformat
   3925 								   << "] "
   3926 									  " and the parent texture's internalformat is not "
   3927 									  "associated with any view class; GL_INVALID_OPERATION "
   3928 									  "was expected"
   3929 								   << tcu::TestLog::EndMessage;
   3930 
   3931 				TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view for "
   3932 						 "a parent texture, internalformat of which is not associated with any "
   3933 						 "view class, when the view's internalformat is different than the one "
   3934 						 "used for parent texture.");
   3935 			}
   3936 
   3937 			/* Release the texture IDs */
   3938 			gl.deleteTextures(1, &m_test_modified_to_id_1);
   3939 			m_test_modified_to_id_1 = 0;
   3940 
   3941 			gl.deleteTextures(1, &m_test_modified_to_id_2);
   3942 			m_test_modified_to_id_2 = 0;
   3943 
   3944 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed");
   3945 		} /* if (parent texture internalformat is not associated with a view class) */
   3946 	}	 /* for (all valid GL internalformats) */
   3947 
   3948 	/* i) GL_INVALID_VALUE error should be generated if <minlevel> is
   3949 	 *    larger than the greatest level of <origtexture>.
   3950 	 */
   3951 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat,
   3952 				   reference_n_levels, /* minlevel */
   3953 				   1,				   /* numlevels */
   3954 				   0,				   /* minlayer */
   3955 				   1);				   /* numlayers */
   3956 
   3957 	error_code = gl.getError();
   3958 	if (error_code != GL_INVALID_VALUE)
   3959 	{
   3960 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3961 						   << "]"
   3962 							  " error generated when passing <minlevel> argument "
   3963 							  " larger than the greatest level of <origtexture>, whereas "
   3964 							  "GL_INVALID_VALUE was expected."
   3965 						   << tcu::TestLog::EndMessage;
   3966 
   3967 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of <minlevel> "
   3968 				 "larger than the greatest level defined for <origtexture>");
   3969 	}
   3970 
   3971 	/* j) GL_INVALID_VALUE error should be generated if <minlayer> is
   3972 	 *    larger than the greatest layer of <origtexture>.
   3973 	 */
   3974 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_id,
   3975 				   reference_to_internalformat, 0, /* minlevel */
   3976 				   reference_n_levels,			   /* numlevels */
   3977 				   reference_to_depth,			   /* minlayer */
   3978 				   1);							   /* numlayers */
   3979 
   3980 	error_code = gl.getError();
   3981 	if (error_code != GL_INVALID_VALUE)
   3982 	{
   3983 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   3984 						   << "]"
   3985 							  " error generated when passing <minlayer> argument "
   3986 							  " larger than the greatest layer of <origtexture>, whereas "
   3987 							  "GL_INVALID_VALUE was expected."
   3988 						   << tcu::TestLog::EndMessage;
   3989 
   3990 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of <minlayer> "
   3991 				 "larger than the greatest layer defined for <origtexture>");
   3992 	}
   3993 
   3994 	/* k) GL_INVALID_VALUE error should be generated if <target> is
   3995 	 *    GL_TEXTURE_CUBE_MAP and <numlayers> is not 6.
   3996 	 */
   3997 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_cube_map_id,
   3998 				   reference_to_internalformat, 0, /* minlevel */
   3999 				   1,							   /* numlevels */
   4000 				   0,							   /* minlayer */
   4001 				   5);							   /* numlayers - invalid argument value */
   4002 
   4003 	error_code = gl.getError();
   4004 	if (error_code != GL_INVALID_VALUE)
   4005 	{
   4006 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4007 						   << "]"
   4008 							  " error generated when passing <numlayers> argument of value "
   4009 							  "5 instead of 6 for GL_TEXTURE_CUBE_MAP texture target, whereas "
   4010 							  "GL_INVALID_VALUE was expected."
   4011 						   << tcu::TestLog::EndMessage;
   4012 
   4013 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 5 to <minlayer>"
   4014 				 "argument");
   4015 	}
   4016 
   4017 	/* l) GL_INVALID_VALUE error should be generated if <target> is
   4018 	 *    GL_TEXTURE_CUBE_MAP_ARRAY and <numlayers> is not a multiple
   4019 	 *    of 6.
   4020 	 */
   4021 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_cube_map_array_id,
   4022 				   reference_to_internalformat, 0, /* minlevel */
   4023 				   1,							   /* numlevels */
   4024 				   0,							   /* minlayer */
   4025 				   1);							   /* numlayers - invalid argument value */
   4026 
   4027 	error_code = gl.getError();
   4028 	if (error_code != GL_INVALID_VALUE)
   4029 	{
   4030 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4031 						   << "]"
   4032 							  " error generated when passing <numlayers> argument of value "
   4033 							  "1 instead of a multiple of 6 for GL_TEXTURE_CUBE_MAP_ARRAY "
   4034 							  "texture target, whereas GL_INVALID_VALUE was expected."
   4035 						   << tcu::TestLog::EndMessage;
   4036 
   4037 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 1 to <minlayer>"
   4038 				 "argument for a GL_TEXTURE_CUBE_MAP_ARRAY texture target");
   4039 	}
   4040 
   4041 	/* m) GL_INVALID_VALUE error should be generated if <target> is
   4042 	 *    GL_TEXTURE_1D and <numlayers> is not 1;
   4043 	 */
   4044 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_1D, m_reference_immutable_to_1d_id, reference_to_internalformat,
   4045 				   0,  /* minlevel */
   4046 				   1,  /* numlevels */
   4047 				   0,  /* minlayer */
   4048 				   2); /* numlayers - invalid argument value */
   4049 
   4050 	error_code = gl.getError();
   4051 	if (error_code != GL_INVALID_VALUE)
   4052 	{
   4053 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4054 						   << "]"
   4055 							  " error generated when passing <numlayers> argument of value "
   4056 							  "2 instead of 1 for GL_TEXTURE_1D texture target, whereas "
   4057 							  "GL_INVALID_VALUE was expected."
   4058 						   << tcu::TestLog::EndMessage;
   4059 
   4060 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
   4061 				 "argument for a GL_TEXTURE_1D texture target");
   4062 	}
   4063 
   4064 	/* n) GL_INVALID_VALUE error should be generated if <target> is
   4065 	 *    GL_TEXTURE_2D and <numlayers> is not 1;
   4066 	 */
   4067 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat,
   4068 				   0,  /* minlevel */
   4069 				   1,  /* numlevels */
   4070 				   0,  /* minlayer */
   4071 				   2); /* numlayers - invalid argument value */
   4072 
   4073 	error_code = gl.getError();
   4074 	if (error_code != GL_INVALID_VALUE)
   4075 	{
   4076 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4077 						   << "]"
   4078 							  " error generated when passing <numlayers> argument of value "
   4079 							  "2 instead of 1 for GL_TEXTURE_2D texture target, whereas "
   4080 							  "GL_INVALID_VALUE was expected."
   4081 						   << tcu::TestLog::EndMessage;
   4082 
   4083 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
   4084 				 "argument for a GL_TEXTURE_2D texture target");
   4085 	}
   4086 
   4087 	/* o) GL_INVALID_VALUE error should be generated if <target> is
   4088 	 *    GL_TEXTURE_3D and <numlayers> is not 1;
   4089 	 */
   4090 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_3D, m_reference_immutable_to_3d_id, reference_to_internalformat,
   4091 				   0,  /* minlevel */
   4092 				   1,  /* numlevels */
   4093 				   0,  /* minlayer */
   4094 				   2); /* numlayers - invalid argument value */
   4095 
   4096 	error_code = gl.getError();
   4097 	if (error_code != GL_INVALID_VALUE)
   4098 	{
   4099 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4100 						   << "]"
   4101 							  " error generated when passing <numlayers> argument of value "
   4102 							  "2 instead of 1 for GL_TEXTURE_3D texture target, whereas "
   4103 							  "GL_INVALID_VALUE was expected."
   4104 						   << tcu::TestLog::EndMessage;
   4105 
   4106 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
   4107 				 "argument for a GL_TEXTURE_3D texture target");
   4108 	}
   4109 
   4110 	/* p) GL_INVALID_VALUE error should be generated if <target> is
   4111 	 *    GL_TEXTURE_RECTANGLE and <numlayers> is not 1;
   4112 	 */
   4113 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_RECTANGLE, m_reference_immutable_to_rectangle_id,
   4114 				   reference_to_internalformat, 0, /* minlevel */
   4115 				   1,							   /* numlevels */
   4116 				   0,							   /* minlayer */
   4117 				   2);							   /* numlayers - invalid argument value */
   4118 
   4119 	error_code = gl.getError();
   4120 	if (error_code != GL_INVALID_VALUE)
   4121 	{
   4122 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4123 						   << "]"
   4124 							  " error generated when passing <numlayers> argument of value "
   4125 							  "2 instead of 1 for GL_TEXTURE_RECTANGLE texture target, whereas "
   4126 							  "GL_INVALID_VALUE was expected."
   4127 						   << tcu::TestLog::EndMessage;
   4128 
   4129 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
   4130 				 "argument for a GL_TEXTURE_RECTANGLE texture target");
   4131 	}
   4132 
   4133 	/* q) GL_INVALID_VALUE error should be generated if <target> is
   4134 	 *    GL_TEXTURE_2D_MULTISAMPLE and <numlayers> is not 1;
   4135 	 */
   4136 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D_MULTISAMPLE, m_reference_immutable_to_2d_multisample_id,
   4137 				   reference_to_internalformat, 0, /* minlevel */
   4138 				   1,							   /* numlevels */
   4139 				   0,							   /* minlayer */
   4140 				   2);							   /* numlayers - invalid argument value */
   4141 
   4142 	error_code = gl.getError();
   4143 	if (error_code != GL_INVALID_VALUE)
   4144 	{
   4145 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4146 						   << "]"
   4147 							  " error generated when passing <numlayers> argument of value "
   4148 							  "2 instead of 1 for GL_TEXTURE_2D_MULTISAMPLE texture target, whereas "
   4149 							  "GL_INVALID_VALUE was expected."
   4150 						   << tcu::TestLog::EndMessage;
   4151 
   4152 		TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
   4153 				 "argument for a GL_TEXTURE_2D_MULTISAMPLE texture target");
   4154 	}
   4155 
   4156 	/* r) GL_INVALID_OPERATION error should be generated if <target> is
   4157 	 *    GL_TEXTURE_CUBE_MAP and original texture's width does not
   4158 	 *    match original texture's height for all levels.
   4159 	 */
   4160 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_2d_array_32_by_33_id,
   4161 				   reference_to_internalformat, 0, /* minlevel */
   4162 				   1,							   /* numlevels */
   4163 				   0,							   /* minlayer */
   4164 				   6);							   /* numlayers */
   4165 
   4166 	error_code = gl.getError();
   4167 	if (error_code != GL_INVALID_OPERATION)
   4168 	{
   4169 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4170 						   << "]"
   4171 							  " error generated when using an immutable 2D array texture of 32x33x6 "
   4172 							  "resolution to generate a GL_TEXTURE_CUBE_MAP view, whereas "
   4173 							  "GL_INVALID_OPERATION was expected."
   4174 						   << tcu::TestLog::EndMessage;
   4175 
   4176 		TCU_FAIL("GL_INVALID_OPERATION not generated when using an immutable 2D array texture of "
   4177 				 "32x33x6 resolution to generate a GL_TEXTURE_CUBE_MAP view");
   4178 	}
   4179 
   4180 	/* s) GL_INVALID_OPERATION error should be generated if <target> is
   4181 	 *    GL_TEXTURE_CUBE_MAP_ARRAY and original texture's width does
   4182 	 *    not match original texture's height for all levels.
   4183 	 */
   4184 	gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_2d_array_32_by_33_id,
   4185 				   reference_to_internalformat, 0, /* minlevel */
   4186 				   1,							   /* numlevels */
   4187 				   0,							   /* minlayer */
   4188 				   6);							   /* numlayers */
   4189 
   4190 	error_code = gl.getError();
   4191 	if (error_code != GL_INVALID_OPERATION)
   4192 	{
   4193 		m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
   4194 						   << "]"
   4195 							  " error generated when using an immutable 2D array texture of 32x33x6 "
   4196 							  "resolution to generate a GL_TEXTURE_CUBE_MAP_ARRAY view, whereas "
   4197 							  "GL_INVALID_OPERATION was expected."
   4198 						   << tcu::TestLog::EndMessage;
   4199 
   4200 		TCU_FAIL("GL_INVALID_OPERATION not generated when using an immutable 2D array texture of "
   4201 				 "32x33x6 resolution to generate a GL_TEXTURE_CUBE_MAP_ARRAY view");
   4202 	}
   4203 
   4204 	/* Test case passed */
   4205 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4206 
   4207 	return STOP;
   4208 }
   4209 
   4210 /** Constructor.
   4211  *
   4212  *  @param context Rendering context.
   4213  **/
   4214 TextureViewTestViewSampling::TextureViewTestViewSampling(deqp::Context& context)
   4215 	: TestCase(context, "view_sampling", "Verify that sampling data from texture views, that use internal "
   4216 										 "format which is compatible with the original texture's internal "
   4217 										 "format, works correctly.")
   4218 	, m_bo_id(0)
   4219 	, m_fs_id(0)
   4220 	, m_gs_id(0)
   4221 	, m_po_id(0)
   4222 	, m_po_lod_location(-1)
   4223 	, m_po_n_face_location(-1)
   4224 	, m_po_reference_colors_location(-1)
   4225 	, m_po_texture_location(-1)
   4226 	, m_po_z_float_location(-1)
   4227 	, m_po_z_int_location(-1)
   4228 	, m_tc_id(0)
   4229 	, m_te_id(0)
   4230 	, m_vs_id(0)
   4231 	, m_per_sample_filler_fs_id(0)
   4232 	, m_per_sample_filler_gs_id(0)
   4233 	, m_per_sample_filler_po_id(0)
   4234 	, m_per_sample_filler_po_layer_id_location(-1)
   4235 	, m_per_sample_filler_po_reference_colors_location(-1)
   4236 	, m_per_sample_filler_vs_id(0)
   4237 	, m_result_to_id(0)
   4238 	, m_to_id(0)
   4239 	, m_view_to_id(0)
   4240 	, m_fbo_id(0)
   4241 	, m_vao_id(0)
   4242 	, m_max_color_texture_samples_gl_value(0)
   4243 	, m_iteration_parent_texture_depth(0)
   4244 	, m_iteration_parent_texture_height(0)
   4245 	, m_iteration_parent_texture_n_levels(0)
   4246 	, m_iteration_parent_texture_n_samples(0)
   4247 	, m_iteration_parent_texture_target(GL_NONE)
   4248 	, m_iteration_parent_texture_width(0)
   4249 	, m_iteration_view_texture_minlayer(0)
   4250 	, m_iteration_view_texture_numlayers(0)
   4251 	, m_iteration_view_texture_minlevel(0)
   4252 	, m_iteration_view_texture_numlevels(0)
   4253 	, m_iteration_view_texture_target(GL_NONE)
   4254 	, m_reference_texture_depth(4)
   4255 	, m_reference_texture_height(4)
   4256 	, m_reference_texture_n_mipmaps(3)
   4257 	, m_reference_texture_width(4)
   4258 	, m_reference_color_storage(DE_NULL)
   4259 	, m_result_data(DE_NULL)
   4260 {
   4261 	/* Left blank on purpose */
   4262 }
   4263 
   4264 /** De-initializes all GL objects created for the test. */
   4265 void TextureViewTestViewSampling::deinit()
   4266 {
   4267 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4268 
   4269 	deinitIterationSpecificProgramAndShaderObjects();
   4270 	deinitPerSampleFillerProgramAndShaderObjects();
   4271 	deinitTextureObjects();
   4272 
   4273 	/* Make sure any buffers we may have allocated during the execution do not leak */
   4274 	if (m_result_data != DE_NULL)
   4275 	{
   4276 		delete[] m_result_data;
   4277 
   4278 		m_result_data = DE_NULL;
   4279 	}
   4280 
   4281 	/* Deinitialize other objects that are not re-created every iteration */
   4282 	if (m_bo_id != 0)
   4283 	{
   4284 		gl.deleteBuffers(1, &m_bo_id);
   4285 
   4286 		m_bo_id = 0;
   4287 	}
   4288 
   4289 	if (m_fbo_id != 0)
   4290 	{
   4291 		gl.deleteFramebuffers(1, &m_fbo_id);
   4292 
   4293 		m_fbo_id = 0;
   4294 	}
   4295 
   4296 	if (m_reference_color_storage != DE_NULL)
   4297 	{
   4298 		delete m_reference_color_storage;
   4299 
   4300 		m_reference_color_storage = DE_NULL;
   4301 	}
   4302 
   4303 	if (m_vao_id != 0)
   4304 	{
   4305 		gl.deleteVertexArrays(1, &m_vao_id);
   4306 
   4307 		m_vao_id = 0;
   4308 	}
   4309 
   4310 	/* Restore default GL state the test may have modified */
   4311 	gl.patchParameteri(GL_PATCH_VERTICES, 3);
   4312 	gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
   4313 	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4);
   4314 }
   4315 
   4316 /** De-initializes program and shader objects created for each iteration. **/
   4317 void TextureViewTestViewSampling::deinitIterationSpecificProgramAndShaderObjects()
   4318 {
   4319 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4320 
   4321 	if (m_fs_id != 0)
   4322 	{
   4323 		gl.deleteShader(m_fs_id);
   4324 
   4325 		m_fs_id = 0;
   4326 	}
   4327 
   4328 	if (m_gs_id != 0)
   4329 	{
   4330 		gl.deleteShader(m_gs_id);
   4331 
   4332 		m_gs_id = 0;
   4333 	}
   4334 
   4335 	if (m_po_id != 0)
   4336 	{
   4337 		gl.deleteProgram(m_po_id);
   4338 
   4339 		m_po_id = 0;
   4340 	}
   4341 
   4342 	if (m_tc_id != 0)
   4343 	{
   4344 		gl.deleteShader(m_tc_id);
   4345 
   4346 		m_tc_id = 0;
   4347 	}
   4348 
   4349 	if (m_te_id != 0)
   4350 	{
   4351 		gl.deleteShader(m_te_id);
   4352 
   4353 		m_te_id = 0;
   4354 	}
   4355 
   4356 	if (m_vs_id != 0)
   4357 	{
   4358 		gl.deleteShader(m_vs_id);
   4359 
   4360 		m_vs_id = 0;
   4361 	}
   4362 }
   4363 
   4364 /** De-initializes shader and program objects providing the 'per-sample filling'
   4365  *  functionality.
   4366  **/
   4367 void TextureViewTestViewSampling::deinitPerSampleFillerProgramAndShaderObjects()
   4368 {
   4369 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4370 
   4371 	if (m_per_sample_filler_fs_id != 0)
   4372 	{
   4373 		gl.deleteShader(m_per_sample_filler_fs_id);
   4374 
   4375 		m_per_sample_filler_fs_id = 0;
   4376 	}
   4377 
   4378 	if (m_per_sample_filler_gs_id != 0)
   4379 	{
   4380 		gl.deleteShader(m_per_sample_filler_gs_id);
   4381 
   4382 		m_per_sample_filler_gs_id = 0;
   4383 	}
   4384 
   4385 	if (m_per_sample_filler_po_id != 0)
   4386 	{
   4387 		gl.deleteProgram(m_per_sample_filler_po_id);
   4388 
   4389 		m_per_sample_filler_po_id = 0;
   4390 	}
   4391 
   4392 	if (m_per_sample_filler_vs_id != 0)
   4393 	{
   4394 		gl.deleteShader(m_per_sample_filler_vs_id);
   4395 
   4396 		m_per_sample_filler_vs_id = 0;
   4397 	}
   4398 }
   4399 
   4400 /** De-initializes texture objects used by the test */
   4401 void TextureViewTestViewSampling::deinitTextureObjects()
   4402 {
   4403 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4404 
   4405 	if (m_result_to_id != 0)
   4406 	{
   4407 		gl.deleteTextures(1, &m_result_to_id);
   4408 
   4409 		m_result_to_id = 0;
   4410 	}
   4411 
   4412 	if (m_to_id != 0)
   4413 	{
   4414 		gl.deleteTextures(1, &m_to_id);
   4415 
   4416 		m_to_id = 0;
   4417 	}
   4418 
   4419 	if (m_view_to_id != 0)
   4420 	{
   4421 		gl.deleteTextures(1, &m_view_to_id);
   4422 
   4423 		m_view_to_id = 0;
   4424 	}
   4425 }
   4426 
   4427 /** Executes a single test iteration.
   4428  *
   4429  *  @return true if the iteration executed successfully, false otherwise.
   4430  **/
   4431 bool TextureViewTestViewSampling::executeTest()
   4432 {
   4433 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   4434 	bool				  result = true;
   4435 
   4436 	/* Bind the view to zero texture unit */
   4437 	gl.activeTexture(GL_TEXTURE0);
   4438 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
   4439 
   4440 	gl.bindTexture(m_iteration_view_texture_target, m_view_to_id);
   4441 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   4442 
   4443 	/* Bind the buffer object to zero TF binding point */
   4444 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
   4445 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
   4446 
   4447 	/* Activate the test program */
   4448 	gl.useProgram(m_po_id);
   4449 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   4450 
   4451 	/* Update draw framebuffer configuration so that the test's fragment shader draws
   4452 	 * to the result texture */
   4453 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   4454 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
   4455 
   4456 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_result_to_id, 0); /* level */
   4457 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
   4458 
   4459 	/* Allocate enough space to hold reference color data for all sample s*/
   4460 	float* reference_color_data = new float[m_iteration_parent_texture_n_samples * sizeof(float) * 4 /* rgba */];
   4461 
   4462 	/* Iterate through the layer/face/mipmap hierarchy. For each iteration, we
   4463 	 * potentially need to update relevant uniforms controlling the sampling process
   4464 	 * the test program object performs.
   4465 	 */
   4466 	bool is_view_cm_cma = (m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP ||
   4467 						   m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   4468 
   4469 	for (unsigned int n_current_layer = m_iteration_view_texture_minlayer;
   4470 		 n_current_layer < (m_iteration_view_texture_minlayer + m_iteration_view_texture_numlayers) && result;
   4471 		 n_current_layer++)
   4472 	{
   4473 		unsigned int n_texture_face  = 0;
   4474 		unsigned int n_texture_layer = 0;
   4475 		unsigned int n_view_face	 = 0;
   4476 		unsigned int n_view_layer	= 0;
   4477 
   4478 		if (is_view_cm_cma)
   4479 		{
   4480 			n_texture_face  = n_current_layer % 6;										 /* faces */
   4481 			n_texture_layer = n_current_layer / 6;										 /* faces */
   4482 			n_view_face		= (n_current_layer - m_iteration_view_texture_minlayer) % 6; /* faces */
   4483 			n_view_layer	= (n_current_layer - m_iteration_view_texture_minlayer) / 6; /* faces */
   4484 		}
   4485 		else
   4486 		{
   4487 			/* Only cube-map and cube-map array textures consist of faces. */
   4488 			n_texture_face  = 0;
   4489 			n_texture_layer = n_current_layer;
   4490 			n_view_face		= 0;
   4491 			n_view_layer	= n_current_layer;
   4492 		}
   4493 
   4494 		if (m_po_z_float_location != -1)
   4495 		{
   4496 			float z = 0.0f;
   4497 
   4498 			if (((false == is_view_cm_cma) && (m_iteration_view_texture_numlayers > 1)) ||
   4499 				((true == is_view_cm_cma) && (m_iteration_view_texture_numlayers > 6)))
   4500 			{
   4501 				if (is_view_cm_cma)
   4502 				{
   4503 					z = float(n_view_layer) / float(m_iteration_view_texture_numlayers / 6 - 1);
   4504 				}
   4505 				else
   4506 				{
   4507 					if (m_iteration_view_texture_numlayers > 1)
   4508 					{
   4509 						/* The program will be sampling a view so make sure that layer the shader accesses
   4510 						 * is relative to how our view was configured */
   4511 						z = float(n_view_layer - m_iteration_view_texture_minlayer) /
   4512 							float(m_iteration_view_texture_numlayers - 1);
   4513 					}
   4514 					else
   4515 					{
   4516 						/* z should stay at 0 */
   4517 					}
   4518 				}
   4519 			}
   4520 			else
   4521 			{
   4522 				/* z should stay at 0.0 */
   4523 			}
   4524 
   4525 			gl.uniform1f(m_po_z_float_location, z);
   4526 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed.");
   4527 		}
   4528 
   4529 		if (m_po_z_int_location != -1)
   4530 		{
   4531 			DE_ASSERT(!is_view_cm_cma);
   4532 
   4533 			gl.uniform1i(m_po_z_int_location, n_current_layer - m_iteration_view_texture_minlayer);
   4534 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   4535 		}
   4536 
   4537 		if (m_po_n_face_location != -1)
   4538 		{
   4539 			gl.uniform1i(m_po_n_face_location, n_view_face);
   4540 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   4541 		}
   4542 
   4543 		for (unsigned int n_mipmap = m_iteration_view_texture_minlevel;
   4544 			 n_mipmap < (m_iteration_view_texture_minlevel + m_iteration_view_texture_numlevels) && result; n_mipmap++)
   4545 		{
   4546 			if (m_po_lod_location != -1)
   4547 			{
   4548 				/* The program will be sampling a view so make sure that LOD the shader accesses
   4549 				 * is relative to how our view was configured.
   4550 				 */
   4551 				gl.uniform1f(m_po_lod_location, (float)(n_mipmap - m_iteration_view_texture_minlevel));
   4552 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   4553 			}
   4554 
   4555 			/* Update local reference color data storage */
   4556 			for (unsigned int n_sample = 0; n_sample < m_iteration_parent_texture_n_samples; ++n_sample)
   4557 			{
   4558 				tcu::Vec4 reference_color = getReferenceColor(n_texture_layer, n_texture_face, n_mipmap, n_sample);
   4559 
   4560 				reference_color_data[4 /* rgba */ * n_sample + 0] = reference_color.x();
   4561 				reference_color_data[4 /* rgba */ * n_sample + 1] = reference_color.y();
   4562 				reference_color_data[4 /* rgba */ * n_sample + 2] = reference_color.z();
   4563 				reference_color_data[4 /* rgba */ * n_sample + 3] = reference_color.w();
   4564 			}
   4565 
   4566 			/* Upload it to GPU */
   4567 			gl.uniform4fv(m_po_reference_colors_location, m_iteration_parent_texture_n_samples, reference_color_data);
   4568 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed.");
   4569 
   4570 			/* Bind the texture view to sample from */
   4571 			gl.bindTexture(m_iteration_view_texture_target, m_view_to_id);
   4572 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   4573 
   4574 			/* Draw a single patch. Given the rendering pipeline we've defined in the
   4575 			 * test program object, this should give us a nice full-screen quad, as well
   4576 			 * as 6*4 ints XFBed out, describing whether the view was sampled correctly.
   4577 			 */
   4578 			gl.beginTransformFeedback(GL_TRIANGLES);
   4579 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
   4580 			{
   4581 				gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
   4582 				GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   4583 			}
   4584 			gl.endTransformFeedback();
   4585 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
   4586 
   4587 			/* In order to verify if the texel data was sampled correctly, we need to do two things:
   4588 			 *
   4589 			 * 1) Verify buffer object contents;
   4590 			 * 2) Make sure that all texels of current render-target are vec4(1).
   4591 			 *
   4592 			 */
   4593 			const int* bo_storage_ptr = (const int*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   4594 
   4595 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   4596 			if (bo_storage_ptr == NULL)
   4597 			{
   4598 				TCU_FAIL("glMapBuffer() call succeeded but the pointer returned is NULL");
   4599 			}
   4600 
   4601 			/* The rendering pipeline should have written 6 vertices * 4 ints to the BO.
   4602 			 * The integers are set to 1 if the sampled texels were found valid, 0 otherwise,
   4603 			 * and are arranged in the following order:
   4604 			 *
   4605 			 * 1) Result of sampling in vertex shader stage;
   4606 			 * 2) Result of sampling in tessellation control shader stage;
   4607 			 * 3) Result of sampling in tessellation evaluation shader stage;
   4608 			 * 4) Result of sampling in geometry shader stage;
   4609 			 */
   4610 			for (unsigned int n_vertex = 0; n_vertex < 6 /* as per comment */ && result; ++n_vertex)
   4611 			{
   4612 				const int* vertex_data_ptr = bo_storage_ptr + n_vertex * 4 /* as per comment */;
   4613 				int		   vs_result	   = vertex_data_ptr[0];
   4614 				int		   tc_result	   = vertex_data_ptr[1];
   4615 				int		   te_result	   = vertex_data_ptr[2];
   4616 				int		   gs_result	   = vertex_data_ptr[3];
   4617 
   4618 				if (vs_result != 1)
   4619 				{
   4620 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled in vertex shader stage."
   4621 									   << tcu::TestLog::EndMessage;
   4622 
   4623 					result = false;
   4624 				}
   4625 
   4626 				if (tc_result != 1)
   4627 				{
   4628 					m_testCtx.getLog() << tcu::TestLog::Message
   4629 									   << "Invalid data was sampled in tessellation control shader stage."
   4630 									   << tcu::TestLog::EndMessage;
   4631 
   4632 					result = false;
   4633 				}
   4634 
   4635 				if (te_result != 1)
   4636 				{
   4637 					m_testCtx.getLog() << tcu::TestLog::Message
   4638 									   << "Invalid data was sampled in tessellation evaluation shader stage."
   4639 									   << tcu::TestLog::EndMessage;
   4640 
   4641 					result = false;
   4642 				}
   4643 
   4644 				if (gs_result != 1)
   4645 				{
   4646 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled in geometry shader stage."
   4647 									   << tcu::TestLog::EndMessage;
   4648 
   4649 					result = false;
   4650 				}
   4651 			} /* for (all vertices) */
   4652 
   4653 			/* Unmap the BO */
   4654 			gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   4655 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
   4656 
   4657 			/* Read texels rendered by the fragment shader. The texture attached uses
   4658 			 * GL_RGBA8 internalformat.*/
   4659 			m_result_data = new unsigned char[m_reference_texture_width * m_reference_texture_height * 4 /* RGBA */];
   4660 
   4661 			gl.bindTexture(GL_TEXTURE_2D, m_result_to_id);
   4662 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed for GL_TEXTURE_2D texture target.");
   4663 
   4664 			gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, GL_UNSIGNED_BYTE, m_result_data);
   4665 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage() call failed.");
   4666 
   4667 			/* The test fails if any of the fragments is not equal to vec4(1) */
   4668 			bool fs_result = true;
   4669 
   4670 			for (unsigned int y = 0; y < m_reference_texture_height && fs_result; ++y)
   4671 			{
   4672 				const unsigned char* row_ptr = m_result_data + m_reference_texture_width * y * 4 /* RGBA */;
   4673 
   4674 				for (unsigned int x = 0; x < m_reference_texture_width && fs_result; ++x)
   4675 				{
   4676 					const unsigned char* pixel_ptr = row_ptr + x * 4 /* RGBA */;
   4677 
   4678 					if (pixel_ptr[0] != 255 || pixel_ptr[1] != 255 || pixel_ptr[2] != 255 || pixel_ptr[3] != 255)
   4679 					{
   4680 						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled at (" << x << ", " << y
   4681 										   << ") "
   4682 											  "in fragment shader stage."
   4683 										   << tcu::TestLog::EndMessage;
   4684 
   4685 						fs_result = false;
   4686 					}
   4687 				} /* for (all columns) */
   4688 			}	 /* for (all rows) */
   4689 
   4690 			if (!fs_result)
   4691 			{
   4692 				result = false;
   4693 			}
   4694 
   4695 			/* Done - we can release the buffer at this point */
   4696 			delete[] m_result_data;
   4697 			m_result_data = DE_NULL;
   4698 		} /* for (all mip-maps) */
   4699 	}	 /* for (all texture layers) */
   4700 
   4701 	/* Release the reference color data buffer */
   4702 	delete[] reference_color_data;
   4703 	reference_color_data = DE_NULL;
   4704 
   4705 	/* All done */
   4706 	return result;
   4707 }
   4708 
   4709 /** Returns a different vec4 every time the function is called. Each component
   4710  *  is assigned a normalized value within <0, 1> range.
   4711  *
   4712  *  @return As per description.
   4713  **/
   4714 tcu::Vec4 TextureViewTestViewSampling::getRandomReferenceColor()
   4715 {
   4716 	static unsigned int seed = 195;
   4717 	tcu::Vec4			result;
   4718 
   4719 	result = tcu::Vec4(float((seed) % 255) / 255.0f, float((seed << 3) % 255) / 255.0f,
   4720 					   float((seed << 4) % 255) / 255.0f, float((seed << 5) % 255) / 255.0f);
   4721 
   4722 	seed += 17;
   4723 
   4724 	return result;
   4725 }
   4726 
   4727 /** Every test iteration is assigned a different set of so-called reference colors.
   4728  *  Depending on the texture target, each reference color corresponds to an unique color
   4729  *  used to build different layers/faces/mip-maps or even samples of tose.
   4730  *
   4731  *  Once the reference color storage is initialized, this function can be used to retrieve
   4732  *  details of a color allocated a specific sample of a layer/face mip-map.
   4733  *
   4734  *  This function will cause an assertion failure if an invalid layer/face/mipmap/sample is
   4735  *  requested, as well as if the reference color storage is not initialized at the time of the call.
   4736  *
   4737  *  @param n_layer  Layer index to use for the query. A value of 0 should be used for non-arrayed
   4738  *                  texture targets.
   4739  *  @param n_face   Face index to use for the query. A value of 0 should be used for non-CM texture
   4740  *                  targets. Otherwise:
   4741  *                  * 0 corresponds to +X;
   4742  *                  * 1 corresponds to -X;
   4743  *                  * 2 corresponds to +Y;
   4744  *                  * 3 corresponds to -Y;
   4745  *                  * 4 corresponds to +Z;
   4746  *                  * 5 corresponds to -Z.
   4747  *  @param n_mipmap Mip-map index to use for the query. A value of 0 should be used for non-mipmapped
   4748  *                  texture targets.
   4749  *  @param n_sample Sample index to use for the query. A value of 0 should be used for single-sampled
   4750  *                  texture targets.
   4751  *
   4752  *  @return Requested color data.
   4753  **/
   4754 tcu::Vec4 TextureViewTestViewSampling::getReferenceColor(unsigned int n_layer, unsigned int n_face,
   4755 														 unsigned int n_mipmap, unsigned int n_sample)
   4756 {
   4757 	tcu::Vec4 result;
   4758 
   4759 	DE_ASSERT(m_reference_color_storage != DE_NULL);
   4760 	if (m_reference_color_storage != DE_NULL)
   4761 	{
   4762 		bool is_parent_texture_cm_cma = (m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP ||
   4763 										 m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   4764 		bool is_view_texture_cm_cma = (m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP ||
   4765 									   m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   4766 
   4767 		if (is_view_texture_cm_cma && !is_parent_texture_cm_cma)
   4768 		{
   4769 			/* Parent texture is not using faces. Compute layer index, as
   4770 			 * if the texture was actually a CM or a CMA */
   4771 			unsigned int temp = n_layer * 6 /* layer-faces per layer */ + n_face;
   4772 
   4773 			n_layer = temp;
   4774 			n_face  = 0;
   4775 		}
   4776 		else if (!is_view_texture_cm_cma && is_parent_texture_cm_cma)
   4777 		{
   4778 			/* The other way around - assume the texture is a CM or CMA */
   4779 			n_face  = n_layer % 6; /* faces per cube-map layer */
   4780 			n_layer = n_layer / 6; /* faces per cube-map layer */
   4781 		}
   4782 
   4783 		DE_ASSERT(n_face < m_reference_color_storage->n_faces);
   4784 		DE_ASSERT(n_layer < m_reference_color_storage->n_layers);
   4785 		DE_ASSERT(n_mipmap < m_reference_color_storage->n_mipmaps);
   4786 		DE_ASSERT(n_sample < m_reference_color_storage->n_samples);
   4787 
   4788 		/* Hierarchy is:
   4789 		 *
   4790 		 * layers -> faces -> mipmaps -> samples */
   4791 		const unsigned int index =
   4792 			n_layer * (m_reference_color_storage->n_faces * m_reference_color_storage->n_mipmaps *
   4793 					   m_reference_color_storage->n_samples) +
   4794 			n_face * (m_reference_color_storage->n_mipmaps * m_reference_color_storage->n_samples) +
   4795 			n_mipmap * (m_reference_color_storage->n_samples) + n_sample;
   4796 
   4797 		result = m_reference_color_storage->data[index];
   4798 	}
   4799 
   4800 	return result;
   4801 }
   4802 
   4803 /* Retrieve max conformant sample count when GL_NV_internalformat_sample_query is supported */
   4804 glw::GLint TextureViewTestViewSampling::getMaxConformantSampleCount(glw::GLenum target, glw::GLenum internalFormat)
   4805 {
   4806 	(void)internalFormat;
   4807 	glw::GLint max_conformant_samples = 0;
   4808 
   4809 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4810 
   4811 	/* Return the max conformant sample count if extension is supported */
   4812 	if (m_context.getContextInfo().isExtensionSupported("GL_NV_internalformat_sample_query"))
   4813 	{
   4814 		glw::GLint