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 gl_sample_counts = 0;
   4815 		gl.getInternalformativ(target, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &gl_sample_counts);
   4816 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_NUM_SAMPLE_COUNTS pname");
   4817 
   4818 		/* Check and return the first conformant sample count */
   4819 		glw::GLint* gl_supported_samples = new glw::GLint[gl_sample_counts];
   4820 		if (gl_supported_samples)
   4821 		{
   4822 			gl.getInternalformativ(target, GL_RGBA8, GL_SAMPLES, gl_sample_counts, gl_supported_samples);
   4823 
   4824 			for (glw::GLint i = 0; i < gl_sample_counts; i++)
   4825 			{
   4826 				glw::GLint isConformant = 0;
   4827 				gl.getInternalformatSampleivNV(target, GL_RGBA8, gl_supported_samples[i], GL_CONFORMANT_NV, 1,
   4828 											   &isConformant);
   4829 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformatSampleivNV() call(s) failed");
   4830 
   4831 				if (isConformant && gl_supported_samples[i] > max_conformant_samples)
   4832 				{
   4833 					max_conformant_samples = gl_supported_samples[i];
   4834 				}
   4835 			}
   4836 			delete[] gl_supported_samples;
   4837 		}
   4838 	}
   4839 	else
   4840 	{
   4841 		/* Otherwise return GL_MAX_COLOR_TEXTURE_SAMPLES */
   4842 		gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_conformant_samples);
   4843 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname.");
   4844 	}
   4845 
   4846 	return max_conformant_samples;
   4847 }
   4848 
   4849 /** Initializes iteration-specific program object used to sample the texture data. */
   4850 void TextureViewTestViewSampling::initIterationSpecificProgramObject()
   4851 {
   4852 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4853 
   4854 	/* Release shader/program objects that may have been initialized in previous
   4855 	 * iterations.
   4856 	 */
   4857 	deinitIterationSpecificProgramAndShaderObjects();
   4858 
   4859 	/* Create program and shader objects */
   4860 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
   4861 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
   4862 	m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
   4863 	m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
   4864 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   4865 
   4866 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
   4867 
   4868 	m_po_id = gl.createProgram();
   4869 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
   4870 
   4871 	/* Prepare token replacement strings */
   4872 	std::stringstream n_samples_sstream;
   4873 	std::string		  sampler_declarations_string;
   4874 	std::string		  sample_fetch_string;
   4875 	std::string		  sample_fetch_fs_string;
   4876 	std::size_t		  token_location			 = std::string::npos;
   4877 	const char*		  token_n_samples			 = "N_SAMPLES";
   4878 	const char*		  token_sampler_declarations = "SAMPLER_DECLARATIONS";
   4879 	const char*		  token_sample_fetch		 = "SAMPLE_FETCH";
   4880 
   4881 	n_samples_sstream << m_iteration_parent_texture_n_samples;
   4882 
   4883 	switch (m_iteration_view_texture_target)
   4884 	{
   4885 	case GL_TEXTURE_1D:
   4886 	{
   4887 		sampler_declarations_string = "uniform sampler1D texture;";
   4888 		sample_fetch_string			= "vec4 current_sample = textureLod(texture, 0.5,        lod);\n";
   4889 		sample_fetch_fs_string		= "vec4 current_sample = textureLod(texture, gs_fs_uv.x, lod);\n";
   4890 
   4891 		break;
   4892 	}
   4893 
   4894 	case GL_TEXTURE_1D_ARRAY:
   4895 	{
   4896 		sampler_declarations_string = "uniform sampler1DArray texture;\n"
   4897 									  "uniform float          z_float;\n";
   4898 
   4899 		sample_fetch_string	= "vec4 current_sample = textureLod(texture, vec2(0.5, z_float), lod);\n";
   4900 		sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec2(gs_fs_uv.x, z_float), lod);\n";
   4901 
   4902 		break;
   4903 	}
   4904 
   4905 	case GL_TEXTURE_2D:
   4906 	{
   4907 		sampler_declarations_string = "uniform sampler2D texture;";
   4908 		sample_fetch_string			= "vec4 current_sample = textureLod(texture, vec2(0.5), lod);\n";
   4909 		sample_fetch_fs_string		= "vec4 current_sample = textureLod(texture, gs_fs_uv, lod);\n";
   4910 
   4911 		break;
   4912 	}
   4913 
   4914 	case GL_TEXTURE_2D_ARRAY:
   4915 	{
   4916 		sampler_declarations_string = "uniform float          z_float;\n"
   4917 									  "uniform sampler2DArray texture;";
   4918 
   4919 		sample_fetch_string	= "vec4 current_sample = textureLod(texture, vec3(vec2(0.5), z_float), lod);\n";
   4920 		sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec3(gs_fs_uv, z_float), lod);\n";
   4921 
   4922 		break;
   4923 	}
   4924 
   4925 	case GL_TEXTURE_2D_MULTISAMPLE:
   4926 	{
   4927 		sampler_declarations_string = "uniform sampler2DMS texture;";
   4928 		sample_fetch_string			= "ivec2 texture_size   = textureSize(texture);\n"
   4929 							  "vec4  current_sample = texelFetch (texture,\n"
   4930 							  "                                   ivec2(texture_size.xy / ivec2(2)),\n"
   4931 							  "                                   n_sample);\n";
   4932 
   4933 		sample_fetch_fs_string = "ivec2 texture_size   = textureSize(texture);\n"
   4934 								 "vec4  current_sample = texelFetch (texture,\n"
   4935 								 "                                   ivec2(gs_fs_uv * vec2(texture_size)),\n"
   4936 								 "                                   n_sample);\n";
   4937 
   4938 		break;
   4939 	}
   4940 
   4941 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   4942 	{
   4943 		sampler_declarations_string = "uniform sampler2DMSArray texture;"
   4944 									  "uniform int              z_int;\n";
   4945 
   4946 		sample_fetch_string = "ivec3 texture_size   = textureSize(texture);\n"
   4947 							  "vec4  current_sample = texelFetch (texture,\n"
   4948 							  "                                   ivec3(texture_size.xy / ivec2(2), z_int),\n"
   4949 							  "                                   n_sample);\n";
   4950 
   4951 		sample_fetch_fs_string =
   4952 			"ivec3 texture_size = textureSize(texture);\n"
   4953 			"vec4  current_sample = texelFetch (texture,\n"
   4954 			"                                   ivec3(ivec2(gs_fs_uv * vec2(texture_size).xy), z_int),\n"
   4955 			"                                   n_sample);\n";
   4956 
   4957 		break;
   4958 	}
   4959 
   4960 	case GL_TEXTURE_3D:
   4961 	{
   4962 		sampler_declarations_string = "uniform sampler3D texture;"
   4963 									  "uniform float     z_float;";
   4964 
   4965 		sample_fetch_string	= "vec4 current_sample = textureLod(texture, vec3(vec2(0.5), z_float), lod);\n";
   4966 		sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec3(gs_fs_uv, z_float), lod);\n";
   4967 
   4968 		break;
   4969 	}
   4970 
   4971 	case GL_TEXTURE_CUBE_MAP:
   4972 	{
   4973 		sampler_declarations_string = "uniform samplerCube texture;\n"
   4974 									  "uniform int         n_face;";
   4975 
   4976 		sample_fetch_string = "vec4 current_sample;\n"
   4977 							  "\n"
   4978 							  "switch (n_face)\n"
   4979 							  "{\n"
   4980 							  // GL_TEXTURE_CUBE_MAP_POSITIVE_X
   4981 							  "    case 0: current_sample = textureLod(texture, vec3( 1,  0,  0), lod); break;\n"
   4982 							  // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
   4983 							  "    case 1: current_sample = textureLod(texture, vec3(-1,  0,  0), lod); break;\n"
   4984 							  // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
   4985 							  "    case 2: current_sample = textureLod(texture, vec3( 0,  1,  0), lod); break;\n"
   4986 							  // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
   4987 							  "    case 3: current_sample = textureLod(texture, vec3( 0, -1,  0), lod); break;\n"
   4988 							  // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
   4989 							  "    case 4: current_sample = textureLod(texture, vec3( 0,  0,  1), lod); break;\n"
   4990 							  // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
   4991 							  "    case 5: current_sample = textureLod(texture, vec3( 0,  0, -1), lod); break;\n"
   4992 							  "}\n";
   4993 
   4994 		sample_fetch_fs_string =
   4995 			"vec4 current_sample;\n"
   4996 			"\n"
   4997 			"switch (n_face)\n"
   4998 			"{\n"
   4999 			// GL_TEXTURE_CUBE_MAP_POSITIVE_X
   5000 			"    case 0: current_sample = textureLod(texture, normalize(vec3( 1, gs_fs_uv.xy)), lod); break;\n"
   5001 			// GL_TEXTURE_CUBE_MAP_NEGATIVE_X
   5002 			"    case 1: current_sample = textureLod(texture, normalize(vec3(-1, gs_fs_uv.xy)), lod); break;\n"
   5003 			// GL_TEXTURE_CUBE_MAP_POSITIVE_Y
   5004 			"    case 2: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.x, 1,  gs_fs_uv.y)), lod); "
   5005 			"break;\n"
   5006 			// GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
   5007 			"    case 3: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.x, -1, gs_fs_uv.y)), lod); "
   5008 			"break;\n"
   5009 			// GL_TEXTURE_CUBE_MAP_POSITIVE_Z
   5010 			"    case 4: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.xy,  1)), lod); break;\n"
   5011 			// GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
   5012 			"    case 5: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.xy, -1)), lod); break;\n"
   5013 			"}\n";
   5014 		break;
   5015 	}
   5016 
   5017 	case GL_TEXTURE_CUBE_MAP_ARRAY:
   5018 	{
   5019 		sampler_declarations_string = "uniform samplerCubeArray texture;\n"
   5020 									  "uniform int              n_face;\n"
   5021 									  "uniform float            z_float;\n";
   5022 
   5023 		sample_fetch_string =
   5024 			"vec4 current_sample;\n"
   5025 			"\n"
   5026 			"switch (n_face)\n"
   5027 			"{\n"
   5028 			// GL_TEXTURE_CUBE_MAP_POSITIVE_X
   5029 			"    case 0: current_sample = textureLod(texture, vec4( 1,  0,  0, z_float), lod); break;\n"
   5030 			// GL_TEXTURE_CUBE_MAP_NEGATIVE_X
   5031 			"    case 1: current_sample = textureLod(texture, vec4(-1,  0,  0, z_float), lod); break;\n"
   5032 			// GL_TEXTURE_CUBE_MAP_POSITIVE_Y
   5033 			"    case 2: current_sample = textureLod(texture, vec4( 0,  1,  0, z_float), lod); break;\n"
   5034 			// GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
   5035 			"    case 3: current_sample = textureLod(texture, vec4( 0, -1,  0, z_float), lod); break;\n"
   5036 			// GL_TEXTURE_CUBE_MAP_POSITIVE_Z
   5037 			"    case 4: current_sample = textureLod(texture, vec4( 0,  0,  1, z_float), lod); break;\n"
   5038 			// GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
   5039 			"    case 5: current_sample = textureLod(texture, vec4( 0,  0, -1, z_float), lod); break;\n"
   5040 			"}\n";
   5041 
   5042 		sample_fetch_fs_string = "vec4 current_sample;\n"
   5043 								 "\n"
   5044 								 "switch (n_face)\n"
   5045 								 "{\n"
   5046 								 // GL_TEXTURE_CUBE_MAP_POSITIVE_X
   5047 								 "    case 0: current_sample = textureLod(texture, vec4(normalize(vec3( 1, "
   5048 								 "gs_fs_uv.xy)), z_float), lod); break;\n"
   5049 								 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
   5050 								 "    case 1: current_sample = textureLod(texture, vec4(normalize(vec3(-1, "
   5051 								 "gs_fs_uv.xy)), z_float), lod); break;\n"
   5052 								 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
   5053 								 "    case 2: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.x, 1, "
   5054 								 " gs_fs_uv.y)), z_float), lod); break;\n"
   5055 								 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
   5056 								 "    case 3: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.x, "
   5057 								 "-1,  gs_fs_uv.y)), z_float), lod); break;\n"
   5058 								 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
   5059 								 "    case 4: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.xy, "
   5060 								 "1)), z_float), lod); break;\n"
   5061 								 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
   5062 								 "    case 5: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.xy, "
   5063 								 "-1)), z_float), lod); break;\n"
   5064 								 "}\n";
   5065 
   5066 		break;
   5067 	}
   5068 
   5069 	case GL_TEXTURE_RECTANGLE:
   5070 	{
   5071 		sampler_declarations_string = "uniform sampler2DRect texture;";
   5072 		sample_fetch_string			= "ivec2 texture_size   = textureSize(texture);\n"
   5073 							  "vec4  current_sample = texelFetch (texture, texture_size / ivec2(2));\n";
   5074 
   5075 		sample_fetch_fs_string =
   5076 			"ivec2 texture_size   = textureSize(texture);\n"
   5077 			"vec4  current_sample = texelFetch (texture, ivec2(gs_fs_uv.xy * vec2(texture_size)));\n";
   5078 
   5079 		break;
   5080 	}
   5081 
   5082 	default:
   5083 	{
   5084 		TCU_FAIL("Unrecognized texture target");
   5085 	}
   5086 	} /* switch (m_iteration_view_texture_target) */
   5087 
   5088 	/* Set vertex shader's body */
   5089 	const char* vs_body = "#version 400\n"
   5090 						  "\n"
   5091 						  "uniform float lod;\n"
   5092 						  "uniform vec4 reference_colors[N_SAMPLES];\n"
   5093 						  "SAMPLER_DECLARATIONS\n"
   5094 						  "\n"
   5095 						  "out int vs_tc_vs_sampling_result;\n"
   5096 						  "\n"
   5097 						  "void main()\n"
   5098 						  "{\n"
   5099 						  "    const float epsilon = 1.0 / 255.0;\n"
   5100 						  "\n"
   5101 						  "    vs_tc_vs_sampling_result = 1;\n"
   5102 						  "\n"
   5103 						  "    for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
   5104 						  "    {\n"
   5105 						  "        SAMPLE_FETCH;\n"
   5106 						  "\n"
   5107 						  "        if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
   5108 						  "            abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
   5109 						  "            abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
   5110 						  "            abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
   5111 						  "        {\n"
   5112 						  "            vs_tc_vs_sampling_result = int(current_sample.x * 256.0);\n"
   5113 						  "\n"
   5114 						  "            break;\n"
   5115 						  "        }\n"
   5116 						  "    }\n"
   5117 						  "\n"
   5118 						  "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
   5119 						  "}\n";
   5120 	std::string vs_string = vs_body;
   5121 
   5122 	while ((token_location = vs_string.find(token_n_samples)) != std::string::npos)
   5123 	{
   5124 		vs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
   5125 	}
   5126 
   5127 	while ((token_location = vs_string.find(token_sampler_declarations)) != std::string::npos)
   5128 	{
   5129 		vs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
   5130 	}
   5131 
   5132 	while ((token_location = vs_string.find(token_sample_fetch)) != std::string::npos)
   5133 	{
   5134 		vs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string);
   5135 	}
   5136 
   5137 	/* Set tessellation control shader's body */
   5138 	const char* tc_body = "#version 400\n"
   5139 						  "\n"
   5140 						  "layout(vertices = 1) out;\n"
   5141 						  "\n"
   5142 						  "uniform float lod;\n"
   5143 						  "uniform vec4  reference_colors[N_SAMPLES];\n"
   5144 						  "SAMPLER_DECLARATIONS\n"
   5145 						  "\n"
   5146 						  "in  int vs_tc_vs_sampling_result[];\n"
   5147 						  "out int tc_te_vs_sampling_result[];\n"
   5148 						  "out int tc_te_tc_sampling_result[];\n"
   5149 						  "\n"
   5150 						  "void main()\n"
   5151 						  "{\n"
   5152 						  "    const float epsilon = 1.0 / 255.0;\n"
   5153 						  "\n"
   5154 						  "    tc_te_vs_sampling_result[gl_InvocationID] = vs_tc_vs_sampling_result[gl_InvocationID];\n"
   5155 						  "    tc_te_tc_sampling_result[gl_InvocationID] = 1;\n"
   5156 						  "\n"
   5157 						  "    for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
   5158 						  "    {\n"
   5159 						  "        SAMPLE_FETCH\n"
   5160 						  "\n"
   5161 						  "        if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
   5162 						  "            abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
   5163 						  "            abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
   5164 						  "            abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
   5165 						  "        {\n"
   5166 						  "            tc_te_tc_sampling_result[gl_InvocationID] = 0;\n"
   5167 						  "\n"
   5168 						  "            break;\n"
   5169 						  "        }\n"
   5170 						  "    }\n"
   5171 						  "\n"
   5172 						  "   gl_TessLevelInner[0] = 1.0;\n"
   5173 						  "   gl_TessLevelInner[1] = 1.0;\n"
   5174 						  "   gl_TessLevelOuter[0] = 1.0;\n"
   5175 						  "   gl_TessLevelOuter[1] = 1.0;\n"
   5176 						  "   gl_TessLevelOuter[2] = 1.0;\n"
   5177 						  "   gl_TessLevelOuter[3] = 1.0;\n"
   5178 						  "}\n";
   5179 
   5180 	std::string tc_string = tc_body;
   5181 
   5182 	while ((token_location = tc_string.find(token_n_samples)) != std::string::npos)
   5183 	{
   5184 		tc_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
   5185 	}
   5186 
   5187 	while ((token_location = tc_string.find(token_sampler_declarations)) != std::string::npos)
   5188 	{
   5189 		tc_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
   5190 	}
   5191 
   5192 	while ((token_location = tc_string.find(token_sample_fetch)) != std::string::npos)
   5193 	{
   5194 		tc_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string);
   5195 	}
   5196 
   5197 	/* Set tessellation evaluation shader's body */
   5198 	const char* te_body = "#version 400\n"
   5199 						  "\n"
   5200 						  "layout(quads) in;\n"
   5201 						  "\n"
   5202 						  "in  int  tc_te_vs_sampling_result[];\n"
   5203 						  "in  int  tc_te_tc_sampling_result[];\n"
   5204 						  "out int  te_gs_vs_sampling_result;\n"
   5205 						  "out int  te_gs_tc_sampling_result;\n"
   5206 						  "out int  te_gs_te_sampling_result;\n"
   5207 						  "out vec2 te_gs_uv;\n"
   5208 						  "\n"
   5209 						  "uniform float lod;\n"
   5210 						  "uniform vec4  reference_colors[N_SAMPLES];\n"
   5211 						  "SAMPLER_DECLARATIONS\n"
   5212 						  "\n"
   5213 						  "void main()\n"
   5214 						  "{\n"
   5215 						  "    te_gs_vs_sampling_result = tc_te_vs_sampling_result[0];\n"
   5216 						  "    te_gs_tc_sampling_result = tc_te_tc_sampling_result[0];\n"
   5217 						  "    te_gs_te_sampling_result = 1;\n"
   5218 						  "\n"
   5219 						  /* gl_TessCoord spans from 0 to 1 for XY. To generate a screen-space quad,
   5220 		 * we need to project these components to <-1, 1>. */
   5221 						  "    gl_Position.xy = gl_TessCoord.xy * 2.0 - 1.0;\n"
   5222 						  "    gl_Position.zw = vec2(0, 1);\n"
   5223 						  "    te_gs_uv       = vec2(gl_TessCoord.x, 1.0 - gl_TessCoord.y);\n"
   5224 						  "\n"
   5225 						  "\n"
   5226 						  "    const float epsilon = 1.0 / 255.0;\n"
   5227 						  "\n"
   5228 						  "    for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
   5229 						  "    {\n"
   5230 						  "        SAMPLE_FETCH\n"
   5231 						  "\n"
   5232 						  "        if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
   5233 						  "            abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
   5234 						  "            abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
   5235 						  "            abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
   5236 						  "        {\n"
   5237 						  "            te_gs_te_sampling_result = 0;\n"
   5238 						  "\n"
   5239 						  "            break;\n"
   5240 						  "        }\n"
   5241 						  "    }\n"
   5242 						  "\n"
   5243 						  "}\n";
   5244 
   5245 	std::string te_string = te_body;
   5246 
   5247 	while ((token_location = te_string.find(token_n_samples)) != std::string::npos)
   5248 	{
   5249 		te_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
   5250 	}
   5251 
   5252 	while ((token_location = te_string.find(token_sampler_declarations)) != std::string::npos)
   5253 	{
   5254 		te_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
   5255 	}
   5256 
   5257 	while ((token_location = te_string.find(token_sample_fetch)) != std::string::npos)
   5258 	{
   5259 		te_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string);
   5260 	}
   5261 
   5262 	/* Set geometry shader's body */
   5263 	const char* gs_body = "#version 400\n"
   5264 						  "\n"
   5265 						  "layout (triangles)                        in;\n"
   5266 						  "layout (triangle_strip, max_vertices = 3) out;\n"
   5267 						  "\n"
   5268 						  "in  int  te_gs_vs_sampling_result[];\n"
   5269 						  "in  int  te_gs_tc_sampling_result[];\n"
   5270 						  "in  int  te_gs_te_sampling_result[];\n"
   5271 						  "in  vec2 te_gs_uv                [];\n"
   5272 						  "out int  gs_fs_vs_sampling_result;\n"
   5273 						  "out int  gs_fs_tc_sampling_result;\n"
   5274 						  "out int  gs_fs_te_sampling_result;\n"
   5275 						  "out int  gs_fs_gs_sampling_result;\n"
   5276 						  "out vec2 gs_fs_uv;\n"
   5277 						  "\n"
   5278 						  "uniform float lod;\n"
   5279 						  "uniform vec4  reference_colors[N_SAMPLES];\n"
   5280 						  "SAMPLER_DECLARATIONS\n"
   5281 						  "\n"
   5282 						  "void main()\n"
   5283 						  "{\n"
   5284 						  "    const float epsilon            = 1.0 / 255.0;\n"
   5285 						  "    int         gs_sampling_result = 1;\n"
   5286 						  "    int         tc_sampling_result = te_gs_tc_sampling_result[0] & "
   5287 						  "te_gs_tc_sampling_result[1] & te_gs_tc_sampling_result[2];\n"
   5288 						  "    int         te_sampling_result = te_gs_te_sampling_result[0] & "
   5289 						  "te_gs_te_sampling_result[1] & te_gs_te_sampling_result[2];\n"
   5290 						  "    int         vs_sampling_result = te_gs_vs_sampling_result[0] & "
   5291 						  "te_gs_vs_sampling_result[1] & te_gs_vs_sampling_result[2];\n"
   5292 						  "\n"
   5293 						  "    for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
   5294 						  "    {\n"
   5295 						  "        SAMPLE_FETCH;\n"
   5296 						  "\n"
   5297 						  "        if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
   5298 						  "            abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
   5299 						  "            abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
   5300 						  "            abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
   5301 						  "        {\n"
   5302 						  "            gs_sampling_result = 0;\n"
   5303 						  "\n"
   5304 						  "            break;\n"
   5305 						  "        }\n"
   5306 						  "    }\n"
   5307 						  "\n"
   5308 						  "    gl_Position              = gl_in[0].gl_Position;\n"
   5309 						  "    gs_fs_uv                 = te_gs_uv[0];\n"
   5310 						  "    gs_fs_gs_sampling_result = gs_sampling_result;\n"
   5311 						  "    gs_fs_tc_sampling_result = tc_sampling_result;\n"
   5312 						  "    gs_fs_te_sampling_result = te_sampling_result;\n"
   5313 						  "    gs_fs_vs_sampling_result = vs_sampling_result;\n"
   5314 						  "    EmitVertex();\n"
   5315 						  "\n"
   5316 						  "    gl_Position              = gl_in[1].gl_Position;\n"
   5317 						  "    gs_fs_uv                 = te_gs_uv[1];\n"
   5318 						  "    gs_fs_gs_sampling_result = gs_sampling_result;\n"
   5319 						  "    gs_fs_tc_sampling_result = tc_sampling_result;\n"
   5320 						  "    gs_fs_te_sampling_result = te_sampling_result;\n"
   5321 						  "    gs_fs_vs_sampling_result = vs_sampling_result;\n"
   5322 						  "    EmitVertex();\n"
   5323 						  "\n"
   5324 						  "    gl_Position              = gl_in[2].gl_Position;\n"
   5325 						  "    gs_fs_uv                 = te_gs_uv[2];\n"
   5326 						  "    gs_fs_gs_sampling_result = gs_sampling_result;\n"
   5327 						  "    gs_fs_tc_sampling_result = tc_sampling_result;\n"
   5328 						  "    gs_fs_te_sampling_result = te_sampling_result;\n"
   5329 						  "    gs_fs_vs_sampling_result = vs_sampling_result;\n"
   5330 						  "    EmitVertex();\n"
   5331 						  "    EndPrimitive();\n"
   5332 						  "}\n";
   5333 
   5334 	std::string gs_string = gs_body;
   5335 
   5336 	while ((token_location = gs_string.find(token_n_samples)) != std::string::npos)
   5337 	{
   5338 		gs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
   5339 	}
   5340 
   5341 	while ((token_location = gs_string.find(token_sampler_declarations)) != std::string::npos)
   5342 	{
   5343 		gs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
   5344 	}
   5345 
   5346 	while ((token_location = gs_string.find(token_sample_fetch)) != std::string::npos)
   5347 	{
   5348 		gs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string);
   5349 	}
   5350 
   5351 	/* Set fragment shader's body */
   5352 	const char* fs_body = "#version 400\n"
   5353 						  "\n"
   5354 						  "in vec2 gs_fs_uv;\n"
   5355 						  "\n"
   5356 						  "uniform float lod;\n"
   5357 						  "uniform vec4  reference_colors[N_SAMPLES];\n"
   5358 						  "SAMPLER_DECLARATIONS\n"
   5359 						  "\n"
   5360 						  "out vec4 result;\n"
   5361 						  "\n"
   5362 						  "void main()\n"
   5363 						  "{\n"
   5364 						  "    const float epsilon = 1.0 / 255.0;\n"
   5365 						  "\n"
   5366 						  "    result = vec4(1.0);\n"
   5367 						  "\n"
   5368 						  "    for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
   5369 						  "    {\n"
   5370 						  "        SAMPLE_FETCH\n"
   5371 						  "\n"
   5372 						  "        if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
   5373 						  "            abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
   5374 						  "            abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
   5375 						  "            abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
   5376 						  "        {\n"
   5377 						  "            result = vec4(0.0);\n"
   5378 						  "\n"
   5379 						  "            break;\n"
   5380 						  "        }\n"
   5381 						  "    }\n"
   5382 						  "}\n";
   5383 
   5384 	std::string fs_string = fs_body;
   5385 
   5386 	while ((token_location = fs_string.find(token_n_samples)) != std::string::npos)
   5387 	{
   5388 		fs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
   5389 	}
   5390 
   5391 	while ((token_location = fs_string.find(token_sampler_declarations)) != std::string::npos)
   5392 	{
   5393 		fs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
   5394 	}
   5395 
   5396 	while ((token_location = fs_string.find(token_sample_fetch)) != std::string::npos)
   5397 	{
   5398 		fs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_fs_string);
   5399 	}
   5400 
   5401 	/* Configure shader bodies */
   5402 	const char* fs_body_raw_ptr = fs_string.c_str();
   5403 	const char* gs_body_raw_ptr = gs_string.c_str();
   5404 	const char* tc_body_raw_ptr = tc_string.c_str();
   5405 	const char* te_body_raw_ptr = te_string.c_str();
   5406 	const char* vs_body_raw_ptr = vs_string.c_str();
   5407 
   5408 	gl.shaderSource(m_fs_id, 1 /* count */, &fs_body_raw_ptr, NULL /* length */);
   5409 	gl.shaderSource(m_gs_id, 1 /* count */, &gs_body_raw_ptr, NULL /* length */);
   5410 	gl.shaderSource(m_tc_id, 1 /* count */, &tc_body_raw_ptr, NULL /* length */);
   5411 	gl.shaderSource(m_te_id, 1 /* count */, &te_body_raw_ptr, NULL /* length */);
   5412 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, NULL /* length */);
   5413 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
   5414 
   5415 	/* Compile the shaders */
   5416 	const glw::GLuint  so_ids[] = { m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
   5417 	const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
   5418 
   5419 	const glw::GLchar* shader_sources[] = { fs_body_raw_ptr, gs_body_raw_ptr, tc_body_raw_ptr, te_body_raw_ptr,
   5420 											vs_body_raw_ptr };
   5421 
   5422 	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
   5423 	{
   5424 		glw::GLint compile_status = GL_FALSE;
   5425 		glw::GLint so_id		  = so_ids[n_so_id];
   5426 
   5427 		gl.compileShader(so_id);
   5428 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   5429 
   5430 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
   5431 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   5432 
   5433 		if (compile_status != GL_TRUE)
   5434 		{
   5435 			char temp[1024];
   5436 
   5437 			gl.getShaderInfoLog(so_id, 1024, NULL, temp);
   5438 
   5439 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation error log:\n"
   5440 												<< temp << "\nShader source:\n"
   5441 												<< shader_sources[n_so_id] << tcu::TestLog::EndMessage;
   5442 
   5443 			TCU_FAIL("Shader compilation failed");
   5444 		}
   5445 
   5446 		/* Attach the shaders to the program object */
   5447 		gl.attachShader(m_po_id, so_id);
   5448 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed");
   5449 	} /* for (all shader objects) */
   5450 
   5451 	/* Set up XFB */
   5452 	const char* varying_names[] = { "gs_fs_vs_sampling_result", "gs_fs_tc_sampling_result", "gs_fs_te_sampling_result",
   5453 									"gs_fs_gs_sampling_result" };
   5454 	const unsigned int n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]);
   5455 
   5456 	gl.transformFeedbackVaryings(m_po_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
   5457 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
   5458 
   5459 	/* Link the program object */
   5460 	glw::GLint link_status = GL_FALSE;
   5461 
   5462 	gl.linkProgram(m_po_id);
   5463 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   5464 
   5465 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   5466 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   5467 
   5468 	if (link_status != GL_TRUE)
   5469 	{
   5470 		TCU_FAIL("Program linking failed.");
   5471 	}
   5472 
   5473 	/* Retrieve uniform locations. Depending on the iteration, a number of those will be
   5474 	 * inactive.
   5475 	 */
   5476 	m_po_lod_location			   = gl.getUniformLocation(m_po_id, "lod");
   5477 	m_po_n_face_location		   = gl.getUniformLocation(m_po_id, "n_face");
   5478 	m_po_reference_colors_location = gl.getUniformLocation(m_po_id, "reference_colors");
   5479 	m_po_texture_location		   = gl.getUniformLocation(m_po_id, "texture");
   5480 	m_po_z_float_location		   = gl.getUniformLocation(m_po_id, "z_float");
   5481 	m_po_z_int_location			   = gl.getUniformLocation(m_po_id, "z_int");
   5482 
   5483 	if (m_po_reference_colors_location == -1)
   5484 	{
   5485 		TCU_FAIL("reference_colors is considered an inactive uniform which is invalid.");
   5486 	}
   5487 }
   5488 
   5489 /** Initializes contents of a texture, from which the view texture will be created. **/
   5490 void TextureViewTestViewSampling::initParentTextureContents()
   5491 {
   5492 	static const glw::GLenum cm_texture_targets[] = {
   5493 		/* NOTE: This order must match the order used for sampling CM/CMA texture targets. */
   5494 		GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
   5495 		GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
   5496 	};
   5497 	static const unsigned int n_cm_texture_targets = sizeof(cm_texture_targets) / sizeof(cm_texture_targets[0]);
   5498 	const glw::Functions&	 gl				   = m_context.getRenderContext().getFunctions();
   5499 
   5500 	/* Bind the parent texture */
   5501 	gl.bindTexture(m_iteration_parent_texture_target, m_to_id);
   5502 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   5503 
   5504 	/* If we're dealing with a single-sampled texture target, then we can clear the
   5505 	 * contents of each layer/face/slice using FBO. This will unfortunately not work
   5506 	 * for arrayed textures, layers or layer-faces of which cannot be attached to a draw
   5507 	 * framebuffer.
   5508 	 * If we need to update contents of a multisampled, potentially arrayed texture,
   5509 	 * we'll need to use the filler program.
   5510 	 **/
   5511 	bool is_arrayed_texture_target = (m_iteration_parent_texture_target == GL_TEXTURE_1D_ARRAY ||
   5512 									  m_iteration_parent_texture_target == GL_TEXTURE_2D_ARRAY ||
   5513 									  m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   5514 	bool is_multisampled_texture_target = (m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
   5515 										   m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
   5516 
   5517 	if (!is_arrayed_texture_target && !is_multisampled_texture_target)
   5518 	{
   5519 		/* Good, no need to work with samples! */
   5520 		DE_ASSERT(m_iteration_parent_texture_depth >= 1);
   5521 		DE_ASSERT(m_iteration_parent_texture_n_levels >= 1);
   5522 
   5523 		/* Cube-map texture target cannot be directly used for a glFramebufferTexture2D() call. Instead,
   5524 		 * we need to split it into 6 cube-map texture targets. */
   5525 		unsigned int n_texture_targets					   = 1;
   5526 		glw::GLenum  texture_targets[n_cm_texture_targets] = {
   5527 			m_iteration_parent_texture_target, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE,
   5528 		};
   5529 
   5530 		if (m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP)
   5531 		{
   5532 			DE_STATIC_ASSERT(sizeof(texture_targets) == sizeof(cm_texture_targets));
   5533 			memcpy(texture_targets, cm_texture_targets, sizeof(cm_texture_targets));
   5534 
   5535 			n_texture_targets = n_cm_texture_targets;
   5536 		}
   5537 
   5538 		resetReferenceColorStorage(m_iteration_parent_texture_depth,	/* n_layers */
   5539 								   n_texture_targets,					/* n_faces */
   5540 								   m_iteration_parent_texture_n_levels, /* n_mipmaps */
   5541 								   1);									/* n_samples */
   5542 
   5543 		/* Iterate through all texture targets we need to update */
   5544 		for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
   5545 		{
   5546 			const glw::GLenum texture_target = texture_targets[n_texture_target];
   5547 
   5548 			/* Iterate through all layers of the texture. */
   5549 			for (unsigned int n_layer = 0; n_layer < m_iteration_parent_texture_depth; ++n_layer)
   5550 			{
   5551 				/* ..and mip-maps, too. */
   5552 				const unsigned int n_mipmaps_for_layer = (texture_target == GL_TEXTURE_3D) ?
   5553 															 (m_iteration_parent_texture_n_levels - n_layer) :
   5554 															 (m_iteration_parent_texture_n_levels);
   5555 
   5556 				for (unsigned int n_mipmap = 0; n_mipmap < n_mipmaps_for_layer; ++n_mipmap)
   5557 				{
   5558 					/* Use appropriate glFramebufferTexture*() API, depending on the texture target of the
   5559 					 * parent texture.
   5560 					 */
   5561 					switch (texture_target)
   5562 					{
   5563 					case GL_TEXTURE_1D:
   5564 					{
   5565 						gl.framebufferTexture1D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_1D, m_to_id,
   5566 												n_mipmap);
   5567 
   5568 						GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D() call failed.");
   5569 						break;
   5570 					}
   5571 
   5572 					case GL_TEXTURE_2D:
   5573 					case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   5574 					case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   5575 					case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   5576 					case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   5577 					case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   5578 					case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   5579 					case GL_TEXTURE_RECTANGLE:
   5580 					{
   5581 						gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, m_to_id,
   5582 												n_mipmap);
   5583 
   5584 						GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
   5585 						break;
   5586 					}
   5587 
   5588 					case GL_TEXTURE_3D:
   5589 					{
   5590 						gl.framebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, m_to_id,
   5591 												n_mipmap, n_layer);
   5592 
   5593 						GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture3D() call failed.");
   5594 						break;
   5595 					}
   5596 
   5597 					default:
   5598 					{
   5599 						TCU_FAIL("Unrecognized texture target");
   5600 					}
   5601 					} /* switch (m_iteration_parent_texture_target) */
   5602 
   5603 					/* Each layer/mipmap needs to be assigned an unique vec4. */
   5604 					tcu::Vec4 reference_color = getRandomReferenceColor();
   5605 
   5606 					setReferenceColor(n_layer, n_texture_target, /* n_face */
   5607 									  n_mipmap, 0,				 /* n_sample */
   5608 									  reference_color);
   5609 
   5610 					/* We should be OK to clear the mip-map at this point */
   5611 					gl.clearColor(reference_color.x(), reference_color.y(), reference_color.z(), reference_color.w());
   5612 					GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");
   5613 
   5614 					gl.clear(GL_COLOR_BUFFER_BIT);
   5615 					GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
   5616 				} /* for (all mip-maps) */
   5617 			}	 /* for (all layers) */
   5618 		}		  /* for (all texture targets) */
   5619 	}			  /* if (!is_arrayed_texture_target && !is_multisampled_texture_target) */
   5620 	else
   5621 	{
   5622 		/* We need to handle an either multisampled or arrayed texture target or
   5623 		 * a combination of the two.
   5624 		 */
   5625 		DE_ASSERT(m_iteration_parent_texture_target == GL_TEXTURE_1D_ARRAY ||
   5626 				  m_iteration_parent_texture_target == GL_TEXTURE_2D_ARRAY ||
   5627 				  m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
   5628 				  m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
   5629 				  m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   5630 
   5631 		DE_ASSERT(m_iteration_parent_texture_depth >= 1);
   5632 		DE_ASSERT(m_iteration_parent_texture_n_levels >= 1);
   5633 
   5634 		const unsigned int n_faces =
   5635 			(m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY) ? 6 /* faces */ : 1;
   5636 
   5637 		resetReferenceColorStorage(m_iteration_parent_texture_depth,			 /* n_layers */
   5638 								   n_faces, m_iteration_parent_texture_n_levels, /* n_mipmaps */
   5639 								   m_max_color_texture_samples_gl_value);		 /* n_samples */
   5640 
   5641 		/* Set up storage for reference colors the fragment shader should use
   5642 		 * when rendering to multisampled texture target */
   5643 		float* reference_colors = new float[4 /* rgba */ * m_max_color_texture_samples_gl_value];
   5644 
   5645 		/* Activate the filler program */
   5646 		gl.useProgram(m_per_sample_filler_po_id);
   5647 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   5648 
   5649 		/* Iterate through all layers of the texture. */
   5650 		for (unsigned int n_layer = 0; n_layer < m_iteration_parent_texture_depth; ++n_layer)
   5651 		{
   5652 			/* ..faces.. */
   5653 			for (unsigned int n_face = 0; n_face < n_faces; ++n_face)
   5654 			{
   5655 				/* ..and mip-maps, too. */
   5656 				for (unsigned int n_mipmap = 0; n_mipmap < m_iteration_parent_texture_n_levels; ++n_mipmap)
   5657 				{
   5658 					/* For all texture targets considered excl. GL_TEXTURE_2D_MULTISAMPLE, we need
   5659 					 * to use glFramebufferTextur() to bind all layers to the color atatchment. For
   5660 					 * 2DMS textures, we can use plain glFramebufferTexture2D().
   5661 					 */
   5662 					if (m_iteration_parent_texture_target != GL_TEXTURE_2D_MULTISAMPLE)
   5663 					{
   5664 						gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, n_mipmap);
   5665 
   5666 						GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
   5667 					}
   5668 					else
   5669 					{
   5670 						/* Sanity check */
   5671 						DE_ASSERT(m_iteration_parent_texture_depth == 1);
   5672 
   5673 						gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
   5674 												m_iteration_parent_texture_target, m_to_id, n_mipmap);
   5675 
   5676 						GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
   5677 					}
   5678 
   5679 					/* Generate reference colors for all samples */
   5680 					const unsigned int n_samples =
   5681 						(is_multisampled_texture_target) ? m_max_color_texture_samples_gl_value : 1;
   5682 
   5683 					for (unsigned int n_sample = 0; n_sample < n_samples; ++n_sample)
   5684 					{
   5685 						tcu::Vec4 reference_color = getRandomReferenceColor();
   5686 
   5687 						reference_colors[4 /* rgba */ * n_sample + 0] = reference_color.x();
   5688 						reference_colors[4 /* rgba */ * n_sample + 1] = reference_color.y();
   5689 						reference_colors[4 /* rgba */ * n_sample + 2] = reference_color.z();
   5690 						reference_colors[4 /* rgba */ * n_sample + 3] = reference_color.w();
   5691 
   5692 						setReferenceColor(n_layer, n_face, n_mipmap, n_sample, reference_color);
   5693 					} /* for (all samples) */
   5694 
   5695 					/* Upload the reference sample colors */
   5696 					gl.uniform4fv(m_per_sample_filler_po_reference_colors_location, n_samples, reference_colors);
   5697 					GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed.");
   5698 
   5699 					/* Update the layer ID the program should render to */
   5700 					const unsigned int layer_id = n_face * 6 /* faces */ + n_layer;
   5701 
   5702 					gl.uniform1i(m_per_sample_filler_po_layer_id_location, layer_id);
   5703 					GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   5704 
   5705 					/* Draw the full-screen quad. Geometry shader will draw the quad for us,
   5706 					 * so all we need to do is to feed the rendering pipeline with a single
   5707 					 * point.
   5708 					 */
   5709 					gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   5710 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   5711 				} /* for (all mip-maps) */
   5712 			}	 /* for (all faces) */
   5713 		}		  /* for (all layers) */
   5714 
   5715 		delete[] reference_colors;
   5716 	}
   5717 }
   5718 
   5719 /** Initializes the 'per sample filler' program object, used to fill a multi-sample texture
   5720  *  with colors varying on a per-sample basis.
   5721  */
   5722 void TextureViewTestViewSampling::initPerSampleFillerProgramObject()
   5723 {
   5724 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5725 
   5726 	/* Sanity checks: GL_MAX_COLOR_TEXTURE_SAMPLES is not 0 */
   5727 	DE_ASSERT(m_max_color_texture_samples_gl_value != 0);
   5728 
   5729 	/* Generate program and shader objects */
   5730 	m_per_sample_filler_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
   5731 	m_per_sample_filler_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
   5732 	m_per_sample_filler_vs_id = gl.createShader(GL_VERTEX_SHADER);
   5733 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
   5734 
   5735 	m_per_sample_filler_po_id = gl.createProgram();
   5736 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
   5737 
   5738 	/* Configure fragment shader's body */
   5739 	static const char* fs_body = "#version 400\n"
   5740 								 "\n"
   5741 								 "uniform vec4 reference_colors[N_MAX_SAMPLES];\n"
   5742 								 "\n"
   5743 								 "out vec4 result;\n"
   5744 								 "\n"
   5745 								 "void main()\n"
   5746 								 "{\n"
   5747 								 "    result = reference_colors[gl_SampleID];\n"
   5748 								 "}\n";
   5749 	std::string		  fs_body_string		 = fs_body;
   5750 	const char*		  fs_body_string_raw_ptr = DE_NULL;
   5751 	std::stringstream n_max_samples_sstream;
   5752 	const char*		  n_max_samples_token = "N_MAX_SAMPLES";
   5753 	std::size_t		  token_location	  = std::string::npos;
   5754 
   5755 	n_max_samples_sstream << m_max_color_texture_samples_gl_value;
   5756 
   5757 	while ((token_location = fs_body_string.find(n_max_samples_token)) != std::string::npos)
   5758 	{
   5759 		fs_body_string.replace(token_location, strlen(n_max_samples_token), n_max_samples_sstream.str());
   5760 	}
   5761 
   5762 	fs_body_string_raw_ptr = fs_body_string.c_str();
   5763 
   5764 	gl.shaderSource(m_per_sample_filler_fs_id, 1 /* count */, &fs_body_string_raw_ptr, DE_NULL /* length */);
   5765 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   5766 
   5767 	/* Configure geometry shader's body */
   5768 	static const char* gs_body = "#version 400\n"
   5769 								 "\n"
   5770 								 "layout(points)                           in;\n"
   5771 								 "layout(triangle_strip, max_vertices = 4) out;\n"
   5772 								 "\n"
   5773 								 "uniform int layer_id;\n"
   5774 								 "\n"
   5775 								 "void main()\n"
   5776 								 "{\n"
   5777 								 "    gl_Layer    = layer_id;\n"
   5778 								 "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   5779 								 "    EmitVertex();\n"
   5780 								 "\n"
   5781 								 "    gl_Layer    = layer_id;\n"
   5782 								 "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   5783 								 "    EmitVertex();\n"
   5784 								 "\n"
   5785 								 "    gl_Layer    = layer_id;\n"
   5786 								 "    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   5787 								 "    EmitVertex();\n"
   5788 								 "\n"
   5789 								 "    gl_Layer    = layer_id;\n"
   5790 								 "    gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
   5791 								 "    EmitVertex();\n"
   5792 								 "\n"
   5793 								 "    EndPrimitive();\n"
   5794 								 "\n"
   5795 								 "}\n";
   5796 
   5797 	gl.shaderSource(m_per_sample_filler_gs_id, 1 /* count */, &gs_body, DE_NULL /* length */);
   5798 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   5799 
   5800 	/* Configure vertex shader */
   5801 	static const char* vs_body = "#version 400\n"
   5802 								 "\n"
   5803 								 "void main()\n"
   5804 								 "{\n"
   5805 								 "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   5806 								 "}\n";
   5807 
   5808 	gl.shaderSource(m_per_sample_filler_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
   5809 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   5810 
   5811 	/* Attach the shaders to the program object */
   5812 	gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_fs_id);
   5813 	gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_gs_id);
   5814 	gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_vs_id);
   5815 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
   5816 
   5817 	/* Compile the shaders */
   5818 	const glw::GLuint  so_ids[] = { m_per_sample_filler_fs_id, m_per_sample_filler_gs_id, m_per_sample_filler_vs_id };
   5819 	const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
   5820 
   5821 	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
   5822 	{
   5823 		glw::GLint  compile_status = GL_FALSE;
   5824 		glw::GLuint so_id		   = so_ids[n_so_id];
   5825 
   5826 		gl.compileShader(so_id);
   5827 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   5828 
   5829 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
   5830 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiV() call failed.");
   5831 
   5832 		if (compile_status != GL_TRUE)
   5833 		{
   5834 			TCU_FAIL("Shader compilation failed.");
   5835 		}
   5836 	} /* for (all shader objects) */
   5837 
   5838 	/* Link the program object */
   5839 	glw::GLint link_status = GL_FALSE;
   5840 
   5841 	gl.linkProgram(m_per_sample_filler_po_id);
   5842 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   5843 
   5844 	gl.getProgramiv(m_per_sample_filler_po_id, GL_LINK_STATUS, &link_status);
   5845 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   5846 
   5847 	if (link_status != GL_TRUE)
   5848 	{
   5849 		TCU_FAIL("Program linking failed.");
   5850 	}
   5851 
   5852 	/* Retrieve uniform locations */
   5853 	m_per_sample_filler_po_layer_id_location = gl.getUniformLocation(m_per_sample_filler_po_id, "layer_id");
   5854 	m_per_sample_filler_po_reference_colors_location =
   5855 		gl.getUniformLocation(m_per_sample_filler_po_id, "reference_colors[0]");
   5856 
   5857 	if (m_per_sample_filler_po_layer_id_location == -1)
   5858 	{
   5859 		TCU_FAIL("layer_id uniform is considered inactive which is invalid");
   5860 	}
   5861 
   5862 	if (m_per_sample_filler_po_reference_colors_location == -1)
   5863 	{
   5864 		TCU_FAIL("reference_colors uniform is considered inactive which is invalid");
   5865 	}
   5866 }
   5867 
   5868 /** Initializes GL objects needed to run the test (excluding iteration-specific objects) */
   5869 void TextureViewTestViewSampling::initTest()
   5870 {
   5871 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5872 
   5873 	/* Generate and configure BO storage to hold result XFB data of a single
   5874 	 * draw call.
   5875 	 *
   5876 	 * Each draw call outputs 6 vertices. For each vertex, 4 ints will be XFBed out. */
   5877 	gl.genBuffers(1, &m_bo_id);
   5878 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
   5879 
   5880 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
   5881 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   5882 
   5883 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 6 /* draw calls */ * (4 * sizeof(int)), /* as per comment */
   5884 				  DE_NULL, GL_STATIC_DRAW);
   5885 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
   5886 
   5887 	/* Generate a FBO and bind it to both binding targets */
   5888 	gl.genFramebuffers(1, &m_fbo_id);
   5889 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
   5890 
   5891 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   5892 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
   5893 
   5894 	/* Generate and bind a VAO */
   5895 	gl.genVertexArrays(1, &m_vao_id);
   5896 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   5897 
   5898 	gl.bindVertexArray(m_vao_id);
   5899 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   5900 
   5901 	/* Generate and configure a texture object we will use to verify view sampling works correctly
   5902 	 * from within a fragment shader.
   5903 	 */
   5904 	gl.genTextures(1, &m_result_to_id);
   5905 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
   5906 
   5907 	gl.bindTexture(GL_TEXTURE_2D, m_result_to_id);
   5908 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   5909 
   5910 	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, m_reference_texture_width, m_reference_texture_height);
   5911 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   5912 
   5913 	/* Determine implementation-specific GL_MAX_COLOR_TEXTURE_SAMPLES value */
   5914 	gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &m_max_color_texture_samples_gl_value);
   5915 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname.");
   5916 
   5917 	/* Modify pixel storage settings so that we don't rely on the default aligment setting. */
   5918 	gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
   5919 	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
   5920 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed.");
   5921 
   5922 	/* Modify GL_PATCH_VERTICES setting so that a single patch consists of only a single vertex
   5923 	 * (instead of the default 3) */
   5924 	gl.patchParameteri(GL_PATCH_VERTICES, 1);
   5925 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed.");
   5926 }
   5927 
   5928 /** Initializes and sets up a texture object storage, but does not fill it
   5929  *  with actual content. Implements separate code paths for handling parent
   5930  *  & view textures.
   5931  *
   5932  *  @param is_view_texture     true if a view texture should be initialized,
   5933  *                             false if te caller needs a parent texture. Note
   5934  *                             that a parent texture must be initialized prior
   5935  *                             to configuring a view texture.
   5936  *  @param texture_target      Texture target to use for the parent texture.
   5937  *  @param view_texture_target Texture target to use for the view texture.
   5938  **/
   5939 void TextureViewTestViewSampling::initTextureObject(bool is_view_texture, glw::GLenum texture_target,
   5940 													glw::GLenum view_texture_target)
   5941 {
   5942 	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
   5943 	unsigned int		  texture_depth = 0;
   5944 	glw::GLuint*		  to_id_ptr		= (is_view_texture) ? &m_view_to_id : &m_to_id;
   5945 
   5946 	/* Sanity check: make sure GL_TEXTURE_BUFFER texture target is not requested. This
   5947 	 *               would be against the test specification.
   5948 	 **/
   5949 	DE_ASSERT(texture_target != GL_TEXTURE_BUFFER);
   5950 	DE_ASSERT(view_texture_target != GL_TEXTURE_BUFFER);
   5951 
   5952 	/* If we're going to be creating a cube-map or cube-map array texture view in this iteration,
   5953 	 * make sure the parent or view texture's depth is valid */
   5954 	if (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
   5955 	{
   5956 		texture_depth = 13; /* 1 + 2 * (6 faces) */
   5957 	}
   5958 	else if (view_texture_target == GL_TEXTURE_CUBE_MAP)
   5959 	{
   5960 		texture_depth = 7; /* 1 + (6 faces) */
   5961 	}
   5962 	else
   5963 	{
   5964 		texture_depth = m_reference_texture_depth;
   5965 	}
   5966 
   5967 	if (texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
   5968 	{
   5969 		texture_depth = 6 /* faces */ * 3;
   5970 	}
   5971 
   5972 	/* Release the texture object, as we're using immutable texture objects and would
   5973 	 * prefer the resources not to leak.
   5974 	 */
   5975 	if (*to_id_ptr != 0)
   5976 	{
   5977 		gl.deleteTextures(1, to_id_ptr);
   5978 
   5979 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
   5980 	}
   5981 
   5982 	/* Generate a new texture object */
   5983 	gl.genTextures(1, to_id_ptr);
   5984 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
   5985 
   5986 	if (is_view_texture)
   5987 	{
   5988 		/* Determine values of arguments we'll pass to glTextureView() call */
   5989 		unsigned int minlayer  = 0;
   5990 		unsigned int minlevel  = 0;
   5991 		unsigned int numlayers = 0;
   5992 		unsigned int numlevels = 2;
   5993 
   5994 		const bool is_texture_arrayed_texture_target =
   5995 			(texture_target == GL_TEXTURE_1D_ARRAY || texture_target == GL_TEXTURE_2D_ARRAY ||
   5996 			 texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   5997 		const bool is_texture_cube_map_texture_target = (texture_target == GL_TEXTURE_CUBE_MAP);
   5998 		const bool is_texture_multisample_texture_target =
   5999 			(texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
   6000 		const bool is_texture_rectangle_texture_target = (texture_target == GL_TEXTURE_RECTANGLE);
   6001 		const bool is_view_arrayed_texture_target =
   6002 			(view_texture_target == GL_TEXTURE_1D_ARRAY || view_texture_target == GL_TEXTURE_2D_ARRAY ||
   6003 			 view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
   6004 			 view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   6005 		const bool is_view_cube_map_texture_target		 = (view_texture_target == GL_TEXTURE_CUBE_MAP);
   6006 		const bool is_view_cube_map_array_texture_target = (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
   6007 
   6008 		if (is_texture_multisample_texture_target || is_texture_rectangle_texture_target)
   6009 		{
   6010 			minlevel  = 0;
   6011 			numlevels = 1;
   6012 		}
   6013 		else
   6014 		{
   6015 			minlevel = 1;
   6016 		}
   6017 
   6018 		if ((true == is_texture_arrayed_texture_target) ||
   6019 			((false == is_texture_cube_map_texture_target) && (true == is_view_cube_map_texture_target)) ||
   6020 			((false == is_texture_cube_map_texture_target) && (true == is_view_cube_map_array_texture_target)))
   6021 		{
   6022 			minlayer = 1;
   6023 		}
   6024 		else
   6025 		{
   6026 			minlayer = 0;
   6027 		}
   6028 
   6029 		if (!is_texture_cube_map_texture_target && is_view_cube_map_array_texture_target)
   6030 		{
   6031 			numlayers = 12;
   6032 		}
   6033 		else if (is_view_cube_map_texture_target || is_view_cube_map_array_texture_target)
   6034 		{
   6035 			numlayers = 6;
   6036 		}
   6037 		else if (is_view_arrayed_texture_target)
   6038 		{
   6039 			if (is_texture_arrayed_texture_target || is_texture_cube_map_texture_target)
   6040 			{
   6041 				numlayers = 2;
   6042 			}
   6043 			else
   6044 			{
   6045 				numlayers = 1;
   6046 			}
   6047 		}
   6048 		else
   6049 		{
   6050 			numlayers = 1;
   6051 		}
   6052 
   6053 		/* Set up view texture */
   6054 		gl.textureView(*to_id_ptr, view_texture_target, m_to_id, GL_RGBA8, minlevel, numlevels, minlayer, numlayers);
   6055 
   6056 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed.");
   6057 
   6058 		/* Store the argument values */
   6059 		m_iteration_view_texture_minlayer  = minlayer;
   6060 		m_iteration_view_texture_minlevel  = minlevel;
   6061 		m_iteration_view_texture_numlayers = numlayers;
   6062 		m_iteration_view_texture_numlevels = numlevels;
   6063 		m_iteration_view_texture_target	= view_texture_target;
   6064 
   6065 		m_testCtx.getLog() << tcu::TestLog::Message << "Created a view for texture target "
   6066 						   << "[" << TextureViewUtilities::getTextureTargetString(view_texture_target) << "] "
   6067 						   << "from a parent texture target "
   6068 						   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6069 						   << "using arguments: "
   6070 						   << "minlayer:[" << minlayer << "] "
   6071 						   << "minlevel:[" << minlevel << "] "
   6072 						   << "numlayers:[" << numlayers << "] "
   6073 						   << "numlevels:[" << numlevels << "]." << tcu::TestLog::EndMessage;
   6074 
   6075 		gl.bindTexture(view_texture_target, *to_id_ptr);
   6076 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   6077 	} /* if (is_view_texture) */
   6078 	else
   6079 	{
   6080 		/* Reset iteration-specific view settings */
   6081 		m_iteration_parent_texture_depth	 = 1;
   6082 		m_iteration_parent_texture_height	= 1;
   6083 		m_iteration_parent_texture_n_levels  = 1;
   6084 		m_iteration_parent_texture_n_samples = 1;
   6085 		m_iteration_parent_texture_width	 = 1;
   6086 
   6087 		/* Initialize storage for the newly created texture object */
   6088 		gl.bindTexture(texture_target, *to_id_ptr);
   6089 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   6090 
   6091 		/* Use max conformant sample count for multisample texture targets */
   6092 		if (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
   6093 		{
   6094 			m_max_color_texture_samples_gl_value = getMaxConformantSampleCount(texture_target, GL_RGBA8);
   6095 		}
   6096 		else
   6097 		{
   6098 			/* Use GL_MAX_COLOR_TEXTURE_SAMPLES value for other targets */
   6099 			gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &m_max_color_texture_samples_gl_value);
   6100 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname.");
   6101 		}
   6102 
   6103 		switch (texture_target)
   6104 		{
   6105 		case GL_TEXTURE_1D:
   6106 		{
   6107 			gl.texStorage1D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width);
   6108 
   6109 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed.");
   6110 
   6111 			m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
   6112 			m_iteration_parent_texture_width	= m_reference_texture_width;
   6113 
   6114 			m_testCtx.getLog() << tcu::TestLog::Message
   6115 							   << "Created an immutable parent texture object for texture target "
   6116 							   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6117 							   << "of "
   6118 							   << "levels:[" << m_reference_texture_n_mipmaps << "] "
   6119 							   << "width:[" << m_reference_texture_width << "]." << tcu::TestLog::EndMessage;
   6120 			break;
   6121 		}
   6122 
   6123 		case GL_TEXTURE_1D_ARRAY:
   6124 		{
   6125 			gl.texStorage2D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width,
   6126 							texture_depth);
   6127 
   6128 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   6129 
   6130 			m_iteration_parent_texture_depth	= texture_depth;
   6131 			m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
   6132 			m_iteration_parent_texture_width	= m_reference_texture_width;
   6133 
   6134 			m_testCtx.getLog() << tcu::TestLog::Message
   6135 							   << "Created an immutable parent texture object for texture target "
   6136 							   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6137 							   << "of "
   6138 							   << "depth:[" << texture_depth << "] "
   6139 							   << "levels:[" << m_reference_texture_n_mipmaps << "] "
   6140 							   << "width:[" << m_reference_texture_width << "]." << tcu::TestLog::EndMessage;
   6141 
   6142 			break;
   6143 		}
   6144 
   6145 		case GL_TEXTURE_CUBE_MAP:
   6146 		case GL_TEXTURE_2D:
   6147 		{
   6148 			gl.texStorage2D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width,
   6149 							m_reference_texture_height);
   6150 
   6151 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   6152 
   6153 			m_iteration_parent_texture_height   = m_reference_texture_height;
   6154 			m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
   6155 			m_iteration_parent_texture_width	= m_reference_texture_width;
   6156 
   6157 			m_testCtx.getLog() << tcu::TestLog::Message
   6158 							   << "Created an immutable parent texture object for texture target "
   6159 							   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6160 							   << "of "
   6161 							   << "levels:[" << m_reference_texture_n_mipmaps << "] "
   6162 							   << "width:[" << m_reference_texture_width << "] "
   6163 							   << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage;
   6164 
   6165 			break;
   6166 		}
   6167 
   6168 		case GL_TEXTURE_RECTANGLE:
   6169 		{
   6170 			gl.texStorage2D(texture_target, 1, /* rectangle textures do not use mip-maps */
   6171 							GL_RGBA8, m_reference_texture_width, m_reference_texture_height);
   6172 
   6173 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   6174 
   6175 			m_iteration_parent_texture_height = m_reference_texture_height;
   6176 			m_iteration_parent_texture_width  = m_reference_texture_width;
   6177 
   6178 			m_testCtx.getLog() << tcu::TestLog::Message
   6179 							   << "Created an immutable parent texture object for texture target "
   6180 							   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6181 							   << "of "
   6182 							   << "levels:1 "
   6183 							   << "width:[" << m_reference_texture_width << "] "
   6184 							   << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage;
   6185 
   6186 			break;
   6187 		}
   6188 
   6189 		case GL_TEXTURE_2D_ARRAY:
   6190 		{
   6191 			gl.texStorage3D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width,
   6192 							m_reference_texture_height, texture_depth);
   6193 
   6194 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
   6195 
   6196 			m_iteration_parent_texture_depth	= texture_depth;
   6197 			m_iteration_parent_texture_height   = m_reference_texture_height;
   6198 			m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
   6199 			m_iteration_parent_texture_width	= m_reference_texture_width;
   6200 
   6201 			m_testCtx.getLog() << tcu::TestLog::Message
   6202 							   << "Created an immutable parent texture object for texture target "
   6203 							   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6204 							   << "of "
   6205 							   << "depth:[" << texture_depth << "] "
   6206 							   << "levels:[" << m_reference_texture_n_mipmaps << "] "
   6207 							   << "width:[" << m_reference_texture_width << "] "
   6208 							   << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage;
   6209 
   6210 			break;
   6211 		}
   6212 
   6213 		case GL_TEXTURE_2D_MULTISAMPLE:
   6214 		{
   6215 			gl.texStorage2DMultisample(texture_target, m_max_color_texture_samples_gl_value, GL_RGBA8,
   6216 									   m_reference_texture_width, m_reference_texture_height,
   6217 									   GL_TRUE); /* fixedsamplelocations */
   6218 
   6219 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed.");
   6220 
   6221 			m_iteration_parent_texture_height	= m_reference_texture_height;
   6222 			m_iteration_parent_texture_n_samples = m_max_color_texture_samples_gl_value;
   6223 			m_iteration_parent_texture_width	 = m_reference_texture_width;
   6224 
   6225 			m_testCtx.getLog() << tcu::TestLog::Message
   6226 							   << "Created an immutable parent texture object for texture target "
   6227 							   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6228 							   << "of "
   6229 							   << "samples:[" << m_max_color_texture_samples_gl_value << "] "
   6230 							   << "width:[" << m_reference_texture_width << "] "
   6231 							   << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage;
   6232 
   6233 			break;
   6234 		}
   6235 
   6236 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   6237 		{
   6238 			gl.texStorage3DMultisample(texture_target, m_max_color_texture_samples_gl_value, GL_RGBA8,
   6239 									   m_reference_texture_width, m_reference_texture_height, texture_depth,
   6240 									   GL_TRUE); /* fixed sample locations */
   6241 
   6242 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3DMultisample() call failed.");
   6243 
   6244 			m_iteration_parent_texture_depth	 = texture_depth;
   6245 			m_iteration_parent_texture_height	= m_reference_texture_height;
   6246 			m_iteration_parent_texture_n_samples = m_max_color_texture_samples_gl_value;
   6247 			m_iteration_parent_texture_width	 = m_reference_texture_width;
   6248 
   6249 			m_testCtx.getLog() << tcu::TestLog::Message
   6250 							   << "Created an immutable parent texture object for texture target "
   6251 							   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6252 							   << "of "
   6253 							   << "samples:[" << m_max_color_texture_samples_gl_value << "] "
   6254 							   << "width:[" << m_reference_texture_width << "] "
   6255 							   << "height:[" << m_reference_texture_height << "] "
   6256 							   << "depth:[" << texture_depth << "]." << tcu::TestLog::EndMessage;
   6257 
   6258 			break;
   6259 		}
   6260 
   6261 		case GL_TEXTURE_3D:
   6262 		case GL_TEXTURE_CUBE_MAP_ARRAY:
   6263 		{
   6264 			gl.texStorage3D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width,
   6265 							m_reference_texture_height, texture_depth);
   6266 
   6267 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
   6268 
   6269 			m_iteration_parent_texture_depth	= texture_depth;
   6270 			m_iteration_parent_texture_height   = m_reference_texture_height;
   6271 			m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
   6272 			m_iteration_parent_texture_width	= m_reference_texture_width;
   6273 
   6274 			m_testCtx.getLog() << tcu::TestLog::Message
   6275 							   << "Created an immutable parent texture object for texture target "
   6276 							   << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
   6277 							   << "of "
   6278 							   << "levels:[" << m_reference_texture_n_mipmaps << "] "
   6279 							   << "width:[" << m_reference_texture_width << "] "
   6280 							   << "height:[" << m_reference_texture_height << "] "
   6281 							   << "depth:[" << texture_depth << "]." << tcu::TestLog::EndMessage;
   6282 
   6283 			break;
   6284 		}
   6285 
   6286 		default:
   6287 		{
   6288 			TCU_FAIL("Unrecognized texture target.");
   6289 		}
   6290 		} /* switch (texture_target) */
   6291 
   6292 		m_iteration_parent_texture_target = texture_target;
   6293 	}
   6294 
   6295 	/* Configure texture filtering */
   6296 	if (texture_target != GL_TEXTURE_2D_MULTISAMPLE && texture_target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY &&
   6297 		texture_target != GL_TEXTURE_RECTANGLE)
   6298 	{
   6299 		gl.texParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   6300 		gl.texParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   6301 
   6302 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed.");
   6303 	}
   6304 }
   6305 
   6306 /** Executes test iteration.
   6307  *
   6308  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   6309  */
   6310 tcu::TestNode::IterateResult TextureViewTestViewSampling::iterate()
   6311 {
   6312 	bool has_failed = false;
   6313 
   6314 	/* Make sure GL_ARB_texture_view is reported as supported before carrying on
   6315 	 * with actual execution */
   6316 	const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
   6317 
   6318 	if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
   6319 	{
   6320 		throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
   6321 	}
   6322 
   6323 	/* Initialize all objects required to run the test */
   6324 	initTest();
   6325 
   6326 	/* Initialize per-sample filler program */
   6327 	initPerSampleFillerProgramObject();
   6328 
   6329 	/* Iterate through all texture/view texture target combinations */
   6330 	TextureViewUtilities::_compatible_texture_target_pairs_const_iterator texture_target_iterator;
   6331 	TextureViewUtilities::_compatible_texture_target_pairs				  texture_target_pairs =
   6332 		TextureViewUtilities::getLegalTextureAndViewTargetCombinations();
   6333 
   6334 	for (texture_target_iterator = texture_target_pairs.begin(); texture_target_iterator != texture_target_pairs.end();
   6335 		 ++texture_target_iterator)
   6336 	{
   6337 		const glw::GLenum parent_texture_target = texture_target_iterator->first;
   6338 		const glw::GLenum view_texture_target   = texture_target_iterator->second;
   6339 
   6340 		/* Initialize parent texture */
   6341 		initTextureObject(false /* is_view_texture */, parent_texture_target, view_texture_target);
   6342 
   6343 		/* Initialize view */
   6344 		initTextureObject(true /* is_view_texture */, parent_texture_target, view_texture_target);
   6345 
   6346 		/* Initialize contents of the parent texture */
   6347 		initParentTextureContents();
   6348 
   6349 		/* Initialize iteration-specific test program object */
   6350 		initIterationSpecificProgramObject();
   6351 
   6352 		/* Run the actual test */
   6353 		bool status = executeTest();
   6354 
   6355 		if (!status)
   6356 		{
   6357 			has_failed = true;
   6358 
   6359 			m_testCtx.getLog() << tcu::TestLog::Message << "Test case failed." << tcu::TestLog::EndMessage;
   6360 		}
   6361 		else
   6362 		{
   6363 			m_testCtx.getLog() << tcu::TestLog::Message << "Test case succeeded." << tcu::TestLog::EndMessage;
   6364 		}
   6365 	}
   6366 
   6367 	if (!has_failed)
   6368 	{
   6369 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   6370 	}
   6371 	else
   6372 	{
   6373 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   6374 	}
   6375 
   6376 	return STOP;
   6377 }
   6378 
   6379 /** De-allocates existing reference color storage (if one already exists) and
   6380  *  allocates a new one using user-provided properties.
   6381  *
   6382  *  @param n_layers  Amount of layers to consider. Use a value of 1 for non-arrayed
   6383  *                   texture targets.
   6384  *  @param n_faces   Amount of faces to consider. Use a value of 1 for non-CM
   6385  *                   texture targets.
   6386  *  @param n_mipmaps Amount of mip-maps to consider. Use a value of 1 for non-mipmapped
   6387  *                   texture targets.
   6388  *  @param n_samples Amount of samples to consider. Use a value of 1 for single-sampled
   6389  *                   texture targets.
   6390  **/
   6391 void TextureViewTestViewSampling::resetReferenceColorStorage(unsigned int n_layers, unsigned int n_faces,
   6392 															 unsigned int n_mipmaps, unsigned int n_samples)
   6393 {
   6394 	/* Sanity checks */
   6395 	DE_ASSERT(n_layers >= 1);
   6396 	DE_ASSERT(n_faces >= 1);
   6397 	DE_ASSERT(n_mipmaps >= 1);
   6398 	DE_ASSERT(n_samples >= 1);
   6399 
   6400 	/* Allocate the descriptor if it's the first time the test will be
   6401 	 * attempting to access it */
   6402 	if (m_reference_color_storage == DE_NULL)
   6403 	{
   6404 		m_reference_color_storage = new _reference_color_storage(n_faces, n_layers, n_mipmaps, n_samples);
   6405 	}
   6406 	else
   6407 	{
   6408 		/* The descriptor's already there so we only need to update the properties */
   6409 		m_reference_color_storage->n_faces   = n_faces;
   6410 		m_reference_color_storage->n_layers  = n_layers;
   6411 		m_reference_color_storage->n_mipmaps = n_mipmaps;
   6412 		m_reference_color_storage->n_samples = n_samples;
   6413 	}
   6414 
   6415 	/* If there's any data descriptor found allocated at this point,
   6416 	 * release it */
   6417 	if (m_reference_color_storage->data != DE_NULL)
   6418 	{
   6419 		delete[] m_reference_color_storage->data;
   6420 
   6421 		m_reference_color_storage->data = DE_NULL;
   6422 	}
   6423 
   6424 	m_reference_color_storage->data = new tcu::Vec4[n_layers * n_faces * n_mipmaps * n_samples];
   6425 }
   6426 
   6427 /** Assigns user-specified reference color to a specific sample of a layer/face's mip-map.
   6428  *
   6429  *  This function throws an assertion failure if the requested layer/face/mip-map/sample index
   6430  *  is invalid.
   6431  *
   6432  *  @param n_layer  Layer index to use for the association. Use a value of 0 for non-arrayed texture
   6433  *                  targets.
   6434  *  @param n_face   Face index to use for the association. Use a value of 0 for non-CM texture targets.
   6435  *  @param n_mipmap Mip-map index to use for the association. Use a value of 0 for non-mipmapped texture
   6436  *                  targets.
   6437  *  @param n_sample Sample index to use for the association. Use a value of 0 for single-sampled texture
   6438  *                  targets.
   6439  *  @param color    Color to associate with the specified sample.
   6440  **/
   6441 void TextureViewTestViewSampling::setReferenceColor(unsigned int n_layer, unsigned int n_face, unsigned int n_mipmap,
   6442 													unsigned int n_sample, tcu::Vec4 color)
   6443 {
   6444 	DE_ASSERT(m_reference_color_storage != DE_NULL);
   6445 	if (m_reference_color_storage != DE_NULL)
   6446 	{
   6447 		DE_ASSERT(n_face < m_reference_color_storage->n_faces);
   6448 		DE_ASSERT(n_layer < m_reference_color_storage->n_layers);
   6449 		DE_ASSERT(n_mipmap < m_reference_color_storage->n_mipmaps);
   6450 		DE_ASSERT(n_sample < m_reference_color_storage->n_samples);
   6451 
   6452 		/* Hierarchy is:
   6453 		 *
   6454 		 * layers -> faces -> mipmaps -> samples */
   6455 		const unsigned int index =
   6456 			n_layer * (m_reference_color_storage->n_faces * m_reference_color_storage->n_mipmaps *
   6457 					   m_reference_color_storage->n_samples) +
   6458 			n_face * (m_reference_color_storage->n_mipmaps * m_reference_color_storage->n_samples) +
   6459 			n_mipmap * (m_reference_color_storage->n_samples) + n_sample;
   6460 
   6461 		m_reference_color_storage->data[index] = color;
   6462 	}
   6463 }
   6464 
   6465 /** Constructor.
   6466  *
   6467  *  @param context Rendering context.
   6468  **/
   6469 TextureViewTestViewClasses::TextureViewTestViewClasses(deqp::Context& context)
   6470 	: TestCase(context, "view_classes", "Verifies view sampling works correctly. Tests all valid"
   6471 										" texture/view internalformat combinations.")
   6472 	, m_bo_id(0)
   6473 	, m_po_id(0)
   6474 	, m_to_id(0)
   6475 	, m_to_temp_id(0)
   6476 	, m_vao_id(0)
   6477 	, m_view_to_id(0)
   6478 	, m_vs_id(0)
   6479 	, m_decompressed_mipmap_data(DE_NULL)
   6480 	, m_mipmap_data(DE_NULL)
   6481 	, m_bo_size(0)
   6482 	, m_has_test_failed(false)
   6483 	, m_texture_height(4)
   6484 	, m_texture_unit_for_parent_texture(GL_TEXTURE0)
   6485 	, m_texture_unit_for_view_texture(GL_TEXTURE1)
   6486 	, m_texture_width(4)
   6487 	, m_view_data_offset(0)
   6488 {
   6489 	/* Left blank on purpose */
   6490 }
   6491 
   6492 /** Deinitializes all buffers and GL objects that may have been created
   6493  *  during test execution. Also restores GL state that may have been modified.
   6494  **/
   6495 void TextureViewTestViewClasses::deinit()
   6496 {
   6497 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6498 
   6499 	if (m_bo_id != 0)
   6500 	{
   6501 		gl.deleteBuffers(1, &m_bo_id);
   6502 
   6503 		m_bo_id = 0;
   6504 	}
   6505 
   6506 	if (m_decompressed_mipmap_data != DE_NULL)
   6507 	{
   6508 		delete[] m_decompressed_mipmap_data;
   6509 
   6510 		m_decompressed_mipmap_data = DE_NULL;
   6511 	}
   6512 
   6513 	if (m_mipmap_data != DE_NULL)
   6514 	{
   6515 		delete[] m_mipmap_data;
   6516 
   6517 		m_mipmap_data = DE_NULL;
   6518 	}
   6519 
   6520 	if (m_po_id != 0)
   6521 	{
   6522 		gl.deleteProgram(m_po_id);
   6523 
   6524 		m_po_id = 0;
   6525 	}
   6526 
   6527 	if (m_to_id != 0)
   6528 	{
   6529 		gl.deleteTextures(1, &m_to_id);
   6530 
   6531 		m_to_id = 0;
   6532 	}
   6533 
   6534 	if (m_to_temp_id != 0)
   6535 	{
   6536 		gl.deleteTextures(1, &m_to_temp_id);
   6537 
   6538 		m_to_temp_id = 0;
   6539 	}
   6540 
   6541 	if (m_vao_id != 0)
   6542 	{
   6543 		gl.deleteVertexArrays(1, &m_vao_id);
   6544 
   6545 		m_vao_id = 0;
   6546 	}
   6547 
   6548 	if (m_view_to_id != 0)
   6549 	{
   6550 		gl.deleteTextures(1, &m_view_to_id);
   6551 
   6552 		m_view_to_id = 0;
   6553 	}
   6554 
   6555 	if (m_vs_id != 0)
   6556 	{
   6557 		gl.deleteShader(m_vs_id);
   6558 
   6559 		m_vs_id = 0;
   6560 	}
   6561 
   6562 	/* Bring back the default pixel storage settings that the test may have modified. */
   6563 	gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
   6564 	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4);
   6565 
   6566 	/* Restore rasterization */
   6567 	gl.enable(GL_RASTERIZER_DISCARD);
   6568 }
   6569 
   6570 /** Reads user-specified amount of components and stores it in user-provided location,
   6571  *  according to user-defined format (snorm, unorm, etc.) and component size.
   6572  *
   6573  *  This function assumes component sizes are aligned on by boundary (that is: size % 8
   6574  *  equals 0 for all components). An assertion failure will occur if this requirement is
   6575  *  not met.
   6576  *  This function throws TestError exception if any of the requested component sizes
   6577  *  or format is not supported.
   6578  *
   6579  *  @param data            Raw data buffer to read the data from.
   6580  *  @param n_components    Amount of components to read.
   6581  *  @param component_sizes 4 ints subsequently defining component size for R/G/B/A channels.
   6582  *                         Must not be NULL.
   6583  *  @param format          Format to be used for data retrieval. This defines data format of
   6584  *                         the underlying components (for instance: for UNORMs we need to
   6585  *                         divide the read ubyte/ushort/uint data by maximum value allowed for
   6586  *                         the type minus one)
   6587  *  @param result          Location to store the read components. Must not be NULL. Must be
   6588  *                         large enough to hold requested amount of components of user-specified
   6589  *                         component size.
   6590  *
   6591  **/
   6592 void TextureViewTestViewClasses::getComponentDataForByteAlignedInternalformat(const unsigned char* data,
   6593 																			  const unsigned int   n_components,
   6594 																			  const unsigned int*  component_sizes,
   6595 																			  const _format format, void* result)
   6596 {
   6597 	float*		  result_float = (float*)result;
   6598 	signed int*   result_sint  = (signed int*)result;
   6599 	unsigned int* result_uint  = (unsigned int*)result;
   6600 
   6601 	/* Sanity checks: we assume the components are aligned on byte boundary. */
   6602 	DE_ASSERT((component_sizes[0] % 8) == 0 && (component_sizes[1] % 8) == 0 && (component_sizes[2] % 8) == 0 &&
   6603 			  (component_sizes[3] % 8) == 0);
   6604 
   6605 	for (unsigned int n_component = 0; n_component < n_components;
   6606 		 data += (component_sizes[n_component] >> 3 /* 8 bits/byte */), ++n_component)
   6607 	{
   6608 		switch (format)
   6609 		{
   6610 		case FORMAT_FLOAT:
   6611 		{
   6612 			switch (component_sizes[n_component])
   6613 			{
   6614 			case 16:
   6615 				result_float[n_component] = deFloat16To32(*(const deFloat16*)data);
   6616 				break;
   6617 			case 32:
   6618 				result_float[n_component] = *(float*)data;
   6619 				break;
   6620 
   6621 			default:
   6622 				TCU_FAIL("Unsupported component size");
   6623 			}
   6624 
   6625 			break;
   6626 		}
   6627 
   6628 		case FORMAT_SIGNED_INTEGER:
   6629 		{
   6630 			switch (component_sizes[n_component])
   6631 			{
   6632 			case 8:
   6633 				result_sint[n_component] = *(signed char*)data;
   6634 				break;
   6635 			case 16:
   6636 				result_sint[n_component] = *(signed short*)data;
   6637 				break;
   6638 			case 32:
   6639 				result_sint[n_component] = *(signed int*)data;
   6640 				break;
   6641 
   6642 			default:
   6643 				TCU_FAIL("Unsupported component size");
   6644 			}
   6645 
   6646 			break;
   6647 		}
   6648 
   6649 		case FORMAT_SNORM:
   6650 		{
   6651 			switch (component_sizes[n_component])
   6652 			{
   6653 			case 8:
   6654 				result_float[n_component] = float(*(signed char*)data) / 127.0f;
   6655 				break;
   6656 			case 16:
   6657 				result_float[n_component] = float(*(signed short*)data) / 32767.0f;
   6658 				break;
   6659 
   6660 			default:
   6661 				TCU_FAIL("Unsupported component size");
   6662 			}
   6663 
   6664 			if (result_float[n_component] < -1.0f)
   6665 			{
   6666 				result_float[n_component] = -1.0f;
   6667 			}
   6668 
   6669 			break;
   6670 		}
   6671 
   6672 		case FORMAT_UNORM:
   6673 		{
   6674 			switch (component_sizes[n_component])
   6675 			{
   6676 			case 8:
   6677 				result_float[n_component] = float(*((unsigned char*)data)) / 255.0f;
   6678 				break;
   6679 			case 16:
   6680 				result_float[n_component] = float(*((unsigned short*)data)) / 65535.0f;
   6681 				break;
   6682 
   6683 			default:
   6684 				TCU_FAIL("Unsupported component size");
   6685 			}
   6686 
   6687 			break;
   6688 		}
   6689 
   6690 		case FORMAT_UNSIGNED_INTEGER:
   6691 		{
   6692 			switch (component_sizes[n_component])
   6693 			{
   6694 			case 8:
   6695 				result_uint[n_component] = *(unsigned char*)data;
   6696 				break;
   6697 			case 16:
   6698 				result_uint[n_component] = *(unsigned short*)data;
   6699 				break;
   6700 			case 32:
   6701 				result_uint[n_component] = *(unsigned int*)data;
   6702 				break;
   6703 
   6704 			default:
   6705 				TCU_FAIL("Unsupported component size");
   6706 			}
   6707 
   6708 			break;
   6709 		}
   6710 
   6711 		default:
   6712 		{
   6713 			TCU_FAIL("Unrecognized mip-map format");
   6714 		}
   6715 		} /* switch (view_format) */
   6716 	}	 /* for (all components) */
   6717 }
   6718 
   6719 /** Initializes buffer object storage of sufficient size to hold data that will be
   6720  *  XFBed out by the test's vertex shader, given user-specified parent texture &
   6721  *  view's internalformats.
   6722  *
   6723  *  Throws TestError exceptions if GL calls fail.
   6724  *
   6725  *  @param texture_internalformat Internalformat used by the parent texture object,
   6726  *                                from which the view will be created.
   6727  *  @param view_internalformat    Internalformat that will be used by the texture view.
   6728  **/
   6729 void TextureViewTestViewClasses::initBufferObject(glw::GLenum texture_internalformat, glw::GLenum view_internalformat)
   6730 {
   6731 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6732 
   6733 	/* Calculate how much size we will need to read the XFBed data. Each sampled data
   6734 	 * will either end up stored in a vecX, ivecX or uvecX (where X stands for amount
   6735 	 * of components supported by considered internalformat), so we can assume it will
   6736 	 * take a sizeof(float) = sizeof(int) = sizeof(unsigned int)
   6737 	 */
   6738 	const unsigned int parent_texture_n_components =
   6739 		TextureViewUtilities::getAmountOfComponentsForInternalformat(texture_internalformat);
   6740 	const unsigned int view_texture_n_components =
   6741 		TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat);
   6742 
   6743 	/* Configure buffer object storage.
   6744 	 *
   6745 	 * NOTE: We do not care about the data type of the stored data, since sizes of the
   6746 	 *       types we're interested in (floats, ints and uints) match.
   6747 	 */
   6748 	DE_ASSERT(sizeof(float) == sizeof(unsigned int) && sizeof(float) == sizeof(int));
   6749 
   6750 	m_bo_size =
   6751 		static_cast<unsigned int>(parent_texture_n_components * sizeof(float) * m_texture_height * m_texture_width +
   6752 								  view_texture_n_components * sizeof(float) * m_texture_height * m_texture_width);
   6753 
   6754 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_size, DE_NULL, /* data */
   6755 				  GL_STATIC_DRAW);
   6756 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
   6757 
   6758 	/* For XFB, we'll be outputting data sampled from both the texture and the view.
   6759 	 * Sampled texture data will go to the first half of the buffer, and the corresponding
   6760 	 * view data will go to the one half.
   6761 	 *
   6762 	 * Store the offset, from which the view's data will start so that we can correctly
   6763 	 * configure buffer object bindings in initProgramObject()
   6764 	 **/
   6765 	m_view_data_offset =
   6766 		static_cast<unsigned int>(parent_texture_n_components * sizeof(float) * m_texture_height * m_texture_width);
   6767 }
   6768 
   6769 /** Initializes a program object that should be used for the test, given
   6770  *  user-specified texture and view internalformats.
   6771  *
   6772  *  @param texture_internalformat Internalformat used by the parent texture object,
   6773  *                                from which the view will be created.
   6774  *  @param view_internalformat    Internalformat that will be used by the texture view.
   6775  **/
   6776 void TextureViewTestViewClasses::initProgramObject(glw::GLenum texture_internalformat, glw::GLenum view_internalformat)
   6777 {
   6778 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6779 
   6780 	/* Determine which samplers we should be using for sampling both textures */
   6781 	const unsigned int texture_n_components =
   6782 		TextureViewUtilities::getAmountOfComponentsForInternalformat(texture_internalformat);
   6783 	const _sampler_type texture_sampler_type =
   6784 		TextureViewUtilities::getSamplerTypeForInternalformat(texture_internalformat);
   6785 	const char* texture_sampler_data_type_glsl =
   6786 		TextureViewUtilities::getGLSLDataTypeForSamplerType(texture_sampler_type, texture_n_components);
   6787 	const char* texture_sampler_glsl = TextureViewUtilities::getGLSLTypeForSamplerType(texture_sampler_type);
   6788 	const char* texture_swizzle_glsl =
   6789 		(texture_n_components == 4) ? "xyzw" :
   6790 									  (texture_n_components == 3) ? "xyz" : (texture_n_components == 2) ? "xy" : "x";
   6791 	const unsigned int view_n_components =
   6792 		TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat);
   6793 	const _sampler_type view_sampler_type = TextureViewUtilities::getSamplerTypeForInternalformat(view_internalformat);
   6794 	const char*			view_sampler_data_type_glsl =
   6795 		TextureViewUtilities::getGLSLDataTypeForSamplerType(view_sampler_type, view_n_components);
   6796 	const char* view_sampler_glsl = TextureViewUtilities::getGLSLTypeForSamplerType(view_sampler_type);
   6797 	const char* view_swizzle_glsl =
   6798 		(view_n_components == 4) ? "xyzw" : (view_n_components == 3) ? "xyz" : (view_n_components == 2) ? "xy" : "x";
   6799 
   6800 	/* Form vertex shader body */
   6801 	const char* token_texture_data_type = "TEXTURE_DATA_TYPE";
   6802 	const char* token_texture_sampler   = "TEXTURE_SAMPLER";
   6803 	const char* token_texture_swizzle   = "TEXTURE_SWIZZLE";
   6804 	const char* token_view_data_type	= "VIEW_DATA_TYPE";
   6805 	const char* token_view_sampler		= "VIEW_SAMPLER";
   6806 	const char* token_view_swizzle		= "VIEW_SWIZZLE";
   6807 	const char* vs_template_body		= "#version 400\n"
   6808 								   "\n"
   6809 								   "uniform TEXTURE_SAMPLER texture;\n"
   6810 								   "uniform VIEW_SAMPLER    view;\n"
   6811 								   "\n"
   6812 								   "out TEXTURE_DATA_TYPE out_texture_data;\n"
   6813 								   "out VIEW_DATA_TYPE    out_view_data;\n"
   6814 								   "\n"
   6815 								   "void main()\n"
   6816 								   "{\n"
   6817 								   "    ivec2 uv = ivec2(gl_VertexID % 4,\n"
   6818 								   "                     gl_VertexID / 4);\n"
   6819 								   "\n"
   6820 								   "    out_texture_data = texelFetch(texture, uv, 0).TEXTURE_SWIZZLE;\n"
   6821 								   "    out_view_data    = texelFetch(view,    uv, 0).VIEW_SWIZZLE;\n"
   6822 								   "}\n";
   6823 
   6824 	std::size_t token_position = std::string::npos;
   6825 	std::string vs_body		   = vs_template_body;
   6826 
   6827 	while ((token_position = vs_body.find(token_texture_data_type)) != std::string::npos)
   6828 	{
   6829 		vs_body.replace(token_position, strlen(token_texture_data_type), texture_sampler_data_type_glsl);
   6830 	}
   6831 
   6832 	while ((token_position = vs_body.find(token_texture_sampler)) != std::string::npos)
   6833 	{
   6834 		vs_body.replace(token_position, strlen(token_texture_sampler), texture_sampler_glsl);
   6835 	}
   6836 
   6837 	while ((token_position = vs_body.find(token_texture_swizzle)) != std::string::npos)
   6838 	{
   6839 		vs_body.replace(token_position, strlen(token_texture_swizzle), texture_swizzle_glsl);
   6840 	}
   6841 
   6842 	while ((token_position = vs_body.find(token_view_data_type)) != std::string::npos)
   6843 	{
   6844 		vs_body.replace(token_position, strlen(token_view_data_type), view_sampler_data_type_glsl);
   6845 	}
   6846 
   6847 	while ((token_position = vs_body.find(token_view_sampler)) != std::string::npos)
   6848 	{
   6849 		vs_body.replace(token_position, strlen(token_view_sampler), view_sampler_glsl);
   6850 	}
   6851 
   6852 	while ((token_position = vs_body.find(token_view_swizzle)) != std::string::npos)
   6853 	{
   6854 		vs_body.replace(token_position, strlen(token_view_swizzle), view_swizzle_glsl);
   6855 	}
   6856 
   6857 	/* Compile the shader */
   6858 	glw::GLint  compile_status  = GL_FALSE;
   6859 	const char* vs_body_raw_ptr = vs_body.c_str();
   6860 
   6861 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
   6862 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   6863 
   6864 	gl.compileShader(m_vs_id);
   6865 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   6866 
   6867 	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
   6868 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   6869 
   6870 	if (compile_status != GL_TRUE)
   6871 	{
   6872 		TCU_FAIL("Shader compilation failed");
   6873 	}
   6874 
   6875 	/* Configure test program object for XFB */
   6876 	const char*		   varying_names[] = { "out_texture_data", "out_view_data" };
   6877 	const unsigned int n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]);
   6878 
   6879 	gl.transformFeedbackVaryings(m_po_id, n_varying_names, varying_names, GL_SEPARATE_ATTRIBS);
   6880 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
   6881 
   6882 	/* Configure buffer object bindings for XFB */
   6883 	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index for 'out_texture_data' */
   6884 					   m_bo_id, 0,						/* offset */
   6885 					   m_view_data_offset);				/* size */
   6886 	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 1, /* index for 'out_view_data' */
   6887 					   m_bo_id, m_view_data_offset,		/* offset */
   6888 					   m_bo_size - m_view_data_offset); /* size */
   6889 
   6890 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange() call(s) failed.");
   6891 
   6892 	/* Link the program object */
   6893 	glw::GLint link_status = GL_FALSE;
   6894 
   6895 	gl.linkProgram(m_po_id);
   6896 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   6897 
   6898 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   6899 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   6900 
   6901 	if (link_status != GL_TRUE)
   6902 	{
   6903 		TCU_FAIL("Program linking failed.");
   6904 	}
   6905 
   6906 	/* Configure sampler uniforms */
   6907 	glw::GLint texture_uniform_location = gl.getUniformLocation(m_po_id, "texture");
   6908 	glw::GLint view_uniform_location	= gl.getUniformLocation(m_po_id, "view");
   6909 
   6910 	if (texture_uniform_location == -1)
   6911 	{
   6912 		TCU_FAIL("'texture' uniform is considered inactive which is invalid");
   6913 	}
   6914 
   6915 	if (view_uniform_location == -1)
   6916 	{
   6917 		TCU_FAIL("'view' uniform is considered inactive which is invalid");
   6918 	}
   6919 
   6920 	gl.useProgram(m_po_id);
   6921 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   6922 
   6923 	gl.uniform1i(texture_uniform_location, m_texture_unit_for_parent_texture - GL_TEXTURE0);
   6924 	gl.uniform1i(view_uniform_location, m_texture_unit_for_view_texture - GL_TEXTURE0);
   6925 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call(s) failed.");
   6926 }
   6927 
   6928 /** Creates GL objects required to run the test, as well as modifies GL
   6929  *  configuration (pixel pack/unpack settings, enables 'rasterizer discard' mode)
   6930  *  in order for the test to run properly.
   6931  **/
   6932 void TextureViewTestViewClasses::initTest()
   6933 {
   6934 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6935 
   6936 	/* Generate objects that will be used by all test iterations.
   6937 	 *
   6938 	 * Note that we're not generating texture objects here. This is owing to the fact
   6939 	 * we'll be using immutable textures and it makes more sense to generate the objects
   6940 	 * in initTexture() instead.
   6941 	 **/
   6942 	gl.genBuffers(1, &m_bo_id);
   6943 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
   6944 
   6945 	m_po_id = gl.createProgram();
   6946 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
   6947 
   6948 	gl.genVertexArrays(1, &m_vao_id);
   6949 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   6950 
   6951 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   6952 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
   6953 
   6954 	/* Attach the vertex shader to the program object */
   6955 	gl.attachShader(m_po_id, m_vs_id);
   6956 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
   6957 
   6958 	/* Configure general buffer object binding. Indiced bindings will be configured
   6959 	 * in initProgramObject()
   6960 	 */
   6961 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
   6962 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   6963 
   6964 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
   6965 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
   6966 
   6967 	/* Bind the VAO */
   6968 	gl.bindVertexArray(m_vao_id);
   6969 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   6970 
   6971 	/* Modify pack & unpack alignment settings */
   6972 	gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
   6973 	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
   6974 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed.");
   6975 
   6976 	/* Disable rasterizatino */
   6977 	gl.enable(GL_RASTERIZER_DISCARD);
   6978 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
   6979 }
   6980 
   6981 /** Generates and initializes storage of either the parent texture object or the
   6982  *  texture view, using user-specified internalformat.
   6983  *
   6984  *  @param should_init_parent_texture true to initialize parent texture object storage,
   6985  *                                    false to configure texture view.
   6986  *  @param internalformat             Internalformat to use for the process.
   6987  *  @param viewformat                 Internalformat that will be used by "view" texture.
   6988  *
   6989  **/
   6990 void TextureViewTestViewClasses::initTextureObject(bool should_init_parent_texture, glw::GLenum texture_internalformat,
   6991 												   glw::GLenum view_internalformat)
   6992 {
   6993 	glw::GLenum			  cached_view_internalformat = view_internalformat;
   6994 	const glw::Functions& gl						 = m_context.getRenderContext().getFunctions();
   6995 	glw::GLuint*		  to_id_ptr					 = (should_init_parent_texture) ? &m_to_id : &m_view_to_id;
   6996 
   6997 	/* If the object we're about to initialize has already been created, delete it first. */
   6998 	if (*to_id_ptr != 0)
   6999 	{
   7000 		gl.deleteTextures(1, to_id_ptr);
   7001 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
   7002 
   7003 		*to_id_ptr = 0;
   7004 	}
   7005 
   7006 	/* Generate a new texture object */
   7007 	gl.genTextures(1, to_id_ptr);
   7008 
   7009 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
   7010 
   7011 	/* Initialize the object */
   7012 	if (should_init_parent_texture)
   7013 	{
   7014 		gl.bindTexture(GL_TEXTURE_2D, *to_id_ptr);
   7015 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   7016 
   7017 		gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
   7018 						texture_internalformat, m_texture_width, m_texture_height);
   7019 
   7020 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   7021 	}
   7022 	else
   7023 	{
   7024 		gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, view_internalformat, 0, /* minlevel */
   7025 					   1,															 /* numlevels */
   7026 					   0,															 /* minlayer */
   7027 					   1);															 /* numlayers */
   7028 
   7029 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed.");
   7030 
   7031 		gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
   7032 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   7033 	}
   7034 
   7035 	if (should_init_parent_texture)
   7036 	{
   7037 		/* We need to fill the base mip-map with actual contents. Calculate how much
   7038 		 * data we will need to fill a 4x4 mip-map, given the requested internalformat.
   7039 		 */
   7040 		bool is_internalformat_compressed = TextureViewUtilities::isInternalformatCompressed(texture_internalformat);
   7041 		glw::GLenum internalformat_to_use = GL_NONE;
   7042 
   7043 		if (is_internalformat_compressed)
   7044 		{
   7045 			/* In order to initialize texture objects defined with a compressed internalformat
   7046 			 * using raw decompressed data, we need to override caller-specified internalformat
   7047 			 * with an internalformat that will describe decompressed data. The data will then
   7048 			 * be converted by GL to the compressed internalformat that was used for the previous
   7049 			 * glTexStorage2D() call.
   7050 			 **/
   7051 			_format format = TextureViewUtilities::getFormatOfInternalformat(texture_internalformat);
   7052 
   7053 			if (format == FORMAT_FLOAT)
   7054 			{
   7055 				internalformat_to_use = GL_RGBA32F;
   7056 			}
   7057 			else
   7058 			{
   7059 				DE_ASSERT(format == FORMAT_UNORM || format == FORMAT_SNORM);
   7060 
   7061 				internalformat_to_use = GL_RGBA8;
   7062 			}
   7063 
   7064 			view_internalformat = internalformat_to_use;
   7065 		}
   7066 		else
   7067 		{
   7068 			internalformat_to_use = texture_internalformat;
   7069 		}
   7070 
   7071 		/* Allocate the buffer.
   7072 		 *
   7073 		 * NOTE: This buffer is used in verifyResults(). When no longer needed, it will either
   7074 		 *       be deallocated there or in deinit().
   7075 		 **/
   7076 		glw::GLenum format_to_use   = TextureViewUtilities::getGLFormatOfInternalformat(internalformat_to_use);
   7077 		glw::GLenum type_to_use		= TextureViewUtilities::getTypeCompatibleWithInternalformat(internalformat_to_use);
   7078 		const glw::GLenum view_type = TextureViewUtilities::getTypeCompatibleWithInternalformat(view_internalformat);
   7079 
   7080 		/* For some internalformats, we need to use a special data type in order to avoid
   7081 		 * implicit data conversion during glTexSubImage2D() call.
   7082 		 */
   7083 		switch (texture_internalformat)
   7084 		{
   7085 		case GL_R11F_G11F_B10F:
   7086 			type_to_use = GL_UNSIGNED_INT_10F_11F_11F_REV;
   7087 			break;
   7088 		case GL_RGB9_E5:
   7089 			type_to_use = GL_UNSIGNED_INT_5_9_9_9_REV;
   7090 			break;
   7091 		case GL_RGB10_A2:
   7092 			type_to_use = GL_UNSIGNED_INT_2_10_10_10_REV;
   7093 			break;
   7094 
   7095 			/* Fall-through for other internalformats! */
   7096 		} /* switch (texture_internalformat) */
   7097 
   7098 		/* Carry on */
   7099 		const unsigned int mipmap_raw_size = TextureViewUtilities::getTextureDataSize(
   7100 			internalformat_to_use, type_to_use, m_texture_width, m_texture_height);
   7101 
   7102 		if (m_mipmap_data != NULL)
   7103 		{
   7104 			delete[] m_mipmap_data;
   7105 
   7106 			m_mipmap_data = NULL;
   7107 		}
   7108 
   7109 		m_mipmap_data = new unsigned char[mipmap_raw_size];
   7110 
   7111 		/* Prepare data for texture */
   7112 		memset(m_mipmap_data, 0, mipmap_raw_size);
   7113 
   7114 		switch (view_type)
   7115 		{
   7116 		case GL_BYTE:
   7117 		{
   7118 			glw::GLbyte*	  buffer			 = (glw::GLbyte*)m_mipmap_data;
   7119 			const glw::GLuint n_total_components = mipmap_raw_size / 1;
   7120 
   7121 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7122 			{
   7123 				buffer[i] = static_cast<glw::GLbyte>(i - 128);
   7124 			}
   7125 
   7126 			break;
   7127 		}
   7128 
   7129 		case GL_SHORT:
   7130 		{
   7131 			glw::GLshort*	 buffer			 = (glw::GLshort*)m_mipmap_data;
   7132 			const glw::GLuint n_total_components = mipmap_raw_size / 2;
   7133 
   7134 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7135 			{
   7136 				buffer[i] = static_cast<glw::GLshort>(i - 0xC000); // 0xC000 = (fp16) -2 makes this non de-norm
   7137 			}
   7138 
   7139 			break;
   7140 		}
   7141 
   7142 		case GL_INT:
   7143 		{
   7144 			glw::GLint*		  buffer			 = (glw::GLint*)m_mipmap_data;
   7145 			const glw::GLuint n_total_components = mipmap_raw_size / 4;
   7146 
   7147 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7148 			{
   7149 				buffer[i] = i - 128;
   7150 			}
   7151 
   7152 			break;
   7153 		}
   7154 
   7155 		case GL_UNSIGNED_BYTE:
   7156 		{
   7157 			glw::GLubyte*	 buffer			 = (glw::GLubyte*)m_mipmap_data;
   7158 			const glw::GLuint n_total_components = mipmap_raw_size / 1;
   7159 
   7160 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7161 			{
   7162 				buffer[i] = static_cast<glw::GLubyte>(i);
   7163 			}
   7164 
   7165 			break;
   7166 		}
   7167 
   7168 		case GL_UNSIGNED_SHORT:
   7169 		{
   7170 			glw::GLushort*	buffer			 = (glw::GLushort*)m_mipmap_data;
   7171 			const glw::GLuint n_total_components = mipmap_raw_size / 2;
   7172 
   7173 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7174 			{
   7175 				buffer[i] = static_cast<glw::GLushort>(i);
   7176 			}
   7177 
   7178 			break;
   7179 		}
   7180 
   7181 		case GL_UNSIGNED_INT:
   7182 		{
   7183 			glw::GLuint*	  buffer			 = (glw::GLuint*)m_mipmap_data;
   7184 			const glw::GLuint n_total_components = mipmap_raw_size / 4;
   7185 
   7186 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7187 			{
   7188 				buffer[i] = i;
   7189 			}
   7190 
   7191 			break;
   7192 		}
   7193 
   7194 		case GL_UNSIGNED_INT_24_8:
   7195 		{
   7196 			glw::GLuint*	  buffer			 = (glw::GLuint*)m_mipmap_data;
   7197 			const glw::GLuint n_total_components = mipmap_raw_size / 4;
   7198 
   7199 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7200 			{
   7201 				buffer[i] = (i << 8) | (0xaa);
   7202 			}
   7203 
   7204 			break;
   7205 		}
   7206 
   7207 		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
   7208 		{
   7209 			glw::GLfloat*	 float_buffer		 = (glw::GLfloat*)m_mipmap_data;
   7210 			const glw::GLuint n_total_components = mipmap_raw_size / 8;
   7211 			glw::GLuint*	  uint_buffer		 = (glw::GLuint*)(m_mipmap_data + 4);
   7212 
   7213 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7214 			{
   7215 				float_buffer[i * 2] = (float)i - 128;
   7216 				uint_buffer[i * 2]  = (i << 8) | (0xaa);
   7217 			}
   7218 
   7219 			break;
   7220 		}
   7221 
   7222 		case GL_HALF_FLOAT:
   7223 		{
   7224 			tcu::Float16*	 buffer			 = (tcu::Float16*)m_mipmap_data;
   7225 			const glw::GLuint n_total_components = mipmap_raw_size / 2;
   7226 
   7227 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7228 			{
   7229 				float value = (float)i - 128;
   7230 
   7231 				buffer[i] = (tcu::Float16)value;
   7232 			}
   7233 
   7234 			break;
   7235 		}
   7236 
   7237 		case GL_FLOAT:
   7238 		{
   7239 			glw::GLfloat*	 float_buffer		 = (glw::GLfloat*)m_mipmap_data;
   7240 			const glw::GLuint n_total_components = mipmap_raw_size / 4;
   7241 
   7242 			float offset = (cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) ? 0.0f : -128.0f;
   7243 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7244 			{
   7245 				float_buffer[i] = (float)i + offset;
   7246 			}
   7247 
   7248 			break;
   7249 		}
   7250 
   7251 		case GL_UNSIGNED_INT_2_10_10_10_REV:
   7252 		{
   7253 			glw::GLuint*	  buffer			 = (glw::GLuint*)m_mipmap_data;
   7254 			const glw::GLuint n_total_components = mipmap_raw_size / 4;
   7255 
   7256 			for (glw::GLuint i = 0; i < n_total_components; ++i)
   7257 			{
   7258 				buffer[i] = i | (i << 8) | (i << 16);
   7259 			}
   7260 
   7261 			break;
   7262 		}
   7263 
   7264 		default:
   7265 		{
   7266 			TCU_FAIL("Unrecognized texture view type");
   7267 		}
   7268 		} /* switch (view_type) */
   7269 
   7270 		/* BPTC_FLOAT view class is a special case that needs an extra step. Signed and
   7271 		 * unsigned internal formats use different encodings, so instead of passing
   7272 		 * "regular" 32-bit floating-point data, we need to convert the values we initialized
   7273 		 * above to an actual BPTC representation. Since the encodings differ, we should
   7274 		 * compress these values using the internalformat that we will be later using for the
   7275 		 * texture view.
   7276 		 */
   7277 		unsigned int imageSize_to_use					= 0;
   7278 		bool		 use_glCompressedTexSubImage2D_call = false;
   7279 
   7280 		if ((cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT ||
   7281 			 cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) &&
   7282 			cached_view_internalformat != texture_internalformat)
   7283 		{
   7284 			/* Create a temporary texture object we'll use to compress the floating-point data. */
   7285 			gl.genTextures(1, &m_to_temp_id);
   7286 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
   7287 
   7288 			gl.bindTexture(GL_TEXTURE_2D, m_to_temp_id);
   7289 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   7290 
   7291 			/* Initialize compressed storage */
   7292 			gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
   7293 							cached_view_internalformat, m_texture_width, m_texture_height);
   7294 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   7295 
   7296 			/* Submit floating-point decompressed data */
   7297 			gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
   7298 							 0,				   /* xoffset */
   7299 							 0,				   /* yoffset */
   7300 							 m_texture_width, m_texture_height, GL_RGB, GL_FLOAT, m_mipmap_data);
   7301 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
   7302 
   7303 			/* Extract the compressed version */
   7304 			gl.getCompressedTexImage(GL_TEXTURE_2D, 0, /* level */
   7305 									 m_mipmap_data);
   7306 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage() call failed.");
   7307 
   7308 			/* Delete the temporary texture object */
   7309 			gl.deleteTextures(1, &m_to_temp_id);
   7310 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
   7311 
   7312 			m_to_temp_id = 0;
   7313 
   7314 			/* Revert to previous 2D texture binding */
   7315 			gl.bindTexture(GL_TEXTURE_2D, m_to_id);
   7316 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   7317 
   7318 			/* Make sure upcoming glCompressedTexSubImage2D() call is made with sensible arguments */
   7319 			imageSize_to_use = (unsigned int)ceil((float)m_texture_width / 4.0f) *
   7320 							   (unsigned int)ceil((float)m_texture_height / 4.0f) * 16; /* block size */
   7321 			use_glCompressedTexSubImage2D_call = true;
   7322 		}
   7323 
   7324 		/* Fill the mip-map with data */
   7325 		if (use_glCompressedTexSubImage2D_call)
   7326 		{
   7327 			gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, /* level */
   7328 									   0,				 /* xoffset */
   7329 									   0,				 /* yoffset */
   7330 									   m_texture_width, m_texture_height, texture_internalformat, imageSize_to_use,
   7331 									   m_mipmap_data);
   7332 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexSubImage2D() call failed.");
   7333 		}
   7334 		else
   7335 		{
   7336 			gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
   7337 							 0,				   /* xoffset */
   7338 							 0,				   /* yoffset */
   7339 							 m_texture_width, m_texture_height, format_to_use, type_to_use, m_mipmap_data);
   7340 
   7341 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
   7342 		}
   7343 	}
   7344 
   7345 	/* Make sure the texture object is complete */
   7346 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
   7347 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   7348 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
   7349 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
   7350 					 GL_NEAREST); /* we're using texelFetch() so no mipmaps needed */
   7351 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   7352 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   7353 
   7354 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed.");
   7355 }
   7356 
   7357 /** Executes test iteration.
   7358  *
   7359  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   7360  */
   7361 tcu::TestNode::IterateResult TextureViewTestViewClasses::iterate()
   7362 {
   7363 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7364 
   7365 	/* Only execute the test if GL_ARB_texture_view is supported */
   7366 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view"))
   7367 	{
   7368 		throw tcu::NotSupportedError("GL_ARB_texture_view is not supported, skipping.");
   7369 	}
   7370 
   7371 	/* Create all GL objects required to run the test */
   7372 	initTest();
   7373 
   7374 	/* Iterate through all valid "texture internalformat + view internalformat" combinations */
   7375 	TextureViewUtilities::_compatible_internalformat_pairs_const_iterator internalformat_combination_iterator;
   7376 	TextureViewUtilities::_compatible_internalformat_pairs				  internalformat_combinations =
   7377 		TextureViewUtilities::getLegalTextureAndViewInternalformatCombinations();
   7378 
   7379 	for (internalformat_combination_iterator = internalformat_combinations.begin();
   7380 		 internalformat_combination_iterator != internalformat_combinations.end();
   7381 		 internalformat_combination_iterator++)
   7382 	{
   7383 		TextureViewUtilities::_internalformat_pair internalformat_pair	= *internalformat_combination_iterator;
   7384 		glw::GLenum								   texture_internalformat = internalformat_pair.first;
   7385 		glw::GLenum								   view_internalformat	= internalformat_pair.second;
   7386 
   7387 		/* Initialize parent texture object storage */
   7388 		initTextureObject(true, /* should_init_parent_texture */
   7389 						  texture_internalformat, view_internalformat);
   7390 
   7391 		/* Create the texture view */
   7392 		initTextureObject(false, /* should_init_parent_texture */
   7393 						  texture_internalformat, view_internalformat);
   7394 
   7395 		/* Initialize buffer object storage so that it's large enough to
   7396 		 * hold the result data.
   7397 		 **/
   7398 		initBufferObject(texture_internalformat, view_internalformat);
   7399 
   7400 		/* Create the program object we'll use for the test */
   7401 		initProgramObject(texture_internalformat, view_internalformat);
   7402 
   7403 		/* Configure texture bindings */
   7404 		gl.activeTexture(m_texture_unit_for_parent_texture);
   7405 		GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
   7406 
   7407 		gl.bindTexture(GL_TEXTURE_2D, m_to_id);
   7408 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   7409 
   7410 		gl.activeTexture(m_texture_unit_for_view_texture);
   7411 		GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
   7412 
   7413 		gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
   7414 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   7415 
   7416 		/* Run the test program */
   7417 		gl.beginTransformFeedback(GL_POINTS);
   7418 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
   7419 		{
   7420 			gl.drawArrays(GL_POINTS, 0 /* first */, m_texture_width * m_texture_height);
   7421 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   7422 		}
   7423 		gl.endTransformFeedback();
   7424 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
   7425 
   7426 		/* Retrieve the results */
   7427 		const unsigned char* result_bo_data_ptr =
   7428 			(const unsigned char*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   7429 		const unsigned char* result_texture_data_ptr = result_bo_data_ptr;
   7430 		const unsigned char* result_view_data_ptr	= result_bo_data_ptr + m_view_data_offset;
   7431 
   7432 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   7433 
   7434 		/* Verify the retrieved values are valid */
   7435 		verifyResultData(texture_internalformat, view_internalformat, result_texture_data_ptr, result_view_data_ptr);
   7436 
   7437 		/* Unmap the buffer object */
   7438 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   7439 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
   7440 	} /* for (all internalformat combinations) */
   7441 
   7442 	if (m_has_test_failed)
   7443 	{
   7444 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   7445 	}
   7446 	else
   7447 	{
   7448 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   7449 	}
   7450 
   7451 	return STOP;
   7452 }
   7453 
   7454 /** Verifies the data XFBed out by the test's vertex shader is valid.
   7455  *
   7456  *  @param texture_internalformat Internalformat that was used to define storage
   7457  *                                of the parent texture object.
   7458  *  @param view_internalformat    Internalformat that was used to define texture
   7459  *                                view.
   7460  *  @param texture_data_ptr       Data, as XFBed out by the vertex shader, that was
   7461  *                                built by texelFetch() calls operating on the parent
   7462  *                                texture object.
   7463  *  @param view_data_ptr          Data, as XFBed out by the vertex shader, that was
   7464  *                                built by texelFetch() calls operating on the texture
   7465  *                                view.
   7466  *
   7467  **/
   7468 void TextureViewTestViewClasses::verifyResultData(glw::GLenum texture_internalformat, glw::GLenum view_internalformat,
   7469 												  const unsigned char* texture_data_ptr,
   7470 												  const unsigned char* view_data_ptr)
   7471 {
   7472 	const char* texture_internalformat_string = TextureViewUtilities::getInternalformatString(texture_internalformat);
   7473 	const char* view_internalformat_string	= TextureViewUtilities::getInternalformatString(view_internalformat);
   7474 
   7475 	/* For quite a number of cases, we can do a plain memcmp() applied to sampled texture/view data.
   7476 	 * If both buffers are a match, we're OK.
   7477 	 */
   7478 	bool				 has_failed  = false;
   7479 	const unsigned char* mipmap_data = DE_NULL;
   7480 
   7481 	if (memcmp(texture_data_ptr, view_data_ptr, m_view_data_offset) != 0)
   7482 	{
   7483 		/* Iterate over all texel components.
   7484 		 *
   7485 		 * The approach we're taking here works as follows:
   7486 		 *
   7487 		 * 1) Calculate what values should be sampled for each component using input mipmap
   7488 		 *    data.
   7489 		 * 2) Compare the reference values against the values returned when sampling the view.
   7490 		 *
   7491 		 * Note that in step 2) we're dealing with data that is returned by float/int/uint samplers,
   7492 		 * so we need to additionally process the data that we obtain by "casting" input data to
   7493 		 * the view's internalformat before we can perform the comparison.
   7494 		 *
   7495 		 * Finally, if the reference values are calculated for compressed data, we decompress it
   7496 		 * to GL_R8/GL_RG8/GL_RGB8/GL_RGBA8 internalformat first, depending on how many components
   7497 		 * the compressed internalformat supports.
   7498 		 **/
   7499 		bool				  can_continue = true;
   7500 		const glw::Functions& gl		   = m_context.getRenderContext().getFunctions();
   7501 
   7502 		/* Determine a few important properties first */
   7503 		const bool is_view_internalformat_compressed =
   7504 			TextureViewUtilities::isInternalformatCompressed(view_internalformat);
   7505 		unsigned int n_bits_per_view_texel = 0;
   7506 
   7507 		const unsigned int n_view_components =
   7508 			TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat);
   7509 		_format texture_format = TextureViewUtilities::getFormatOfInternalformat(texture_internalformat);
   7510 
   7511 		unsigned int view_component_sizes[4] = { 0 };
   7512 		_format		 view_format			 = TextureViewUtilities::getFormatOfInternalformat(view_internalformat);
   7513 
   7514 		if (!is_view_internalformat_compressed)
   7515 		{
   7516 			TextureViewUtilities::getComponentSizeForInternalformat(view_internalformat, view_component_sizes);
   7517 
   7518 			n_bits_per_view_texel =
   7519 				view_component_sizes[0] + view_component_sizes[1] + view_component_sizes[2] + view_component_sizes[3];
   7520 		}
   7521 		else
   7522 		{
   7523 			if (texture_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT ||
   7524 				texture_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT)
   7525 			{
   7526 				/* Each component of decompressed data will be retrieved as a 32-bit FP */
   7527 				for (unsigned int n_component = 0; n_component < n_view_components; ++n_component)
   7528 				{
   7529 					view_component_sizes[n_component] = 32 /* bits per byte */;
   7530 				}
   7531 
   7532 				n_bits_per_view_texel = 32 /* bits per byte */ * n_view_components;
   7533 			}
   7534 			else
   7535 			{
   7536 				/* Each component of decompressed data is stored as either signed or unsigned
   7537 				 * byte. */
   7538 				for (unsigned int n_component = 0; n_component < n_view_components; ++n_component)
   7539 				{
   7540 					view_component_sizes[n_component] = 8 /* bits per byte */;
   7541 				}
   7542 
   7543 				n_bits_per_view_texel = 8 /* bits per byte */ * n_view_components;
   7544 			}
   7545 		}
   7546 
   7547 		/* If we need to use compressed data as reference, we need to ask GL to decompress
   7548 		 * the mipmap data using view-specific internalformat.
   7549 		 */
   7550 		mipmap_data = m_mipmap_data;
   7551 
   7552 		if (is_view_internalformat_compressed)
   7553 		{
   7554 			/* Deallocate the buffer if necessary just in case */
   7555 			if (m_decompressed_mipmap_data != DE_NULL)
   7556 			{
   7557 				delete[] m_decompressed_mipmap_data;
   7558 
   7559 				m_decompressed_mipmap_data = DE_NULL;
   7560 			}
   7561 
   7562 			m_decompressed_mipmap_data =
   7563 				new unsigned char[m_texture_width * m_texture_height * (n_bits_per_view_texel >> 3)];
   7564 
   7565 			glw::GLuint reference_tex_id = m_to_id;
   7566 			if (texture_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT ||
   7567 				texture_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT)
   7568 			{
   7569 				// Encodings of SIGNED and UNSIGNED BPTC compressed texture are not compatible
   7570 				// even though they are in the same view class. Since the "view" texture contains
   7571 				// the correct encoding for the results we use that as a reference instead of the
   7572 				// incompatible parent encoded.
   7573 				reference_tex_id = m_view_to_id;
   7574 			}
   7575 			gl.bindTexture(GL_TEXTURE_2D, reference_tex_id);
   7576 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   7577 
   7578 			gl.getTexImage(GL_TEXTURE_2D, 0, /* level */
   7579 						   (n_view_components == 4) ?
   7580 							   GL_RGBA :
   7581 							   (n_view_components == 3) ? GL_RGB : (n_view_components == 2) ? GL_RG : GL_RED,
   7582 						   (texture_format == FORMAT_SNORM) ?
   7583 							   GL_BYTE :
   7584 							   (texture_format == FORMAT_FLOAT) ? GL_FLOAT : GL_UNSIGNED_BYTE,
   7585 						   m_decompressed_mipmap_data);
   7586 
   7587 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage() call failed.");
   7588 
   7589 			mipmap_data = m_decompressed_mipmap_data;
   7590 		}
   7591 
   7592 		for (unsigned int n_texel = 0; n_texel < m_texture_height * m_texture_width && can_continue; ++n_texel)
   7593 		{
   7594 			/* NOTE: Vertex shader stores the sampled contents of a view texture as a
   7595 			 *       vec4/ivec4/uvec4. This means that each comonent in view_data_ptr
   7596 			 *       always takes sizeof(float) = sizeof(int) = sizeof(uint) bytes.
   7597 			 *
   7598 			 * NOTE: We cast input mip-map's data to view's internalformat, which is
   7599 			 *       why we're assuming each components takes n_bits_per_view_texel
   7600 			 *       bits instead of n_bits_per_mipmap_texel.
   7601 			 */
   7602 			const unsigned char* mipmap_texel_data =
   7603 				mipmap_data + (n_bits_per_view_texel >> 3 /* 8 bits/byte */) * n_texel;
   7604 			float		  reference_components_float[4] = { 0 };
   7605 			signed int	reference_components_int[4]   = { 0 };
   7606 			unsigned int  reference_components_uint[4]  = { 0 };
   7607 			float		  view_components_float[4]		= { 0 };
   7608 			signed int	view_components_int[4]		= { 0 };
   7609 			unsigned int  view_components_uint[4]		= { 0 };
   7610 			_sampler_type view_sampler_type =
   7611 				TextureViewUtilities::getSamplerTypeForInternalformat(view_internalformat);
   7612 			const unsigned char* view_texel_data = view_data_ptr + sizeof(float) * n_view_components * n_texel;
   7613 
   7614 			/* Retrieve data sampled from the view */
   7615 			for (unsigned int n_component = 0; n_component < n_view_components;
   7616 				 view_texel_data += sizeof(float), /* as per comment */
   7617 				 ++n_component)
   7618 			{
   7619 				switch (view_sampler_type)
   7620 				{
   7621 				case SAMPLER_TYPE_FLOAT:
   7622 				{
   7623 					view_components_float[n_component] = *((float*)view_texel_data);
   7624 
   7625 					break;
   7626 				}
   7627 
   7628 				case SAMPLER_TYPE_SIGNED_INTEGER:
   7629 				{
   7630 					view_components_int[n_component] = *((signed int*)view_texel_data);
   7631 
   7632 					break;
   7633 				}
   7634 
   7635 				case SAMPLER_TYPE_UNSIGNED_INTEGER:
   7636 				{
   7637 					view_components_uint[n_component] = *((unsigned int*)view_texel_data);
   7638 
   7639 					break;
   7640 				}
   7641 
   7642 				default:
   7643 				{
   7644 					TCU_FAIL("Unrecognized sampler type");
   7645 				}
   7646 				} /* switch (view_sampler_type) */
   7647 			}	 /* for (all components) */
   7648 
   7649 			/* Compute reference data. Handle non-byte aligned internalformats manually. */
   7650 			if (view_internalformat == GL_R11F_G11F_B10F)
   7651 			{
   7652 				const unsigned int* reference_data  = (unsigned int*)mipmap_texel_data;
   7653 				const unsigned int  red_component   = (*reference_data) & ((1 << 11) - 1);
   7654 				const unsigned int  green_component = (*reference_data >> 11) & ((1 << 11) - 1);
   7655 				const unsigned int  blue_component  = (*reference_data >> 22) & ((1 << 10) - 1);
   7656 
   7657 				if (view_sampler_type == SAMPLER_TYPE_FLOAT)
   7658 				{
   7659 					reference_components_float[0] = Float11(red_component).asFloat();
   7660 					reference_components_float[1] = Float11(green_component).asFloat();
   7661 					reference_components_float[2] = Float10(blue_component).asFloat();
   7662 				}
   7663 				else
   7664 				{
   7665 					TCU_FAIL("Internal error: invalid sampler type requested");
   7666 				}
   7667 			}
   7668 			else if (view_internalformat == GL_RGB9_E5)
   7669 			{
   7670 				/* Refactored version of tcuTexture.cpp::unpackRGB999E5() */
   7671 				const unsigned int* reference_data  = (unsigned int*)mipmap_texel_data;
   7672 				const unsigned int  exponent		= (*reference_data >> 27) & ((1 << 5) - 1);
   7673 				const unsigned int  red_component   = (*reference_data) & ((1 << 9) - 1);
   7674 				const unsigned int  green_component = (*reference_data >> 9) & ((1 << 9) - 1);
   7675 				const unsigned int  blue_component  = (*reference_data >> 18) & ((1 << 9) - 1);
   7676 
   7677 				float shared_exponent =
   7678 					deFloatPow(2.0f, (float)((int)exponent - 15 /* exponent bias */ - 9 /* mantissa */));
   7679 
   7680 				if (view_sampler_type == SAMPLER_TYPE_FLOAT)
   7681 				{
   7682 					reference_components_float[0] = float(red_component) * shared_exponent;
   7683 					reference_components_float[1] = float(green_component) * shared_exponent;
   7684 					reference_components_float[2] = float(blue_component) * shared_exponent;
   7685 				}
   7686 				else
   7687 				{
   7688 					TCU_FAIL("Internal error: invalid sampler type requested");
   7689 				}
   7690 			}
   7691 			else if (view_internalformat == GL_RGB10_A2)
   7692 			{
   7693 				unsigned int*	  reference_data = (unsigned int*)mipmap_texel_data;
   7694 				const unsigned int mask_rgb		  = (1 << 10) - 1;
   7695 				const unsigned int mask_a		  = (1 << 2) - 1;
   7696 
   7697 				if (view_sampler_type == SAMPLER_TYPE_FLOAT)
   7698 				{
   7699 					reference_components_float[0] = float(((*reference_data)) & (mask_rgb)) / float(mask_rgb);
   7700 					reference_components_float[1] = float(((*reference_data) >> 10) & (mask_rgb)) / float(mask_rgb);
   7701 					reference_components_float[2] = float(((*reference_data) >> 20) & (mask_rgb)) / float(mask_rgb);
   7702 					reference_components_float[3] = float(((*reference_data) >> 30) & (mask_a)) / float(mask_a);
   7703 				}
   7704 				else
   7705 				{
   7706 					TCU_FAIL("Internal error: invalid sampler type requested");
   7707 				}
   7708 			}
   7709 			else if (view_internalformat == GL_RGB10_A2UI)
   7710 			{
   7711 				unsigned int*	  reference_data = (unsigned int*)mipmap_texel_data;
   7712 				const unsigned int mask_rgb		  = (1 << 10) - 1;
   7713 				const unsigned int mask_a		  = (1 << 2) - 1;
   7714 
   7715 				if (view_sampler_type == SAMPLER_TYPE_UNSIGNED_INTEGER)
   7716 				{
   7717 					reference_components_uint[0] = ((*reference_data)) & (mask_rgb);
   7718 					reference_components_uint[1] = ((*reference_data) >> 10) & (mask_rgb);
   7719 					reference_components_uint[2] = ((*reference_data) >> 20) & (mask_rgb);
   7720 					reference_components_uint[3] = ((*reference_data) >> 30) & (mask_a);
   7721 				}
   7722 				else
   7723 				{
   7724 					TCU_FAIL("Internal error: invalid sampler type requested");
   7725 				}
   7726 			}
   7727 			else if (view_internalformat == GL_RG16F)
   7728 			{
   7729 				unsigned short* reference_data = (unsigned short*)mipmap_texel_data;
   7730 
   7731 				if (view_sampler_type == SAMPLER_TYPE_FLOAT)
   7732 				{
   7733 					reference_components_float[0] = tcu::Float16(*(reference_data + 0)).asFloat();
   7734 					reference_components_float[1] = tcu::Float16(*(reference_data + 1)).asFloat();
   7735 				}
   7736 				else
   7737 				{
   7738 					TCU_FAIL("Internal error: invalid sampler type requested");
   7739 				}
   7740 			}
   7741 			else
   7742 			{
   7743 				void* result_data = NULL;
   7744 
   7745 				switch (view_sampler_type)
   7746 				{
   7747 				case SAMPLER_TYPE_FLOAT:
   7748 					result_data = reference_components_float;
   7749 					break;
   7750 				case SAMPLER_TYPE_SIGNED_INTEGER:
   7751 					result_data = reference_components_int;
   7752 					break;
   7753 				case SAMPLER_TYPE_UNSIGNED_INTEGER:
   7754 					result_data = reference_components_uint;
   7755 					break;
   7756 
   7757 				default:
   7758 					TCU_FAIL("Unrecognized sampler type");
   7759 				}
   7760 
   7761 				getComponentDataForByteAlignedInternalformat(mipmap_texel_data, n_view_components, view_component_sizes,
   7762 															 view_format, result_data);
   7763 			}
   7764 
   7765 			for (unsigned int n_component = 0; n_component < n_view_components; ++n_component)
   7766 			{
   7767 				/* If view texture operates on sRGB color space, we need to adjust our
   7768 				 * reference value so that it is moved back into linear space.
   7769 				 */
   7770 				if (TextureViewUtilities::isInternalformatSRGB(view_internalformat) &&
   7771 					!TextureViewUtilities::isInternalformatSRGB(texture_internalformat))
   7772 				{
   7773 					DE_ASSERT(view_sampler_type == SAMPLER_TYPE_FLOAT);
   7774 
   7775 					/* Convert as per (8.14) from GL4.4 spec. Exclude alpha channel. */
   7776 					if (n_component != 3)
   7777 					{
   7778 						if (reference_components_float[n_component] <= 0.04045f)
   7779 						{
   7780 							reference_components_float[n_component] /= 12.92f;
   7781 						}
   7782 						else
   7783 						{
   7784 							reference_components_float[n_component] =
   7785 								deFloatPow((reference_components_float[n_component] + 0.055f) / 1.055f, 2.4f);
   7786 						}
   7787 					} /* if (n_component != 3) */
   7788 				}	 /* if (TextureViewUtilities::isInternalformatSRGB(view_internalformat) ) */
   7789 
   7790 				/* Compare the reference and view texture values */
   7791 				const float		   epsilon_float = 1.0f / float((1 << (view_component_sizes[n_component] - 1)) - 1);
   7792 				const signed int   epsilon_int   = 1;
   7793 				const unsigned int epsilon_uint  = 1;
   7794 
   7795 				switch (view_sampler_type)
   7796 				{
   7797 				case SAMPLER_TYPE_FLOAT:
   7798 				{
   7799 					if (de::abs(reference_components_float[n_component] - view_components_float[n_component]) >
   7800 						epsilon_float)
   7801 					{
   7802 						has_failed = true;
   7803 					}
   7804 
   7805 					break;
   7806 				}
   7807 
   7808 				case SAMPLER_TYPE_SIGNED_INTEGER:
   7809 				{
   7810 					signed int larger_value  = 0;
   7811 					signed int smaller_value = 0;
   7812 
   7813 					if (reference_components_int[n_component] > view_components_int[n_component])
   7814 					{
   7815 						larger_value  = reference_components_int[n_component];
   7816 						smaller_value = view_components_int[n_component];
   7817 					}
   7818 					else
   7819 					{
   7820 						smaller_value = reference_components_int[n_component];
   7821 						larger_value  = view_components_int[n_component];
   7822 					}
   7823 
   7824 					if ((larger_value - smaller_value) > epsilon_int)
   7825 					{
   7826 						has_failed = true;
   7827 					}
   7828 
   7829 					break;
   7830 				}
   7831 
   7832 				case SAMPLER_TYPE_UNSIGNED_INTEGER:
   7833 				{
   7834 					unsigned int larger_value  = 0;
   7835 					unsigned int smaller_value = 0;
   7836 
   7837 					if (reference_components_uint[n_component] > view_components_uint[n_component])
   7838 					{
   7839 						larger_value  = reference_components_uint[n_component];
   7840 						smaller_value = view_components_uint[n_component];
   7841 					}
   7842 					else
   7843 					{
   7844 						smaller_value = reference_components_uint[n_component];
   7845 						larger_value  = view_components_uint[n_component];
   7846 					}
   7847 
   7848 					if ((larger_value - smaller_value) > epsilon_uint)
   7849 					{
   7850 						has_failed = true;
   7851 					}
   7852 
   7853 					break;
   7854 				}
   7855 
   7856 				default:
   7857 					TCU_FAIL("Unrecognized sampler type");
   7858 				} /* switch (view_sampler_type) */
   7859 
   7860 				if (has_failed)
   7861 				{
   7862 					can_continue = false;
   7863 
   7864 					switch (view_sampler_type)
   7865 					{
   7866 					case SAMPLER_TYPE_FLOAT:
   7867 					{
   7868 						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data sampled from a texture view "
   7869 																	   "["
   7870 										   << view_internalformat_string << "]"
   7871 																			" created from a texture object"
   7872 																			"["
   7873 										   << texture_internalformat_string << "]"
   7874 																			   " at texel "
   7875 																			   "("
   7876 										   << (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height)
   7877 										   << "): expected:(" << reference_components_float[0] << ", "
   7878 										   << reference_components_float[1] << ", " << reference_components_float[2]
   7879 										   << ", " << reference_components_float[3] << ") found:("
   7880 										   << view_components_float[0] << ", " << view_components_float[1] << ", "
   7881 										   << view_components_float[2] << ", " << view_components_float[3] << ")."
   7882 										   << tcu::TestLog::EndMessage;
   7883 
   7884 						break;
   7885 					}
   7886 
   7887 					case SAMPLER_TYPE_SIGNED_INTEGER:
   7888 					{
   7889 						m_testCtx.getLog()
   7890 							<< tcu::TestLog::Message << "Invalid data sampled from a signed integer texture view "
   7891 														"["
   7892 							<< view_internalformat_string << "]"
   7893 															 " created from a texture object"
   7894 															 "["
   7895 							<< texture_internalformat_string << "]"
   7896 																" at texel "
   7897 																"("
   7898 							<< (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height) << "): expected:("
   7899 							<< reference_components_int[0] << ", " << reference_components_int[1] << ", "
   7900 							<< reference_components_int[2] << ", " << reference_components_int[3] << ") found:("
   7901 							<< view_components_int[0] << ", " << view_components_int[1] << ", "
   7902 							<< view_components_int[2] << ", " << view_components_int[3] << ")."
   7903 							<< tcu::TestLog::EndMessage;
   7904 
   7905 						break;
   7906 					}
   7907 
   7908 					case SAMPLER_TYPE_UNSIGNED_INTEGER:
   7909 					{
   7910 						m_testCtx.getLog()
   7911 							<< tcu::TestLog::Message << "Invalid data sampled from an unsigned integer texture view "
   7912 														"["
   7913 							<< view_internalformat_string << "]"
   7914 															 " created from a texture object"
   7915 															 "["
   7916 							<< texture_internalformat_string << "]"
   7917 																" at texel "
   7918 																"("
   7919 							<< (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height) << "): expected:("
   7920 							<< reference_components_uint[0] << ", " << reference_components_uint[1] << ", "
   7921 							<< reference_components_uint[2] << ", " << reference_components_uint[3] << ") found:("
   7922 							<< view_components_uint[0] << ", " << view_components_uint[1] << ", "
   7923 							<< view_components_uint[2] << ", " << view_components_uint[3] << ")."
   7924 							<< tcu::TestLog::EndMessage;
   7925 
   7926 						break;
   7927 					}
   7928 
   7929 					default:
   7930 						TCU_FAIL("Unrecognized sampler type");
   7931 					} /* switch (view_sampler_type) */
   7932 
   7933 					break;
   7934 				} /* if (has_failed) */
   7935 			}	 /* for (all components) */
   7936 		}		  /* for (all texels) */
   7937 	}			  /* if (memcmp(texture_data_ptr, view_data_ptr, m_view_data_offset) != 0) */
   7938 
   7939 	if (has_failed)
   7940 	{
   7941 		/* Log detailed information about the failure */
   7942 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data read from a view of internalformat "
   7943 						   << "[" << view_internalformat_string << "]"
   7944 						   << " created from a texture of internalformat "
   7945 						   << "[" << texture_internalformat_string << "]"
   7946 						   << ". Byte streams follow:" << tcu::TestLog::EndMessage;
   7947 
   7948 		/* Form texture and view data strings */
   7949 		std::stringstream mipmap_data_sstream;
   7950 		std::stringstream sampled_view_data_sstream;
   7951 
   7952 		mipmap_data_sstream.fill('0');
   7953 		sampled_view_data_sstream.fill('0');
   7954 
   7955 		mipmap_data_sstream.width(2);
   7956 		sampled_view_data_sstream.width(2);
   7957 
   7958 		mipmap_data_sstream << "Mip-map data: [";
   7959 		sampled_view_data_sstream << "Sampled view data: [";
   7960 
   7961 		for (unsigned int n = 0; n < m_view_data_offset; ++n)
   7962 		{
   7963 			mipmap_data_sstream << "0x" << std::hex << (int)(mipmap_data[n]);
   7964 			sampled_view_data_sstream << "0x" << std::hex << (int)(view_data_ptr[n]);
   7965 
   7966 			if (n != (m_view_data_offset - 1))
   7967 			{
   7968 				mipmap_data_sstream << "|";
   7969 				sampled_view_data_sstream << "|";
   7970 			}
   7971 			else
   7972 			{
   7973 				mipmap_data_sstream << "]";
   7974 				sampled_view_data_sstream << "]";
   7975 			}
   7976 		}
   7977 
   7978 		sampled_view_data_sstream << "\n";
   7979 		mipmap_data_sstream << "\n";
   7980 
   7981 		/* Log both strings */
   7982 		m_testCtx.getLog() << tcu::TestLog::Message << mipmap_data_sstream.str() << sampled_view_data_sstream.str()
   7983 						   << tcu::TestLog::EndMessage;
   7984 
   7985 		/* Do not fail the test at this point. Instead, raise a failure flag that will
   7986 		 * cause the test to fail once all iterations execute */
   7987 		m_has_test_failed = true;
   7988 	}
   7989 	else
   7990 	{
   7991 		m_testCtx.getLog() << tcu::TestLog::Message << "Correct data read from a view of internalformat "
   7992 						   << "[" << view_internalformat_string << "]"
   7993 						   << " created from a texture of internalformat "
   7994 						   << "[" << texture_internalformat_string << "]" << tcu::TestLog::EndMessage;
   7995 	}
   7996 }
   7997 
   7998 /** Constructor.
   7999  *
   8000  *  @param context Rendering context.
   8001  *
   8002  **/
   8003 TextureViewTestCoherency::TextureViewTestCoherency(deqp::Context& context)
   8004 	: TestCase(context, "coherency", "Verifies view/parent texture coherency")
   8005 	, m_are_images_supported(false)
   8006 	, m_bo_id(0)
   8007 	, m_draw_fbo_id(0)
   8008 	, m_gradient_verification_po_id(0)
   8009 	, m_gradient_verification_po_sample_exact_uv_location(-1)
   8010 	, m_gradient_verification_po_lod_location(-1)
   8011 	, m_gradient_verification_po_texture_location(-1)
   8012 	, m_gradient_verification_vs_id(0)
   8013 	, m_gradient_image_write_image_size_location(-1)
   8014 	, m_gradient_image_write_po_id(0)
   8015 	, m_gradient_image_write_vs_id(0)
   8016 	, m_gradient_write_po_id(0)
   8017 	, m_gradient_write_fs_id(0)
   8018 	, m_gradient_write_vs_id(0)
   8019 	, m_read_fbo_id(0)
   8020 	, m_static_to_id(0)
   8021 	, m_to_id(0)
   8022 	, m_vao_id(0)
   8023 	, m_view_to_id(0)
   8024 	, m_verification_po_expected_color_location(-1)
   8025 	, m_verification_po_lod_location(-1)
   8026 	, m_verification_po_id(0)
   8027 	, m_verification_vs_id(0)
   8028 	, m_static_texture_height(1)
   8029 	, m_static_texture_width(1)
   8030 	, m_texture_height(64)
   8031 	, m_texture_n_components(4)
   8032 	, m_texture_n_levels(7)
   8033 	, m_texture_width(64)
   8034 {
   8035 	/* Initialize static color that will be used for some of the cases */
   8036 	m_static_color_byte[0] = 100;
   8037 	m_static_color_byte[1] = 0;
   8038 	m_static_color_byte[2] = 255;
   8039 	m_static_color_byte[3] = 200;
   8040 
   8041 	m_static_color_float[0] = float(m_static_color_byte[0]) / 255.0f;
   8042 	m_static_color_float[1] = float(m_static_color_byte[1]) / 255.0f;
   8043 	m_static_color_float[2] = float(m_static_color_byte[2]) / 255.0f;
   8044 	m_static_color_float[3] = float(m_static_color_byte[3]) / 255.0f;
   8045 }
   8046 
   8047 /** Verifies that texture/view & view/texture coherency requirement is met
   8048  *  when glTexSubImage2D() or glBlitFramebuffer() API calls are used to modify
   8049  *  the contents of one of the mip-maps. The function does not use any memory
   8050  *  barriers as these are not required for the objects to stay synchronised.
   8051  *
   8052  *  Throws TestError  exceptionif the GL implementation fails the check.
   8053  *
   8054  *  @param texture_type               Defines whether it should be parent texture or
   8055  *                                    its view that the writing operation should be
   8056  *                                    performed against. The reading operation will
   8057  *                                    be issued against the sibling object.
   8058  *  @param should_use_glTexSubImage2D true if glTexSubImage2D() should be used for the
   8059  *                                    check, false to use glBlitFramebuffer().
   8060  *
   8061  **/
   8062 void TextureViewTestCoherency::checkAPICallCoherency(_texture_type texture_type, bool should_use_glTexSubImage2D)
   8063 {
   8064 	const glw::Functions& gl			  = m_context.getRenderContext().getFunctions();
   8065 	unsigned int		  write_to_height = 0;
   8066 	unsigned int		  write_to_width  = 0;
   8067 	glw::GLuint			  write_to_id	 = 0;
   8068 
   8069 	getWritePropertiesForTextureType(texture_type, &write_to_id, &write_to_width, &write_to_height);
   8070 
   8071 	if (should_use_glTexSubImage2D)
   8072 	{
   8073 		/* Update texture binding for texture unit 0, given the texture type the caller wants
   8074 		 * us to test. We'll need the binding set appropriately for the subsequent
   8075 		 * glTexSubImage2D() call.
   8076 		 */
   8077 		gl.activeTexture(GL_TEXTURE0);
   8078 		GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
   8079 
   8080 		gl.bindTexture(GL_TEXTURE_2D, write_to_id);
   8081 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   8082 	}
   8083 	else
   8084 	{
   8085 		/* To perform a blit operation, we need to configure draw & read FBO, taking
   8086 		 * the tested texture type into account. */
   8087 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_draw_fbo_id);
   8088 		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
   8089 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call(s) failed.");
   8090 
   8091 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, write_to_id, 1); /* level */
   8092 		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed for GL_DRAW_FRAMEBUFFER target.");
   8093 
   8094 		gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_static_to_id,
   8095 								0); /* level */
   8096 		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed for GL_READ_FRAMEBUFFER target.");
   8097 	}
   8098 
   8099 	/* Execute the API call */
   8100 	const unsigned int region_width  = (write_to_width >> 1);
   8101 	const unsigned int region_height = (write_to_height >> 1);
   8102 	const unsigned int region_x		 = region_width - (region_width >> 1);
   8103 	const unsigned int region_y		 = region_height - (region_height >> 1);
   8104 
   8105 	if (should_use_glTexSubImage2D)
   8106 	{
   8107 		/* Call glTexSubImage2D() to replace a portion of the gradient with a static color */
   8108 		{
   8109 			unsigned char* static_color_data_ptr = getStaticColorTextureData(region_width, region_height);
   8110 
   8111 			gl.texSubImage2D(GL_TEXTURE_2D, 1, /* level */
   8112 							 region_x, region_y, region_width, region_height, GL_RGBA, GL_UNSIGNED_BYTE,
   8113 							 static_color_data_ptr);
   8114 
   8115 			/* Good to release static color data buffer at this point */
   8116 			delete[] static_color_data_ptr;
   8117 
   8118 			static_color_data_ptr = DE_NULL;
   8119 
   8120 			/* Make sure the API call was successful */
   8121 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
   8122 		}
   8123 	}
   8124 	else
   8125 	{
   8126 		gl.blitFramebuffer(0,						/* srcX0 */
   8127 						   0,						/* srcY0 */
   8128 						   m_static_texture_width,  /* srcX1 */
   8129 						   m_static_texture_height, /* srcY1 */
   8130 						   region_x, region_y, region_x + region_width, region_y + region_height, GL_COLOR_BUFFER_BIT,
   8131 						   GL_NEAREST);
   8132 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBlitFramebuffer() call failed.");
   8133 	}
   8134 
   8135 	/* Bind the sibling object so that we can make sure the data read from the
   8136 	 * region can be correctly read from a shader without a memory barrier.
   8137 	 *
   8138 	 * While we're here, also determine which LOD we should be sampling from in
   8139 	 * the shader.
   8140 	 **/
   8141 	unsigned int read_lod   = 0;
   8142 	glw::GLuint  read_to_id = 0;
   8143 
   8144 	getReadPropertiesForTextureType(texture_type, &read_to_id, &read_lod);
   8145 
   8146 	gl.bindTexture(GL_TEXTURE_2D, read_to_id);
   8147 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   8148 
   8149 	/* Update the test program uniforms before we carry on with actual
   8150 	 * verification
   8151 	 */
   8152 	gl.useProgram(m_verification_po_id);
   8153 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   8154 
   8155 	DE_STATIC_ASSERT(sizeof(m_static_color_float) == sizeof(float) * 4);
   8156 
   8157 	gl.uniform4fv(m_verification_po_expected_color_location, 1, /* count */
   8158 				  m_static_color_float);
   8159 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed.");
   8160 
   8161 	gl.uniform1i(m_verification_po_lod_location, read_lod);
   8162 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   8163 
   8164 	/* Make sure rasterization is disabled before we carry on */
   8165 	gl.enable(GL_RASTERIZER_DISCARD);
   8166 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed.");
   8167 
   8168 	/* Go ahead with the rendering. Make sure to capture the varyings */
   8169 	gl.beginTransformFeedback(GL_POINTS);
   8170 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
   8171 	{
   8172 		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   8173 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   8174 	}
   8175 	gl.endTransformFeedback();
   8176 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
   8177 
   8178 	/* Map the buffer object so we can validate the sampling result */
   8179 	const glw::GLint* data_ptr = (const glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   8180 
   8181 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   8182 	DE_ASSERT(data_ptr != NULL);
   8183 
   8184 	/* Verify the outcome of the sampling operation */
   8185 	if (*data_ptr != 1)
   8186 	{
   8187 		TCU_FAIL("Invalid data was sampled in vertex shader");
   8188 	}
   8189 
   8190 	/* Unmap the buffer object */
   8191 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   8192 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
   8193 
   8194 	data_ptr = DE_NULL;
   8195 
   8196 	/* Disable GL_RASTERIZER_DISCARD mode */
   8197 	gl.disable(GL_RASTERIZER_DISCARD);
   8198 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed.");
   8199 }
   8200 
   8201 /** Verifies texture/view & view/texture coherency is met when one of the objects
   8202  *  is used as a render-target. The function writes to user-specified texture type,
   8203  *  and then verifies the contents of the sibling object.
   8204  *
   8205  *  The function throws TestError exception if any of the checks fail.
   8206  *
   8207  *  @param texture_type      Tells which of the two objects should be written to.
   8208  *  @param should_use_images true if images should be used for
   8209  *  @param barrier_type      Type of the memory barrier that should be injected
   8210  *                           after vertex shader stage with image writes is executed.
   8211  *                           Must be BARRIER_TYPE_NONE if @param should_use_images
   8212  *                           is set to false.
   8213  *  @param verification_mean Determines whether the verification should be performed
   8214  *                           using a program object, or by CPU with the data
   8215  *                           extracted from the sibling object using a glGetTexImage()
   8216  *                           call.
   8217  *
   8218  **/
   8219 void TextureViewTestCoherency::checkProgramWriteCoherency(_texture_type texture_type, bool should_use_images,
   8220 														  _barrier_type		 barrier_type,
   8221 														  _verification_mean verification_mean)
   8222 {
   8223 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8224 
   8225 	if (!should_use_images)
   8226 	{
   8227 		/* Sanity check: no barrier should be requested if images are not used */
   8228 		DE_ASSERT(barrier_type == BARRIER_TYPE_NONE);
   8229 
   8230 		/* Sanity check: glGetTexImage*() call should only be used for verification
   8231 		 *               when images are used */
   8232 		DE_ASSERT(verification_mean == VERIFICATION_MEAN_PROGRAM);
   8233 	}
   8234 
   8235 	/* Determine GL id of an object we will be rendering the gradient to */
   8236 	glw::GLuint  write_to_id	 = 0;
   8237 	unsigned int write_to_width  = 0;
   8238 	unsigned int write_to_height = 0;
   8239 
   8240 	getWritePropertiesForTextureType(texture_type, &write_to_id, &write_to_width, &write_to_height);
   8241 
   8242 	/* Configure the render targets */
   8243 	if (should_use_images)
   8244 	{
   8245 		gl.bindImageTexture(0,				/* unit */
   8246 							write_to_id, 1, /* second level */
   8247 							GL_FALSE,		/* layered */
   8248 							0,				/* layer */
   8249 							GL_WRITE_ONLY, GL_RGBA8);
   8250 
   8251 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed.");
   8252 	}
   8253 	else
   8254 	{
   8255 		/* We first need to fill either the texture or its sibling view with
   8256 		 * gradient data. Set up draw framebuffer */
   8257 		gl.bindFramebuffer(GL_FRAMEBUFFER, m_draw_fbo_id);
   8258 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed for GL_FRAMEBUFFER target");
   8259 
   8260 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, write_to_id, 1); /* level */
   8261 		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
   8262 
   8263 		/* Configure the viewport accordingly */
   8264 		gl.viewport(0, /* x */
   8265 					0, /* y */
   8266 					write_to_width, write_to_height);
   8267 		GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
   8268 	}
   8269 
   8270 	/* The gradient needs to be rendered differently, depending on whether
   8271 	 * we're asked to use images or not */
   8272 	if (should_use_images)
   8273 	{
   8274 		gl.useProgram(m_gradient_image_write_po_id);
   8275 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   8276 
   8277 		gl.uniform2i(m_gradient_image_write_image_size_location, write_to_width, write_to_height);
   8278 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform2i() call failed.");
   8279 
   8280 		gl.enable(GL_RASTERIZER_DISCARD);
   8281 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
   8282 		{
   8283 			gl.drawArrays(GL_POINTS, 0 /* first */, write_to_width * write_to_height);
   8284 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   8285 		}
   8286 		gl.disable(GL_RASTERIZER_DISCARD);
   8287 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable(GL_RASTERIZER_DISCARD) call failed.");
   8288 
   8289 		/* If the caller requested any barriers, issue them at this point */
   8290 		switch (barrier_type)
   8291 		{
   8292 		case BARRIER_TYPE_TEXTURE_FETCH_BARRIER_BIT:
   8293 		{
   8294 			gl.memoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
   8295 
   8296 			GLU_EXPECT_NO_ERROR(gl.getError(),
   8297 								"glMemoryBarrier() call failed for GL_TEXTURE_FETCH_BARRIER_BIT barrier");
   8298 
   8299 			break;
   8300 		}
   8301 
   8302 		case BARRIER_TYPE_TEXTURE_UPDATE_BUFFER_BIT:
   8303 		{
   8304 			gl.memoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
   8305 
   8306 			GLU_EXPECT_NO_ERROR(gl.getError(),
   8307 								"glMemoryBarrier() call failed for GL_TEXTURE_UPDATE_BARRIER_BIT barrier");
   8308 
   8309 			break;
   8310 		}
   8311 
   8312 		default:
   8313 		{
   8314 			TCU_FAIL("Unrecognized barrier type");
   8315 		}
   8316 		} /* switch (barrier_type) */
   8317 	}	 /* if (should_use_images) */
   8318 	else
   8319 	{
   8320 		/* Render the gradient on a full-screen quad */
   8321 		gl.useProgram(m_gradient_write_po_id);
   8322 		GLU_EXPECT_NO_ERROR(gl.getError(), "gluseProgram() call failed.");
   8323 
   8324 		gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
   8325 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   8326 	}
   8327 
   8328 	/* Determine which texture and which mip-map level we will need to sample
   8329 	 * in order to verify whether the former operations have been completed
   8330 	 * successfully.
   8331 	 **/
   8332 	unsigned int read_lod   = 0;
   8333 	glw::GLuint  read_to_id = 0;
   8334 
   8335 	getReadPropertiesForTextureType(texture_type, &read_to_id, &read_lod);
   8336 
   8337 	/* Before we proceed with verification, update the texture binding so that
   8338 	 * the verification program can sample from the right texture */
   8339 	gl.activeTexture(GL_TEXTURE0);
   8340 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
   8341 
   8342 	gl.bindTexture(GL_TEXTURE_2D, read_to_id);
   8343 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   8344 
   8345 	if (verification_mean == VERIFICATION_MEAN_PROGRAM)
   8346 	{
   8347 		/* Switch to a verification program. It uses a vertex shader to sample
   8348 		 * all texels of the texture so issue as many invocations as necessary. */
   8349 		unsigned int n_invocations = write_to_width * write_to_height;
   8350 
   8351 		gl.useProgram(m_gradient_verification_po_id);
   8352 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   8353 
   8354 		gl.uniform1i(m_gradient_verification_po_texture_location, 0);
   8355 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   8356 
   8357 		gl.uniform1i(m_gradient_verification_po_sample_exact_uv_location, should_use_images);
   8358 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   8359 
   8360 		gl.uniform1f(m_gradient_verification_po_lod_location, (float)read_lod);
   8361 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed.");
   8362 
   8363 		gl.enable(GL_RASTERIZER_DISCARD);
   8364 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
   8365 
   8366 		gl.beginTransformFeedback(GL_POINTS);
   8367 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
   8368 		{
   8369 			gl.drawArrays(GL_POINTS, 0 /* first */, n_invocations);
   8370 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   8371 		}
   8372 		gl.endTransformFeedback();
   8373 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
   8374 
   8375 		gl.disable(GL_RASTERIZER_DISCARD);
   8376 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable(GL_RASTERIZER_DISCARD) call failed.");
   8377 
   8378 		/* Map the result buffer object storage into process space */
   8379 		const int* result_data_ptr = (const int*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   8380 
   8381 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   8382 
   8383 		if (result_data_ptr == DE_NULL)
   8384 		{
   8385 			TCU_FAIL("glMapBuffer() did not generate an error but returned a NULL pointer");
   8386 		}
   8387 
   8388 		/* Verify the XFBed data */
   8389 		for (unsigned int n_invocation = 0; n_invocation < n_invocations; ++n_invocation)
   8390 		{
   8391 			if (result_data_ptr[n_invocation] != 1)
   8392 			{
   8393 				unsigned int invocation_x = n_invocation % write_to_width;
   8394 				unsigned int invocation_y = n_invocation / write_to_width;
   8395 
   8396 				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled at "
   8397 								   << "(" << invocation_x << ", " << invocation_y << ") when sampling from "
   8398 								   << ((texture_type == TEXTURE_TYPE_PARENT_TEXTURE) ? "a texture" : "a view")
   8399 								   << tcu::TestLog::EndMessage;
   8400 
   8401 				/* Make sure the buffer is unmapped before throwing the exception */
   8402 				gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   8403 
   8404 				TCU_FAIL("Invalid data sampled");
   8405 			}
   8406 		} /* for (all invocations) */
   8407 
   8408 		/* Unmap the buffer storage */
   8409 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   8410 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
   8411 	} /* if (verification_mean == VERIFICATION_MEAN_PROGRAM) */
   8412 	else
   8413 	{
   8414 		DE_ASSERT(verification_mean == VERIFICATION_MEAN_GLGETTEXIMAGE);
   8415 
   8416 		/* Allocate space for the data */
   8417 		unsigned char* data_ptr = new unsigned char[write_to_width * write_to_height * m_texture_n_components];
   8418 
   8419 		/* Retrieve the rendered data */
   8420 		gl.getTexImage(GL_TEXTURE_2D, read_lod, GL_RGBA, GL_UNSIGNED_BYTE, data_ptr);
   8421 
   8422 		if (gl.getError() != GL_NO_ERROR)
   8423 		{
   8424 			/* Release the buffer before we throw an exception */
   8425 			delete[] data_ptr;
   8426 
   8427 			TCU_FAIL("glGetTexImage() call failed.");
   8428 		}
   8429 
   8430 		/* Verify the data is correct */
   8431 		const int epsilon		  = 1;
   8432 		bool	  is_data_correct = true;
   8433 
   8434 		for (unsigned int y = 0; y < write_to_height; ++y)
   8435 		{
   8436 			const unsigned char* row_ptr = data_ptr + y * m_texture_n_components * write_to_width;
   8437 
   8438 			for (unsigned int x = 0; x < write_to_width; ++x)
   8439 			{
   8440 				const unsigned char* texel_ptr	= row_ptr + x * m_texture_n_components;
   8441 				const float			 end_rgba[]   = { 0.0f, 0.1f, 1.0f, 1.0f };
   8442 				const float			 lerp_factor  = float(x) / float(write_to_width);
   8443 				const float			 start_rgba[] = { 1.0f, 0.9f, 0.0f, 0.0f };
   8444 				const float expected_data_float[] = { start_rgba[0] * (1.0f - lerp_factor) + end_rgba[0] * lerp_factor,
   8445 													  start_rgba[1] * (1.0f - lerp_factor) + end_rgba[1] * lerp_factor,
   8446 													  start_rgba[2] * (1.0f - lerp_factor) + end_rgba[2] * lerp_factor,
   8447 													  start_rgba[3] * (1.0f - lerp_factor) +
   8448 														  end_rgba[3] * lerp_factor };
   8449 				const unsigned char expected_data_ubyte[] = { (unsigned char)(expected_data_float[0] * 255.0f),
   8450 															  (unsigned char)(expected_data_float[1] * 255.0f),
   8451 															  (unsigned char)(expected_data_float[2] * 255.0f),
   8452 															  (unsigned char)(expected_data_float[3] * 255.0f) };
   8453 
   8454 				if (de::abs((int)texel_ptr[0] - (int)expected_data_ubyte[0]) > epsilon ||
   8455 					de::abs((int)texel_ptr[1] - (int)expected_data_ubyte[1]) > epsilon ||
   8456 					de::abs((int)texel_ptr[2] - (int)expected_data_ubyte[2]) > epsilon ||
   8457 					de::abs((int)texel_ptr[3] - (int)expected_data_ubyte[3]) > epsilon)
   8458 				{
   8459 					is_data_correct = false;
   8460 
   8461 					break;
   8462 				}
   8463 			}
   8464 		} /* for (all rows) */
   8465 
   8466 		/* Good to release the data buffer at this point */
   8467 		delete[] data_ptr;
   8468 
   8469 		data_ptr = DE_NULL;
   8470 
   8471 		/* Fail the test if any of the rendered texels were found invalid */
   8472 		if (!is_data_correct)
   8473 		{
   8474 			TCU_FAIL("Invalid data sampled");
   8475 		}
   8476 	}
   8477 }
   8478 
   8479 /** Deinitializes all GL objects that may have been created during
   8480  *  test execution.
   8481  **/
   8482 void TextureViewTestCoherency::deinit()
   8483 {
   8484 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8485 
   8486 	/* Release any GL objects the test may have created */
   8487 	if (m_bo_id != 0)
   8488 	{
   8489 		gl.deleteBuffers(1, &m_bo_id);
   8490 
   8491 		m_bo_id = 0;
   8492 	}
   8493 
   8494 	if (m_draw_fbo_id != 0)
   8495 	{
   8496 		gl.deleteFramebuffers(1, &m_draw_fbo_id);
   8497 
   8498 		m_draw_fbo_id = 0;
   8499 	}
   8500 
   8501 	if (m_gradient_image_write_po_id != 0)
   8502 	{
   8503 		gl.deleteProgram(m_gradient_image_write_po_id);
   8504 
   8505 		m_gradient_image_write_po_id = 0;
   8506 	}
   8507 
   8508 	if (m_gradient_image_write_vs_id != 0)
   8509 	{
   8510 		gl.deleteShader(m_gradient_image_write_vs_id);
   8511 
   8512 		m_gradient_image_write_vs_id = 0;
   8513 	}
   8514 
   8515 	if (m_gradient_verification_po_id != 0)
   8516 	{
   8517 		gl.deleteProgram(m_gradient_verification_po_id);
   8518 
   8519 		m_gradient_verification_po_id = 0;
   8520 	}
   8521 
   8522 	if (m_gradient_verification_vs_id != 0)
   8523 	{
   8524 		gl.deleteShader(m_gradient_verification_vs_id);
   8525 
   8526 		m_gradient_verification_vs_id = 0;
   8527 	}
   8528 
   8529 	if (m_gradient_write_fs_id != 0)
   8530 	{
   8531 		gl.deleteShader(m_gradient_write_fs_id);
   8532 
   8533 		m_gradient_write_fs_id = 0;
   8534 	}
   8535 
   8536 	if (m_gradient_write_po_id != 0)
   8537 	{
   8538 		gl.deleteProgram(m_gradient_write_po_id);
   8539 
   8540 		m_gradient_write_po_id = 0;
   8541 	}
   8542 
   8543 	if (m_gradient_write_vs_id != 0)
   8544 	{
   8545 		gl.deleteShader(m_gradient_write_vs_id);
   8546 
   8547 		m_gradient_write_vs_id = 0;
   8548 	}
   8549 
   8550 	if (m_read_fbo_id != 0)
   8551 	{
   8552 		gl.deleteFramebuffers(1, &m_read_fbo_id);
   8553 
   8554 		m_read_fbo_id = 0;
   8555 	}
   8556 
   8557 	if (m_static_to_id != 0)
   8558 	{
   8559 		gl.deleteTextures(1, &m_static_to_id);
   8560 
   8561 		m_static_to_id = 0;
   8562 	}
   8563 
   8564 	if (m_to_id != 0)
   8565 	{
   8566 		gl.deleteTextures(1, &m_to_id);
   8567 
   8568 		m_to_id = 0;
   8569 	}
   8570 
   8571 	if (m_vao_id != 0)
   8572 	{
   8573 		gl.deleteVertexArrays(1, &m_vao_id);
   8574 
   8575 		m_vao_id = 0;
   8576 	}
   8577 
   8578 	if (m_view_to_id != 0)
   8579 	{
   8580 		gl.deleteTextures(1, &m_view_to_id);
   8581 
   8582 		m_view_to_id = 0;
   8583 	}
   8584 
   8585 	if (m_verification_po_id != 0)
   8586 	{
   8587 		gl.deleteProgram(m_verification_po_id);
   8588 
   8589 		m_verification_po_id = 0;
   8590 	}
   8591 
   8592 	if (m_verification_vs_id != 0)
   8593 	{
   8594 		gl.deleteShader(m_verification_vs_id);
   8595 
   8596 		m_verification_vs_id = 0;
   8597 	}
   8598 
   8599 	/* Disable GL_RASTERIZER_DISCARD mode */
   8600 	gl.disable(GL_RASTERIZER_DISCARD);
   8601 }
   8602 
   8603 /** Allocates a sufficiently large buffer for RGBA8 data and fills it with
   8604  *  a horizontal gradient (as described in the test specification)
   8605  *
   8606  *  It is user's responsibility to release the buffer when no longer needed.
   8607  *
   8608  *  @return Pointer to the buffer.
   8609  **/
   8610 unsigned char* TextureViewTestCoherency::getHorizontalGradientData() const
   8611 {
   8612 	const float		   end_rgba[]   = { 1.0f, 0.9f, 0.0f, 0.0f };
   8613 	unsigned char*	 result		= new unsigned char[m_texture_width * m_texture_height * m_texture_n_components];
   8614 	const float		   start_rgba[] = { 0.0f, 0.1f, 1.0f, 1.0f };
   8615 	const unsigned int texel_size   = m_texture_n_components;
   8616 
   8617 	for (unsigned int y = 0; y < m_texture_height; ++y)
   8618 	{
   8619 		unsigned char* row_data_ptr = result + texel_size * m_texture_width * y;
   8620 
   8621 		for (unsigned int x = 0; x < m_texture_width; ++x)
   8622 		{
   8623 			const float	lerp_factor	= float(x) / float(m_texture_width);
   8624 			unsigned char* pixel_data_ptr = row_data_ptr + texel_size * x;
   8625 
   8626 			for (unsigned int n_component = 0; n_component < 4 /* rgba */; ++n_component)
   8627 			{
   8628 				pixel_data_ptr[n_component] = (unsigned char)((end_rgba[n_component] * lerp_factor +
   8629 															   start_rgba[n_component] * (1.0f - lerp_factor)) *
   8630 															  255.0f);
   8631 			} /* for (all components) */
   8632 		}	 /* for (all columns) */
   8633 	}		  /* for (all rows) */
   8634 
   8635 	return result;
   8636 }
   8637 
   8638 /** Retrieves properties of a sibling object that should be read from during
   8639  *  some of the checks.
   8640  *
   8641  *  @param texture_type Type of the texture object that should be used for reading.
   8642  *  @param out_to_id    Deref will be used to store texture object ID of the object.
   8643  *  @param out_read_lod Deref will be used to store LOD to be used for reading from
   8644  *                      the object.
   8645  *
   8646  **/
   8647 void TextureViewTestCoherency::getReadPropertiesForTextureType(_texture_type texture_type, glw::GLuint* out_to_id,
   8648 															   unsigned int* out_read_lod) const
   8649 {
   8650 	switch (texture_type)
   8651 	{
   8652 	case TEXTURE_TYPE_PARENT_TEXTURE:
   8653 	{
   8654 		*out_to_id = m_view_to_id;
   8655 
   8656 		/* We've modified LOD1 of parent texture which corresponds
   8657 		 * to LOD 0 from the view's PoV
   8658 		 */
   8659 		*out_read_lod = 0;
   8660 
   8661 		break;
   8662 	}
   8663 
   8664 	case TEXTURE_TYPE_TEXTURE_VIEW:
   8665 	{
   8666 		*out_to_id = m_to_id;
   8667 
   8668 		/* We've modified LOD1 of the view texture which corresponds
   8669 		 * to LOD2 from parent texture's PoV.
   8670 		 */
   8671 		*out_read_lod = 2;
   8672 
   8673 		break;
   8674 	}
   8675 
   8676 	default:
   8677 	{
   8678 		TCU_FAIL("Unrecognized read source");
   8679 	}
   8680 	} /* switch (texture_type) */
   8681 }
   8682 
   8683 /** Allocates a sufficiently large buffer to hold RGBA8 data of user-specified resolution
   8684  *  and fills it with a static color (as described in the test specification)
   8685  *
   8686  *  It is caller's responsibility to release the returned buffer when it's no longer
   8687  *  needed.
   8688  *
   8689  *  @param width  Width of the mip-map the buffer will be used as a data source for;
   8690  *  @param height Height of the mip-map the buffer will be used as a data source for;
   8691  *
   8692  *  @return Pointer to the buffer.
   8693  **/
   8694 unsigned char* TextureViewTestCoherency::getStaticColorTextureData(unsigned int width, unsigned int height) const
   8695 {
   8696 	/* Prepare the data buffer storing the data we want to replace the region of the
   8697 	 * data source with.
   8698 	 */
   8699 	unsigned char* result_ptr = new unsigned char[width * height * m_texture_n_components];
   8700 
   8701 	for (unsigned int y = 0; y < height; ++y)
   8702 	{
   8703 		unsigned char* row_data_ptr = result_ptr + y * width * m_texture_n_components;
   8704 
   8705 		for (unsigned int x = 0; x < width; ++x)
   8706 		{
   8707 			unsigned char* pixel_data_ptr = row_data_ptr + x * m_texture_n_components;
   8708 
   8709 			memcpy(pixel_data_ptr, m_static_color_byte, sizeof(m_static_color_byte));
   8710 		} /* for (all columns) */
   8711 	}	 /* for (all rows) */
   8712 
   8713 	return result_ptr;
   8714 }
   8715 
   8716 /** Retrieves properties of a parent texture object that should be written to during
   8717  *  some of the checks.
   8718  *
   8719  *  @param texture_type Type of the texture object that should be used for writing.
   8720  *  @param out_to_id    Deref will be used to store texture object ID of the object. Must not be NULL.
   8721  *  @param out_width    Deref will be used to store width of the mip-map the test will
   8722  *                      be writing to; Must not be NULL.
   8723  *  @param out_height   Deref will be used to store height of the mip-map the test will
   8724  *                      be writing to. Must not be NULL.
   8725  *
   8726  **/
   8727 void TextureViewTestCoherency::getWritePropertiesForTextureType(_texture_type texture_type, glw::GLuint* out_to_id,
   8728 																unsigned int* out_width, unsigned int* out_height) const
   8729 {
   8730 	DE_ASSERT(out_to_id != DE_NULL);
   8731 	DE_ASSERT(out_width != DE_NULL);
   8732 	DE_ASSERT(out_height != DE_NULL);
   8733 
   8734 	/* All tests will be attempting to modify layer 1 of either the texture
   8735 	 * or its sibling view. For views, the resolution is therefore going to
   8736 	 * be 16x16 (because the base resolution is 32x32, as the view uses a mipmap
   8737 	 * range of 1 to 2 inclusive); for parent texture, this will be 32x32 (as the base
   8738 	 * mip-map is 64x64)
   8739 	 */
   8740 	switch (texture_type)
   8741 	{
   8742 	case TEXTURE_TYPE_PARENT_TEXTURE:
   8743 	{
   8744 		*out_to_id  = m_to_id;
   8745 		*out_width  = m_texture_width >> 1;
   8746 		*out_height = m_texture_height >> 1;
   8747 
   8748 		break;
   8749 	}
   8750 
   8751 	case TEXTURE_TYPE_TEXTURE_VIEW:
   8752 	{
   8753 		*out_to_id  = m_view_to_id;
   8754 		*out_width  = m_texture_width >> 2;
   8755 		*out_height = m_texture_height >> 2;
   8756 
   8757 		break;
   8758 	}
   8759 
   8760 	default:
   8761 	{
   8762 		TCU_FAIL("Unrecognized texture type");
   8763 	}
   8764 	} /* switch (texture_type) */
   8765 }
   8766 
   8767 /** Initializes buffer objects that will be used during the test.
   8768  *
   8769  *  Throws exceptions if the initialization fails at any point.
   8770  **/
   8771 void TextureViewTestCoherency::initBufferObjects()
   8772 {
   8773 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8774 
   8775 	/* Generate and configure buffer object storage */
   8776 	gl.genBuffers(1, &m_bo_id);
   8777 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
   8778 
   8779 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
   8780 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   8781 
   8782 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
   8783 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
   8784 
   8785 	/* Case 1) needs the BO to hold just a single int.
   8786 	 * Case 3) needs one int per result texel.
   8787 	 *
   8788 	 * Allocate enough space to handle all the cases.
   8789 	 **/
   8790 	glw::GLint bo_size = static_cast<glw::GLint>((m_texture_height >> 1) * (m_texture_width >> 1) * sizeof(int));
   8791 
   8792 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL, /* data */
   8793 				  GL_STATIC_DRAW);
   8794 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferdata() call failed.");
   8795 }
   8796 
   8797 /** Initializes framebuffer objects that will be used during the test.
   8798  *
   8799  *  Throws exceptions if the initialization fails at any point.
   8800  **/
   8801 void TextureViewTestCoherency::initFBO()
   8802 {
   8803 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8804 
   8805 	/* Generate framebuffer object(s) */
   8806 	gl.genFramebuffers(1, &m_draw_fbo_id);
   8807 	gl.genFramebuffers(1, &m_read_fbo_id);
   8808 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
   8809 }
   8810 
   8811 /** Initializes program objects that will be used during the test.
   8812  *
   8813  *  This method will throw exceptions if either compilation or linking of
   8814  *  any of the processed shaders/programs fails.
   8815  *
   8816  **/
   8817 void TextureViewTestCoherency::initPrograms()
   8818 {
   8819 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8820 
   8821 	/* The test uses images in vertex shader stage. Make sure this is actually supported by
   8822 	 * the implementation */
   8823 	m_are_images_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_image_load_store");
   8824 
   8825 	if (m_are_images_supported)
   8826 	{
   8827 		glw::GLint gl_max_vertex_image_uniforms_value = 0;
   8828 
   8829 		gl.getIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &gl_max_vertex_image_uniforms_value);
   8830 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_VERTEX_IMAGE_UNIFORM pname");
   8831 
   8832 		if (gl_max_vertex_image_uniforms_value < 1)
   8833 		{
   8834 			m_testCtx.getLog() << tcu::TestLog::Message
   8835 							   << "Image support will not be tested by view_parent_texture_coherency, as"
   8836 								  "the implementation does not support image uniforms in vertex shader stage."
   8837 							   << tcu::TestLog::EndMessage;
   8838 
   8839 			/* We cannot execute the test on this platform */
   8840 			m_are_images_supported = false;
   8841 		}
   8842 	} /* if (m_are_images_supported) */
   8843 
   8844 	/* Create program objects */
   8845 	if (m_are_images_supported)
   8846 	{
   8847 		m_gradient_image_write_po_id = gl.createProgram();
   8848 	}
   8849 
   8850 	m_gradient_verification_po_id = gl.createProgram();
   8851 	m_gradient_write_po_id		  = gl.createProgram();
   8852 	m_verification_po_id		  = gl.createProgram();
   8853 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
   8854 
   8855 	/* Create fragment shader objects */
   8856 	m_gradient_write_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
   8857 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed for GL_FRAGMENT_SHADER type");
   8858 
   8859 	/* Create vertex shader objects */
   8860 	if (m_are_images_supported)
   8861 	{
   8862 		m_gradient_image_write_vs_id = gl.createShader(GL_VERTEX_SHADER);
   8863 	}
   8864 
   8865 	m_gradient_verification_vs_id = gl.createShader(GL_VERTEX_SHADER);
   8866 	m_gradient_write_vs_id		  = gl.createShader(GL_VERTEX_SHADER);
   8867 	m_verification_vs_id		  = gl.createShader(GL_VERTEX_SHADER);
   8868 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed for GL_VERTEX_SHADER type.");
   8869 
   8870 	/* Set gradient verification program's fragment shader body */
   8871 	const char* gradient_verification_vs_body =
   8872 		"#version 400\n"
   8873 		"\n"
   8874 		"out int result;\n"
   8875 		"\n"
   8876 		"uniform float     lod;\n"
   8877 		"uniform bool      sample_exact_uv;\n"
   8878 		"uniform sampler2D texture;\n"
   8879 		"\n"
   8880 		"void main()\n"
   8881 		"{\n"
   8882 		"    const float epsilon    = 1.0 / 255.0;\n"
   8883 		"    const vec4  end_rgba   = vec4(0.0, 0.1, 1.0, 1.0);\n"
   8884 		"    const vec4  start_rgba = vec4(1.0, 0.9, 0.0, 0.0);\n"
   8885 		"\n"
   8886 		"    ivec2 texture_size   = textureSize(texture, int(lod) );\n"
   8887 		"    vec2  uv             = vec2(      float(gl_VertexID % texture_size.x) / float(texture_size.x),\n"
   8888 		"                                1.0 - float(gl_VertexID / texture_size.x) / float(texture_size.y) );\n"
   8889 		"    vec4  expected_color;\n"
   8890 		"    vec4  texture_color  = textureLod(texture, uv, lod);\n"
   8891 		"\n"
   8892 		"    if (sample_exact_uv)\n"
   8893 		"    {\n"
   8894 		"        expected_color = mix(start_rgba, end_rgba, uv.x);\n"
   8895 		"    }\n"
   8896 		"    else\n"
   8897 		"    {\n"
   8898 		"        expected_color = mix(start_rgba, end_rgba, uv.x + 0.5/float(texture_size.x) );\n"
   8899 		"    }\n"
   8900 		"\n"
   8901 		"\n"
   8902 		"    if (abs(texture_color.x - expected_color.x) > epsilon ||\n"
   8903 		"        abs(texture_color.y - expected_color.y) > epsilon ||\n"
   8904 		"        abs(texture_color.z - expected_color.z) > epsilon ||\n"
   8905 		"        abs(texture_color.w - expected_color.w) > epsilon)\n"
   8906 		"    {\n"
   8907 		"        result = int( texture_color.y * 255.0);\n"
   8908 		"    }\n"
   8909 		"    else\n"
   8910 		"    {\n"
   8911 		"        result = 1;\n"
   8912 		"    }\n"
   8913 		"}\n";
   8914 
   8915 	gl.shaderSource(m_gradient_verification_vs_id, 1 /* count */, &gradient_verification_vs_body, NULL /* length */);
   8916 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   8917 
   8918 	/* Set gradient write (for images) program's vertex shader body */
   8919 	if (m_are_images_supported)
   8920 	{
   8921 		const char* gradient_write_image_vs_body =
   8922 			"#version 400\n"
   8923 			"\n"
   8924 			"#extension GL_ARB_shader_image_load_store : require\n"
   8925 			"\n"
   8926 			"layout(rgba8) uniform image2D image;\n"
   8927 			"              uniform ivec2   image_size;\n"
   8928 			"\n"
   8929 			"void main()\n"
   8930 			"{\n"
   8931 			"    const  vec4 end_rgba   =  vec4(0.0, 0.1, 1.0, 1.0);\n"
   8932 			"    const  vec4 start_rgba =  vec4(1.0, 0.9, 0.0, 0.0);\n"
   8933 			"          ivec2 xy         = ivec2(gl_VertexID % image_size.x,              gl_VertexID / image_size.x);\n"
   8934 			"           vec2 uv         =  vec2(float(xy.x) / float(image_size.x), 1.0 - float(xy.y) / "
   8935 			"float(image_size.y) );\n"
   8936 			"          vec4  result     = mix  (start_rgba, end_rgba, uv.x);\n"
   8937 			"\n"
   8938 			"    imageStore(image, xy, result);\n"
   8939 			"}\n";
   8940 
   8941 		gl.shaderSource(m_gradient_image_write_vs_id, 1 /* count */, &gradient_write_image_vs_body, NULL /* length */);
   8942 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   8943 	}
   8944 
   8945 	/* Set gradient write program's fragment shader body */
   8946 	const char* gradient_write_fs_body = "#version 400\n"
   8947 										 "\n"
   8948 										 "in vec2 uv;\n"
   8949 										 "\n"
   8950 										 "layout(location = 0) out vec4 result;\n"
   8951 										 "\n"
   8952 										 "void main()\n"
   8953 										 "{\n"
   8954 										 "    const vec4 end_rgba   = vec4(0.0, 0.1, 1.0, 1.0);\n"
   8955 										 "    const vec4 start_rgba = vec4(1.0, 0.9, 0.0, 0.0);\n"
   8956 										 "\n"
   8957 										 "    result = mix(start_rgba, end_rgba, uv.x);\n"
   8958 										 "}\n";
   8959 
   8960 	gl.shaderSource(m_gradient_write_fs_id, 1 /* count */, &gradient_write_fs_body, NULL /* length */);
   8961 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   8962 
   8963 	/* Set gradient write program's vertex shader body */
   8964 	const char* gradient_write_vs_body =
   8965 		"#version 400\n"
   8966 		"\n"
   8967 		"out vec2 uv;\n"
   8968 		"\n"
   8969 		"void main()\n"
   8970 		"{\n"
   8971 		"    switch (gl_VertexID)\n"
   8972 		"    {\n"
   8973 		"        case 0: gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); uv = vec2(0.0, 1.0); break;\n"
   8974 		"        case 1: gl_Position = vec4(-1.0,  1.0, 0.0, 1.0); uv = vec2(0.0, 0.0); break;\n"
   8975 		"        case 2: gl_Position = vec4( 1.0, -1.0, 0.0, 1.0); uv = vec2(1.0, 1.0); break;\n"
   8976 		"        case 3: gl_Position = vec4( 1.0,  1.0, 0.0, 1.0); uv = vec2(1.0, 0.0); break;\n"
   8977 		"    }\n"
   8978 		"}\n";
   8979 
   8980 	gl.shaderSource(m_gradient_write_vs_id, 1 /* count */, &gradient_write_vs_body, NULL /* length */);
   8981 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   8982 
   8983 	/* Set verification program's vertex shader body */
   8984 	const char* verification_vs_body = "#version 400\n"
   8985 									   "\n"
   8986 									   "uniform vec4      expected_color;\n"
   8987 									   "uniform int       lod;\n"
   8988 									   "uniform sampler2D sampler;\n"
   8989 									   "\n"
   8990 									   "out int result;\n"
   8991 									   "\n"
   8992 									   "void main()\n"
   8993 									   "{\n"
   8994 									   "    const float epsilon = 1.0 / 256.0;\n"
   8995 									   "\n"
   8996 									   "    vec4 sampled_data = textureLod(sampler, vec2(0.5, 0.5), lod);\n"
   8997 									   "\n"
   8998 									   "    if (abs(sampled_data.x - expected_color.x) > epsilon ||\n"
   8999 									   "        abs(sampled_data.y - expected_color.y) > epsilon ||\n"
   9000 									   "        abs(sampled_data.z - expected_color.z) > epsilon ||\n"
   9001 									   "        abs(sampled_data.w - expected_color.w) > epsilon)\n"
   9002 									   "    {\n"
   9003 									   "        result = 0;\n"
   9004 									   "    }\n"
   9005 									   "    else\n"
   9006 									   "    {\n"
   9007 									   "        result = 1;\n"
   9008 									   "    }\n"
   9009 									   "}\n";
   9010 
   9011 	gl.shaderSource(m_verification_vs_id, 1 /* count */, &verification_vs_body, NULL /* length */);
   9012 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   9013 
   9014 	/* Compile the shaders */
   9015 	const glw::GLuint so_ids[] = { m_gradient_image_write_vs_id, m_gradient_verification_vs_id, m_gradient_write_fs_id,
   9016 								   m_gradient_write_vs_id, m_verification_vs_id };
   9017 	const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
   9018 
   9019 	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
   9020 	{
   9021 		glw::GLuint so_id = so_ids[n_so_id];
   9022 
   9023 		if (so_id != 0)
   9024 		{
   9025 			gl.compileShader(so_id);
   9026 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   9027 
   9028 			/* Verify the compilation ended successfully */
   9029 			glw::GLint compile_status = GL_FALSE;
   9030 
   9031 			gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
   9032 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   9033 
   9034 			if (compile_status != GL_TRUE)
   9035 			{
   9036 				TCU_FAIL("Shader compilation failed.");
   9037 			}
   9038 		}
   9039 	} /* for (all shader objects) */
   9040 
   9041 	/* Attach the shaders to relevant programs */
   9042 	if (m_are_images_supported)
   9043 	{
   9044 		gl.attachShader(m_gradient_image_write_po_id, m_gradient_image_write_vs_id);
   9045 	}
   9046 
   9047 	gl.attachShader(m_gradient_verification_po_id, m_gradient_verification_vs_id);
   9048 	gl.attachShader(m_gradient_write_po_id, m_gradient_write_fs_id);
   9049 	gl.attachShader(m_gradient_write_po_id, m_gradient_write_vs_id);
   9050 	gl.attachShader(m_verification_po_id, m_verification_vs_id);
   9051 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
   9052 
   9053 	/* Set up XFB */
   9054 	const char*		  verification_varying_name = "result";
   9055 	const glw::GLuint xfb_po_ids[]				= {
   9056 		m_gradient_verification_po_id, m_verification_po_id,
   9057 	};
   9058 	const unsigned int n_xfb_po_ids = sizeof(xfb_po_ids) / sizeof(xfb_po_ids[0]);
   9059 
   9060 	for (unsigned int n_xfb_po_id = 0; n_xfb_po_id < n_xfb_po_ids; ++n_xfb_po_id)
   9061 	{
   9062 		glw::GLint po_id = xfb_po_ids[n_xfb_po_id];
   9063 
   9064 		gl.transformFeedbackVaryings(po_id, 1 /* count */, &verification_varying_name, GL_INTERLEAVED_ATTRIBS);
   9065 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
   9066 	}
   9067 
   9068 	/* Link the programs */
   9069 	const glw::GLuint po_ids[] = { m_gradient_image_write_po_id, m_gradient_verification_po_id, m_gradient_write_po_id,
   9070 								   m_verification_po_id };
   9071 	const unsigned int n_po_ids = sizeof(po_ids) / sizeof(po_ids[0]);
   9072 
   9073 	for (unsigned int n_po_id = 0; n_po_id < n_po_ids; ++n_po_id)
   9074 	{
   9075 		glw::GLuint po_id = po_ids[n_po_id];
   9076 
   9077 		if (po_id != 0)
   9078 		{
   9079 			gl.linkProgram(po_id);
   9080 			GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   9081 
   9082 			/* Make sure the linking was successful. */
   9083 			glw::GLint link_status = GL_FALSE;
   9084 
   9085 			gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);
   9086 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   9087 
   9088 			if (link_status != GL_TRUE)
   9089 			{
   9090 				TCU_FAIL("Program linking failed.");
   9091 			}
   9092 		}
   9093 	} /* for (all program objects) */
   9094 
   9095 	/* Retrieve uniform locations for gradient write program (image case) */
   9096 	if (m_are_images_supported)
   9097 	{
   9098 		m_gradient_image_write_image_size_location = gl.getUniformLocation(m_gradient_image_write_po_id, "image_size");
   9099 
   9100 		if (m_gradient_image_write_image_size_location == -1)
   9101 		{
   9102 			TCU_FAIL("image_size is considered an inactive uniform which is invalid.");
   9103 		}
   9104 	}
   9105 
   9106 	/* Retrieve uniform locations for gradient verification program */
   9107 	m_gradient_verification_po_sample_exact_uv_location =
   9108 		gl.getUniformLocation(m_gradient_verification_po_id, "sample_exact_uv");
   9109 	m_gradient_verification_po_lod_location		= gl.getUniformLocation(m_gradient_verification_po_id, "lod");
   9110 	m_gradient_verification_po_texture_location = gl.getUniformLocation(m_gradient_verification_po_id, "texture");
   9111 
   9112 	if (m_gradient_verification_po_sample_exact_uv_location == -1)
   9113 	{
   9114 		TCU_FAIL("sample_exact_uv is considered an inactive uniform which is invalid");
   9115 	}
   9116 
   9117 	if (m_gradient_verification_po_lod_location == -1)
   9118 	{
   9119 		TCU_FAIL("lod is considered an inactive uniform which is invalid.");
   9120 	}
   9121 
   9122 	if (m_gradient_verification_po_texture_location == -1)
   9123 	{
   9124 		TCU_FAIL("texture is considered an inactive uniform which is invalid.");
   9125 	}
   9126 
   9127 	/* Retrieve uniform locations for verification program */
   9128 	m_verification_po_expected_color_location = gl.getUniformLocation(m_verification_po_id, "expected_color");
   9129 	m_verification_po_lod_location			  = gl.getUniformLocation(m_verification_po_id, "lod");
   9130 
   9131 	if (m_verification_po_expected_color_location == -1)
   9132 	{
   9133 		TCU_FAIL("expected_color is considered an inactive uniform which is invalid.");
   9134 	}
   9135 
   9136 	if (m_verification_po_lod_location == -1)
   9137 	{
   9138 		TCU_FAIL("lod is considered an inactive uniform which is invalid.");
   9139 	}
   9140 }
   9141 
   9142 /** Initializes texture objects required to run the test.
   9143  *
   9144  *  Throws exceptions if the initialization fails at any point.
   9145  **/
   9146 void TextureViewTestCoherency::initTextures()
   9147 {
   9148 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9149 
   9150 	/* Generate the texture objects */
   9151 	gl.genTextures(1, &m_static_to_id);
   9152 	gl.genTextures(1, &m_to_id);
   9153 	gl.genTextures(1, &m_view_to_id);
   9154 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed.");
   9155 
   9156 	/* Set up parent texture object */
   9157 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
   9158 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   9159 
   9160 	gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height);
   9161 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   9162 
   9163 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   9164 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   9165 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   9166 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   9167 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed.");
   9168 
   9169 	/* Set up the texture views we'll be using for the test */
   9170 	gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, GL_RGBA8, 1, /* minlevel */
   9171 				   2,												  /* numlevels */
   9172 				   0,												  /* minlayer */
   9173 				   1);												  /* numlayers */
   9174 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
   9175 
   9176 	gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
   9177 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   9178 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   9179 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   9180 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   9181 
   9182 	/* Set up storage for static color texture */
   9183 	gl.bindTexture(GL_TEXTURE_2D, m_static_to_id);
   9184 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   9185 
   9186 	gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
   9187 					GL_RGBA8, m_static_texture_width, m_static_texture_height);
   9188 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
   9189 
   9190 	/* Fill the texture objects with actual contents */
   9191 	initTextureContents();
   9192 }
   9193 
   9194 /** Fills all relevant mip-maps of all previously initialized texture objects with
   9195  *  contents.
   9196  *
   9197  *  Throws an exception if any of the issued GL API calls fail.
   9198  **/
   9199 void TextureViewTestCoherency::initTextureContents()
   9200 {
   9201 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9202 
   9203 	/* Make sure parent texture object is bound before we start modifying
   9204 	 * the mip-maps */
   9205 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
   9206 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   9207 
   9208 	/* Set up parent texture mip-maps */
   9209 	unsigned char* base_mipmap_data_ptr = getHorizontalGradientData();
   9210 
   9211 	gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
   9212 					 0,				   /* xoffset */
   9213 					 0,				   /* yoffset */
   9214 					 m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, base_mipmap_data_ptr);
   9215 
   9216 	delete[] base_mipmap_data_ptr;
   9217 	base_mipmap_data_ptr = NULL;
   9218 
   9219 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
   9220 
   9221 	/* Generate all mip-maps */
   9222 	gl.generateMipmap(GL_TEXTURE_2D);
   9223 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed.");
   9224 
   9225 	/* Set up static color texture contents. We only need to fill the base mip-map
   9226 	 * since the texture's resolution is 1x1.
   9227 	 */
   9228 	DE_ASSERT(m_static_texture_height == 1 && m_static_texture_width == 1);
   9229 
   9230 	unsigned char* static_texture_data_ptr = getStaticColorTextureData(m_static_texture_width, m_static_texture_height);
   9231 
   9232 	gl.bindTexture(GL_TEXTURE_2D, m_static_to_id);
   9233 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   9234 
   9235 	gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
   9236 					 0,				   /* xoffset */
   9237 					 0,				   /* yoffset */
   9238 					 m_static_texture_width, m_static_texture_height, GL_RGBA, GL_UNSIGNED_BYTE,
   9239 					 static_texture_data_ptr);
   9240 
   9241 	/* Good to release the buffer at this point */
   9242 	delete[] static_texture_data_ptr;
   9243 
   9244 	static_texture_data_ptr = DE_NULL;
   9245 
   9246 	/* Was the API call successful? */
   9247 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
   9248 }
   9249 
   9250 /** Initializes a vertex array object used for the draw calls issued during the test. */
   9251 void TextureViewTestCoherency::initVAO()
   9252 {
   9253 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9254 
   9255 	/* Generate and bind a vertex array object */
   9256 	gl.genVertexArrays(1, &m_vao_id);
   9257 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   9258 
   9259 	gl.bindVertexArray(m_vao_id);
   9260 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   9261 }
   9262 
   9263 /** Executes test iteration.
   9264  *
   9265  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   9266  */
   9267 tcu::TestNode::IterateResult TextureViewTestCoherency::iterate()
   9268 {
   9269 	/* Do not execute the test if GL_ARB_texture_view is not supported */
   9270 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view"))
   9271 	{
   9272 		throw tcu::NotSupportedError("GL_ARB_texture_view is not supported.");
   9273 	}
   9274 
   9275 	/* Initialize all GL objects required to run the test */
   9276 	initBufferObjects();
   9277 	initPrograms();
   9278 	initTextures();
   9279 	initFBO();
   9280 	initVAO();
   9281 
   9282 	/* Iterate over the set of texture types we are to test */
   9283 	const _texture_type texture_types[] = { TEXTURE_TYPE_PARENT_TEXTURE, TEXTURE_TYPE_TEXTURE_VIEW };
   9284 	const unsigned int  n_texture_types = sizeof(texture_types) / sizeof(texture_types[0]);
   9285 
   9286 	for (unsigned int n_texture_type = 0; n_texture_type < n_texture_types; ++n_texture_type)
   9287 	{
   9288 		_texture_type texture_type = texture_types[n_texture_type];
   9289 
   9290 		/* Verify parent texture/view coherency when using glTexSubImage2D() */
   9291 		checkAPICallCoherency(texture_type, true);
   9292 
   9293 		/* Verify parent texture/view coherency when using glBlitFramebuffer() */
   9294 		checkAPICallCoherency(texture_type, false);
   9295 
   9296 		/* Verify parent texture/view coherency when modifying contents of one
   9297 		 * of the objects in a program, and then reading the sibling from another
   9298 		 * program.
   9299 		 */
   9300 		checkProgramWriteCoherency(texture_type, false, /* should_use_images */
   9301 								   BARRIER_TYPE_NONE, VERIFICATION_MEAN_PROGRAM);
   9302 
   9303 		if (m_are_images_supported)
   9304 		{
   9305 			/* Verify a view bound to an image unit and written to using image uniforms
   9306 			 * in vertex shader stage can later be sampled correctly, assuming
   9307 			 * a GL_TEXTURE_FETCH_BARRIER_BIT barrier is inserted between the write
   9308 			 * operations and sampling from another program object.
   9309 			 */
   9310 			checkProgramWriteCoherency(texture_type, true, /* should_use_images */
   9311 									   BARRIER_TYPE_TEXTURE_FETCH_BARRIER_BIT, VERIFICATION_MEAN_PROGRAM);
   9312 
   9313 			/* Verify a view bound to an image unit and written to using image uniforms
   9314 			 * in vertex shader stage can later be correctly retrieved using a glGetTexImage()
   9315 			 * call, assuming a GL_TEXTURE_UPDATE_BARRIER_BIT barrier is inserted between the
   9316 			 * two operations.
   9317 			 **/
   9318 			checkProgramWriteCoherency(texture_type, true, /* should_use_images */
   9319 									   BARRIER_TYPE_TEXTURE_UPDATE_BUFFER_BIT, VERIFICATION_MEAN_GLGETTEXIMAGE);
   9320 		}
   9321 
   9322 		/* Reinitialize all texture contents */
   9323 		initTextureContents();
   9324 	} /* for (all read sources) */
   9325 
   9326 	/* Test case passed */
   9327 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   9328 
   9329 	return STOP;
   9330 }
   9331 
   9332 /** Constructor.
   9333  *
   9334  *  @param context Rendering context.
   9335  *
   9336  **/
   9337 TextureViewTestBaseAndMaxLevels::TextureViewTestBaseAndMaxLevels(deqp::Context& context)
   9338 	: TestCase(context, "base_and_max_levels", "test_description")
   9339 	, m_texture_height(256)
   9340 	, m_texture_n_components(4)
   9341 	, m_texture_n_levels(6)
   9342 	, m_texture_width(256)
   9343 	, m_view_height(128)
   9344 	, m_view_width(128)
   9345 	, m_layer_data_lod0(DE_NULL)
   9346 	, m_layer_data_lod1(DE_NULL)
   9347 	, m_fbo_id(0)
   9348 	, m_fs_id(0)
   9349 	, m_po_id(0)
   9350 	, m_po_lod_index_uniform_location(-1)
   9351 	, m_po_to_sampler_uniform_location(-1)
   9352 	, m_result_to_id(0)
   9353 	, m_to_id(0)
   9354 	, m_vao_id(0)
   9355 	, m_view_to_id(0)
   9356 	, m_vs_id(0)
   9357 {
   9358 	/* Left blank on purpose */
   9359 }
   9360 
   9361 /* Deinitializes all GL objects that may have been created during test execution. */
   9362 void TextureViewTestBaseAndMaxLevels::deinit()
   9363 {
   9364 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9365 
   9366 	if (m_fbo_id != 0)
   9367 	{
   9368 		gl.deleteFramebuffers(1, &m_fbo_id);
   9369 
   9370 		m_fbo_id = 0;
   9371 	}
   9372 
   9373 	if (m_fs_id != 0)
   9374 	{
   9375 		gl.deleteShader(m_fs_id);
   9376 
   9377 		m_fs_id = 0;
   9378 	}
   9379 
   9380 	if (m_layer_data_lod0 != DE_NULL)
   9381 	{
   9382 		delete[] m_layer_data_lod0;
   9383 
   9384 		m_layer_data_lod0 = DE_NULL;
   9385 	}
   9386 
   9387 	if (m_layer_data_lod1 != DE_NULL)
   9388 	{
   9389 		delete[] m_layer_data_lod1;
   9390 
   9391 		m_layer_data_lod1 = DE_NULL;
   9392 	}
   9393 
   9394 	if (m_po_id != 0)
   9395 	{
   9396 		gl.deleteProgram(m_po_id);
   9397 
   9398 		m_po_id = 0;
   9399 	}
   9400 
   9401 	if (m_result_to_id != 0)
   9402 	{
   9403 		gl.deleteTextures(1, &m_result_to_id);
   9404 
   9405 		m_result_to_id = 0;
   9406 	}
   9407 
   9408 	if (m_to_id != 0)
   9409 	{
   9410 		gl.deleteTextures(1, &m_to_id);
   9411 
   9412 		m_to_id = 0;
   9413 	}
   9414 
   9415 	if (m_vao_id != 0)
   9416 	{
   9417 		gl.deleteVertexArrays(1, &m_vao_id);
   9418 
   9419 		m_vao_id = 0;
   9420 	}
   9421 
   9422 	if (m_view_to_id != 0)
   9423 	{
   9424 		gl.deleteTextures(1, &m_view_to_id);
   9425 
   9426 		m_view_to_id = 0;
   9427 	}
   9428 
   9429 	if (m_vs_id != 0)
   9430 	{
   9431 		gl.deleteShader(m_vs_id);
   9432 
   9433 		m_vs_id = 0;
   9434 	}
   9435 }
   9436 
   9437 /* Initializes and configures a program object used later by the test. */
   9438 void TextureViewTestBaseAndMaxLevels::initProgram()
   9439 {
   9440 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9441 
   9442 	/* Generate shader object IDs */
   9443 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
   9444 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   9445 
   9446 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed");
   9447 
   9448 	/* Generate program object ID */
   9449 	m_po_id = gl.createProgram();
   9450 
   9451 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
   9452 
   9453 	/* Set up vertex shader body */
   9454 	static const char* vs_body =
   9455 		"#version 400\n"
   9456 		"\n"
   9457 		"out vec2 uv;\n"
   9458 		"\n"
   9459 		"void main()\n"
   9460 		"{\n"
   9461 		"    switch (gl_VertexID)\n"
   9462 		"    {\n"
   9463 		"        case 0: gl_Position = vec4(-1.0,  1.0, 0.0, 1.0); uv = vec2(0.0, 1.0); break;\n"
   9464 		"        case 1: gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); uv = vec2(0.0, 0.0); break;\n"
   9465 		"        case 2: gl_Position = vec4( 1.0,  1.0, 0.0, 1.0); uv = vec2(1.0, 1.0); break;\n"
   9466 		"        case 3: gl_Position = vec4( 1.0, -1.0, 0.0, 1.0); uv = vec2(1.0, 0.0); break;\n"
   9467 		"    };\n"
   9468 		"}\n";
   9469 
   9470 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
   9471 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed for vertex shader case");
   9472 
   9473 	/* Set up fragment shader body */
   9474 	static const char* fs_body = "#version 400\n"
   9475 								 "\n"
   9476 								 "in vec2 uv;\n"
   9477 								 "\n"
   9478 								 "uniform int       lod_index;\n"
   9479 								 "uniform sampler2D to_sampler;\n"
   9480 								 "\n"
   9481 								 "out vec4 result;\n"
   9482 								 "\n"
   9483 								 "void main()\n"
   9484 								 "{\n"
   9485 								 "    result = textureLod(to_sampler, uv, float(lod_index) );\n"
   9486 								 "}\n";
   9487 
   9488 	gl.shaderSource(m_fs_id, 1 /* count */, &fs_body, DE_NULL /* length */);
   9489 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed for fragment shader case");
   9490 
   9491 	/* Compile both shaders */
   9492 	const glw::GLuint  so_ids[] = { m_fs_id, m_vs_id };
   9493 	const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
   9494 
   9495 	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
   9496 	{
   9497 		glw::GLint so_id = so_ids[n_so_id];
   9498 
   9499 		gl.compileShader(so_id);
   9500 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   9501 
   9502 		/* Make sure the compilation has succeeded */
   9503 		glw::GLint compile_status = GL_FALSE;
   9504 
   9505 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
   9506 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   9507 
   9508 		if (compile_status != GL_TRUE)
   9509 		{
   9510 			m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed" << tcu::TestLog::EndMessage;
   9511 		}
   9512 	} /* for (all shader objects) */
   9513 
   9514 	/* Attach the shaders to the program object */
   9515 	gl.attachShader(m_po_id, m_fs_id);
   9516 	gl.attachShader(m_po_id, m_vs_id);
   9517 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed");
   9518 
   9519 	/* Link the program object */
   9520 	gl.linkProgram(m_po_id);
   9521 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call faikled");
   9522 
   9523 	/* Verify the linking has succeeded */
   9524 	glw::GLint link_status = GL_FALSE;
   9525 
   9526 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   9527 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed for GL_LINK_STATUS pname");
   9528 
   9529 	if (link_status != GL_TRUE)
   9530 	{
   9531 		TCU_FAIL("Program linking failed");
   9532 	}
   9533 
   9534 	/* Retrieve uniform locations */
   9535 	m_po_lod_index_uniform_location  = gl.getUniformLocation(m_po_id, "lod_index");
   9536 	m_po_to_sampler_uniform_location = gl.getUniformLocation(m_po_id, "to_sampler");
   9537 
   9538 	if (m_po_lod_index_uniform_location == -1)
   9539 	{
   9540 		TCU_FAIL("lod_index is considered an inactive uniform");
   9541 	}
   9542 
   9543 	if (m_po_to_sampler_uniform_location == -1)
   9544 	{
   9545 		TCU_FAIL("to_sampler is considered an inactive uniform");
   9546 	}
   9547 }
   9548 
   9549 /* Initializes all GL objects used by the test. */
   9550 void TextureViewTestBaseAndMaxLevels::initTest()
   9551 {
   9552 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9553 
   9554 	/* Initialize textures */
   9555 	initTextures();
   9556 
   9557 	/* Initialize framebuffer and configure its attachments */
   9558 	gl.genFramebuffers(1, &m_fbo_id);
   9559 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed");
   9560 
   9561 	/* Build the program we'll need for the test */
   9562 	initProgram();
   9563 
   9564 	/* Generate a vertex array object to execute the draw calls */
   9565 	gl.genVertexArrays(1, &m_vao_id);
   9566 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   9567 
   9568 	gl.bindVertexArray(m_vao_id);
   9569 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   9570 
   9571 	/* Finally, allocate space for buffers that will be filled with rendered data */
   9572 	m_layer_data_lod0 = new unsigned char[m_texture_width * m_texture_height * m_texture_n_components];
   9573 	m_layer_data_lod1 = new unsigned char[(m_texture_width >> 1) * (m_texture_height >> 1) * m_texture_n_components];
   9574 
   9575 	if (m_layer_data_lod0 == DE_NULL || m_layer_data_lod1 == DE_NULL)
   9576 	{
   9577 		TCU_FAIL("Out of memory");
   9578 	}
   9579 }
   9580 
   9581 /** Initializes texture objects used by the test. */
   9582 void TextureViewTestBaseAndMaxLevels::initTextures()
   9583 {
   9584 	/* Generate IDs first */
   9585 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9586 
   9587 	gl.genTextures(1, &m_result_to_id);
   9588 	gl.genTextures(1, &m_to_id);
   9589 	gl.genTextures(1, &m_view_to_id);
   9590 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
   9591 
   9592 	/* Set up parent texture object's storage */
   9593 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
   9594 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   9595 
   9596 	gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height);
   9597 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
   9598 
   9599 	/* Configure GL_TEXTURE_BASE_LEVEL parameter of the texture object as per test spec */
   9600 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
   9601 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_BASE_LEVEL pname");
   9602 
   9603 	/* Configure GL_TEXTURE_MAX_LEVEL parameter of the texture object as per test spec */
   9604 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
   9605 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_MAX_LEVEL pname");
   9606 
   9607 	/* Set up mip-maps */
   9608 	for (unsigned int n_mipmap = 0; n_mipmap < m_texture_n_levels; ++n_mipmap)
   9609 	{
   9610 		const float start_rgba[] = { /* As per test specification */
   9611 									 float(n_mipmap + 0) / 10.0f, float(n_mipmap + 1) / 10.0f,
   9612 									 float(n_mipmap + 2) / 10.0f, float(n_mipmap + 3) / 10.0f
   9613 		};
   9614 		const float end_rgba[] = { float(10 - (n_mipmap + 0)) / 10.0f, float(10 - (n_mipmap + 1)) / 10.0f,
   9615 								   float(10 - (n_mipmap + 2)) / 10.0f, float(10 - (n_mipmap + 3)) / 10.0f };
   9616 
   9617 		/* Allocate space for the layer data */
   9618 		const unsigned int mipmap_height = m_texture_height >> n_mipmap;
   9619 		const unsigned int mipmap_width  = m_texture_width >> n_mipmap;
   9620 		unsigned char*	 data			 = new unsigned char[mipmap_width * mipmap_height * m_texture_n_components];
   9621 
   9622 		if (data == NULL)
   9623 		{
   9624 			TCU_FAIL("Out of memory");
   9625 		}
   9626 
   9627 		/* Fill the buffer with layer data */
   9628 		const unsigned int pixel_size = 4 /* components */;
   9629 
   9630 		for (unsigned int y = 0; y < mipmap_height; ++y)
   9631 		{
   9632 			unsigned char* row_data_ptr = data + mipmap_width * y * pixel_size;
   9633 
   9634 			for (unsigned int x = 0; x < mipmap_width; ++x)
   9635 			{
   9636 				const float	lerp_factor	= float(x) / float(mipmap_width);
   9637 				unsigned char* pixel_data_ptr = row_data_ptr + x * pixel_size;
   9638 
   9639 				for (unsigned int n_component = 0; n_component < m_texture_n_components; n_component++)
   9640 				{
   9641 					pixel_data_ptr[n_component] = (unsigned char)((start_rgba[n_component] * lerp_factor +
   9642 																   end_rgba[n_component] * (1.0f - lerp_factor)) *
   9643 																  255.0f);
   9644 				}
   9645 			} /* for (all columns) */
   9646 		}	 /* for (all rows) */
   9647 
   9648 		/* Upload the layer data */
   9649 		gl.texSubImage2D(GL_TEXTURE_2D, n_mipmap, 0, /* xoffset */
   9650 						 0,							 /* yoffset */
   9651 						 mipmap_width, mipmap_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
   9652 
   9653 		/* Release the data buffer */
   9654 		delete[] data;
   9655 
   9656 		data = DE_NULL;
   9657 
   9658 		/* Make sure the API call finished successfully */
   9659 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed");
   9660 	} /* for (all mip-maps) */
   9661 
   9662 	/* Configure the texture view storage as per spec. */
   9663 	gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, GL_RGBA8, 0, /* minlevel */
   9664 				   5,												  /* numlevels */
   9665 				   0,												  /* minlayer */
   9666 				   1);												  /* numlayers */
   9667 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
   9668 
   9669 	/* Configure the texture view's GL_TEXTURE_BASE_LEVEL parameter */
   9670 	gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
   9671 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   9672 
   9673 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
   9674 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_BASE_LEVEL pname");
   9675 
   9676 	/* Configure the texture view's GL_TEXTURE_MAX_LEVEL parameter */
   9677 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
   9678 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_MAX_LEVEL pname");
   9679 
   9680 	/* Set up result texture storage */
   9681 	gl.bindTexture(GL_TEXTURE_2D, m_result_to_id);
   9682 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   9683 
   9684 	gl.texStorage2D(GL_TEXTURE_2D, 1, /* We will only attach the first level of the result texture to the FBO */
   9685 					GL_RGBA8, m_view_width, m_view_height);
   9686 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
   9687 }
   9688 
   9689 /** Executes test iteration.
   9690  *
   9691  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   9692  */
   9693 tcu::TestNode::IterateResult TextureViewTestBaseAndMaxLevels::iterate()
   9694 {
   9695 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9696 
   9697 	/* Only execute if GL_ARB_texture_view extension is supported */
   9698 	const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
   9699 
   9700 	if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
   9701 	{
   9702 		throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
   9703 	}
   9704 
   9705 	/* Initialize all GL objects necessary to run the test */
   9706 	initTest();
   9707 
   9708 	/* Activate test-wide program object */
   9709 	gl.useProgram(m_po_id);
   9710 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   9711 
   9712 	/* Bind the data texture */
   9713 	gl.activeTexture(GL_TEXTURE0);
   9714 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed");
   9715 
   9716 	gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
   9717 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   9718 
   9719 	/* We will now use the program to sample the view's LOD 0 and LOD 1 and store
   9720 	 * it in two separate textures.
   9721 	 **/
   9722 	for (unsigned int lod_level = 0; lod_level < 2; /* as per test spec */
   9723 		 ++lod_level)
   9724 	{
   9725 		/* Set up FBO attachments */
   9726 		gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   9727 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed");
   9728 
   9729 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_result_to_id,
   9730 								0); /* level */
   9731 		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed");
   9732 
   9733 		/* Update viewport configuration */
   9734 		gl.viewport(0, /* x */
   9735 					0, /* y */
   9736 					m_view_width >> lod_level, m_view_height >> lod_level);
   9737 
   9738 		GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed");
   9739 
   9740 		/* Configure program object uniforms before we continue */
   9741 		gl.uniform1i(m_po_lod_index_uniform_location, lod_level);
   9742 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   9743 
   9744 		/* Render a triangle strip. The program we're using will output a full-screen
   9745 		 * quad with the sampled data */
   9746 		gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
   9747 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   9748 
   9749 		/* At the time of the draw call, we've modified the draw/read framebuffer binding
   9750 		 * so that everything we render ends up in result texture. It's time to read it */
   9751 		glw::GLvoid* result_data_ptr = (lod_level == 0) ? m_layer_data_lod0 : m_layer_data_lod1;
   9752 
   9753 		gl.readPixels(0, /* x */
   9754 					  0, /* y */
   9755 					  m_view_width >> lod_level, m_view_height >> lod_level, GL_RGBA, GL_UNSIGNED_BYTE,
   9756 					  result_data_ptr);
   9757 
   9758 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
   9759 	} /* for (both LODs) */
   9760 
   9761 	/* Now that we have both pieces of data, we can proceed with actual verification */
   9762 	for (unsigned int lod_level = 0; lod_level < 2; ++lod_level)
   9763 	{
   9764 		/* NOTE: This code is a modification of initialization routine
   9765 		 *       found in initTextures()
   9766 		 */
   9767 		const unsigned char epsilon			   = 1;
   9768 		const glw::GLvoid*  layer_data_ptr	 = (lod_level == 0) ? m_layer_data_lod0 : m_layer_data_lod1;
   9769 		const unsigned int  layer_height	   = m_view_height >> lod_level;
   9770 		const unsigned int  layer_width		   = m_view_width >> lod_level;
   9771 		const unsigned int  pixel_size		   = 4 /* components */;
   9772 		const unsigned int  view_minimum_level = 1; /* THS SHOULD BE 1 */
   9773 		const float			start_rgba[]	   = {
   9774 			/* As per test specification */
   9775 			float(lod_level + view_minimum_level + 0) / 10.0f, float(lod_level + view_minimum_level + 1) / 10.0f,
   9776 			float(lod_level + view_minimum_level + 2) / 10.0f, float(lod_level + view_minimum_level + 3) / 10.0f
   9777 		};
   9778 		const float end_rgba[] = { float(10 - (lod_level + view_minimum_level + 0)) / 10.0f,
   9779 								   float(10 - (lod_level + view_minimum_level + 1)) / 10.0f,
   9780 								   float(10 - (lod_level + view_minimum_level + 2)) / 10.0f,
   9781 								   float(10 - (lod_level + view_minimum_level + 3)) / 10.0f };
   9782 
   9783 		for (unsigned int y = 0; y < layer_height; ++y)
   9784 		{
   9785 			const unsigned char* row_data_ptr = (const unsigned char*)layer_data_ptr + layer_width * y * pixel_size;
   9786 
   9787 			for (unsigned int x = 0; x < layer_width; ++x)
   9788 			{
   9789 				const float			 lerp_factor	= float(x) / float(layer_width);
   9790 				const unsigned char* pixel_data_ptr = row_data_ptr + x * pixel_size;
   9791 
   9792 				const unsigned char expected_data[] = {
   9793 					(unsigned char)((start_rgba[0] * lerp_factor + end_rgba[0] * (1.0f - lerp_factor)) * 255.0f),
   9794 					(unsigned char)((start_rgba[1] * lerp_factor + end_rgba[1] * (1.0f - lerp_factor)) * 255.0f),
   9795 					(unsigned char)((start_rgba[2] * lerp_factor + end_rgba[2] * (1.0f - lerp_factor)) * 255.0f),
   9796 					(unsigned char)((start_rgba[3] * lerp_factor + end_rgba[3] * (1.0f - lerp_factor)) * 255.0f)
   9797 				};
   9798 
   9799 				if (de::abs(expected_data[0] - pixel_data_ptr[0]) > epsilon ||
   9800 					de::abs(expected_data[1] - pixel_data_ptr[1]) > epsilon ||
   9801 					de::abs(expected_data[2] - pixel_data_ptr[2]) > epsilon ||
   9802 					de::abs(expected_data[3] - pixel_data_ptr[3]) > epsilon)
   9803 				{
   9804 					m_testCtx.getLog() << tcu::TestLog::Message << "Found an invalid texel at (" << x << ", " << y
   9805 									   << ");"
   9806 										  " expected value:"
   9807 										  "("
   9808 									   << expected_data[0] << ", " << expected_data[1] << ", " << expected_data[2]
   9809 									   << ", " << expected_data[3] << ")"
   9810 																	  ", found:"
   9811 																	  "("
   9812 									   << pixel_data_ptr[0] << ", " << pixel_data_ptr[1] << ", " << pixel_data_ptr[2]
   9813 									   << ", " << pixel_data_ptr[3] << ")" << tcu::TestLog::EndMessage;
   9814 
   9815 					TCU_FAIL("Rendered data does not match expected pixel data");
   9816 				} /* if (pixel mismatch found) */
   9817 			}	 /* for (all columns) */
   9818 		}		  /* for (all rows) */
   9819 	}			  /* for (both LODs) */
   9820 
   9821 	/* Test case passed */
   9822 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   9823 
   9824 	return STOP;
   9825 }
   9826 
   9827 /** Constructor.
   9828  *
   9829  *  @param context Rendering context.
   9830  **/
   9831 TextureViewTestReferenceCounting::TextureViewTestReferenceCounting(deqp::Context& context)
   9832 	: TestCase(context, "reference_counting",
   9833 			   "Makes sure that sampling from views, for which the parent texture object "
   9834 			   "has already been deleted, works correctly.")
   9835 	, m_bo_id(0)
   9836 	, m_parent_to_id(0)
   9837 	, m_po_id(0)
   9838 	, m_po_expected_texel_uniform_location(-1)
   9839 	, m_po_lod_uniform_location(-1)
   9840 	, m_vao_id(0)
   9841 	, m_view_to_id(0)
   9842 	, m_view_view_to_id(0)
   9843 	, m_vs_id(0)
   9844 	, m_texture_height(64)
   9845 	, m_texture_n_levels(7)
   9846 	, m_texture_width(64)
   9847 {
   9848 	/* Configure a vector storing unique colors that should be used
   9849 	 * for filling subsequent mip-maps of parent texture */
   9850 	m_mipmap_colors.push_back(_norm_vec4(123, 34, 56, 78));
   9851 	m_mipmap_colors.push_back(_norm_vec4(234, 45, 67, 89));
   9852 	m_mipmap_colors.push_back(_norm_vec4(34, 56, 78, 90));
   9853 	m_mipmap_colors.push_back(_norm_vec4(45, 67, 89, 1));
   9854 	m_mipmap_colors.push_back(_norm_vec4(56, 78, 90, 123));
   9855 	m_mipmap_colors.push_back(_norm_vec4(67, 89, 1, 234));
   9856 	m_mipmap_colors.push_back(_norm_vec4(78, 90, 12, 34));
   9857 
   9858 	DE_ASSERT(m_mipmap_colors.size() == m_texture_n_levels);
   9859 }
   9860 
   9861 /** Deinitializes all GL objects that may have been created during test
   9862  *  execution.
   9863  **/
   9864 void TextureViewTestReferenceCounting::deinit()
   9865 {
   9866 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9867 
   9868 	if (m_bo_id != 0)
   9869 	{
   9870 		gl.deleteBuffers(1, &m_bo_id);
   9871 
   9872 		m_bo_id = 0;
   9873 	}
   9874 
   9875 	if (m_parent_to_id != 0)
   9876 	{
   9877 		gl.deleteTextures(1, &m_parent_to_id);
   9878 
   9879 		m_parent_to_id = 0;
   9880 	}
   9881 
   9882 	if (m_po_id != 0)
   9883 	{
   9884 		gl.deleteProgram(m_po_id);
   9885 
   9886 		m_po_id = 0;
   9887 	}
   9888 
   9889 	if (m_vao_id != 0)
   9890 	{
   9891 		gl.deleteVertexArrays(1, &m_vao_id);
   9892 
   9893 		m_vao_id = 0;
   9894 	}
   9895 
   9896 	if (m_view_to_id != 0)
   9897 	{
   9898 		gl.deleteTextures(1, &m_view_to_id);
   9899 
   9900 		m_view_to_id = 0;
   9901 	}
   9902 
   9903 	if (m_view_view_to_id != 0)
   9904 	{
   9905 		gl.deleteTextures(1, &m_view_view_to_id);
   9906 
   9907 		m_view_view_to_id = 0;
   9908 	}
   9909 
   9910 	if (m_vs_id != 0)
   9911 	{
   9912 		gl.deleteShader(m_vs_id);
   9913 
   9914 		m_vs_id = 0;
   9915 	}
   9916 }
   9917 
   9918 /* Initializes a program object to be used during the test. */
   9919 void TextureViewTestReferenceCounting::initProgram()
   9920 {
   9921 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9922 
   9923 	/* Create program & shader object IDs */
   9924 	m_po_id = gl.createProgram();
   9925 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
   9926 
   9927 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   9928 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed");
   9929 
   9930 	/* Set vertex shader body */
   9931 	const char* vs_body = "#version 400\n"
   9932 						  "\n"
   9933 						  "uniform vec4      expected_texel;\n"
   9934 						  "uniform int       lod;\n"
   9935 						  "uniform sampler2D sampler;\n"
   9936 						  "\n"
   9937 						  "out int has_passed;\n"
   9938 						  "\n"
   9939 						  "void main()\n"
   9940 						  "{\n"
   9941 						  "          vec4  data    = textureLod(sampler, vec2(0.5, 0.5), lod);\n"
   9942 						  "    const float epsilon = 1.0 / 256.0;\n"
   9943 						  "\n"
   9944 						  "    if (abs(data.r - expected_texel.r) > epsilon ||\n"
   9945 						  "        abs(data.g - expected_texel.g) > epsilon ||\n"
   9946 						  "        abs(data.b - expected_texel.b) > epsilon ||\n"
   9947 						  "        abs(data.a - expected_texel.a) > epsilon)\n"
   9948 						  "    {\n"
   9949 						  "        has_passed = 0;\n"
   9950 						  "    }\n"
   9951 						  "    else\n"
   9952 						  "    {\n"
   9953 						  "        has_passed = 1;\n"
   9954 						  "    }\n"
   9955 						  "}\n";
   9956 
   9957 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, NULL /* length */);
   9958 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
   9959 
   9960 	/* Configure XFB */
   9961 	const char* varying_name = "has_passed";
   9962 
   9963 	gl.transformFeedbackVaryings(m_po_id, 1 /* count */, &varying_name, GL_INTERLEAVED_ATTRIBS);
   9964 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed");
   9965 
   9966 	/* Attach the shader object to the program */
   9967 	gl.attachShader(m_po_id, m_vs_id);
   9968 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed");
   9969 
   9970 	/* Compile the shader */
   9971 	gl.compileShader(m_vs_id);
   9972 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   9973 
   9974 	/* Make sure the compilation has succeeded */
   9975 	glw::GLint compile_status = GL_FALSE;
   9976 
   9977 	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
   9978 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   9979 
   9980 	if (compile_status != GL_TRUE)
   9981 	{
   9982 		m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed" << tcu::TestLog::EndMessage;
   9983 	}
   9984 
   9985 	/* Link the program object */
   9986 	gl.linkProgram(m_po_id);
   9987 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed");
   9988 
   9989 	/* Make sure the program object has linked successfully */
   9990 	glw::GLint link_status = GL_FALSE;
   9991 
   9992 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   9993 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
   9994 
   9995 	if (link_status != GL_TRUE)
   9996 	{
   9997 		TCU_FAIL("Program linking failed");
   9998 	}
   9999 
   10000 	/* Retrieve uniform locations */
   10001 	m_po_expected_texel_uniform_location = gl.getUniformLocation(m_po_id, "expected_texel");
   10002 	m_po_lod_uniform_location			 = gl.getUniformLocation(m_po_id, "lod");
   10003 
   10004 	if (m_po_expected_texel_uniform_location == -1)
   10005 	{
   10006 		TCU_FAIL("expected_texel is considered an inactive uniform which is invalid");
   10007 	}
   10008 
   10009 	if (m_po_lod_uniform_location == -1)
   10010 	{
   10011 		TCU_FAIL("lod is considered an inactive uniform which is invalid");
   10012 	}
   10013 }
   10014 
   10015 /** Initializes all texture objects and all views used by the test. */
   10016 void TextureViewTestReferenceCounting::initTextures()
   10017 {
   10018 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10019 
   10020 	/* Generate texture IDs */
   10021 	gl.genTextures(1, &m_parent_to_id);
   10022 	gl.genTextures(1, &m_view_to_id);
   10023 	gl.genTextures(1, &m_view_view_to_id);
   10024 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
   10025 
   10026 	/* Set up parent texture object A */
   10027 	gl.bindTexture(GL_TEXTURE_2D, m_parent_to_id);
   10028 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
   10029 
   10030 	gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height);
   10031 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
   10032 
   10033 	/* Set up view B */
   10034 	gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_parent_to_id, GL_RGBA8, 0, /* minlevel */
   10035 				   m_texture_n_levels, 0,									 /* minlayer */
   10036 				   1);														 /* numlayers */
   10037 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
   10038 
   10039 	/* Set up view C */
   10040 	gl.textureView(m_view_view_to_id, GL_TEXTURE_2D, m_view_to_id, GL_RGBA8, 0, /* minlevel */
   10041 				   m_texture_n_levels, 0,										/* minlayer */
   10042 				   1);															/* numlayers */
   10043 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
   10044 
   10045 	/* Fill parent texture mip-maps with different static colors */
   10046 	unsigned char* texel_data = new unsigned char[m_texture_width * m_texture_height * 4 /* components */];
   10047 
   10048 	for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); n_mipmap++)
   10049 	{
   10050 		const _norm_vec4&  mipmap_color  = m_mipmap_colors[n_mipmap];
   10051 		const unsigned int mipmap_height = m_texture_height >> n_mipmap;
   10052 		const unsigned int mipmap_width  = m_texture_width >> n_mipmap;
   10053 
   10054 		for (unsigned int n_texel = 0; n_texel < mipmap_height * mipmap_width; ++n_texel)
   10055 		{
   10056 			unsigned char* texel_data_ptr = texel_data + n_texel * sizeof(mipmap_color.rgba);
   10057 
   10058 			memcpy(texel_data_ptr, mipmap_color.rgba, sizeof(mipmap_color.rgba));
   10059 		} /* for (all relevant mip-map texels) */
   10060 
   10061 		/* Upload new mip-map contents */
   10062 		gl.texSubImage2D(GL_TEXTURE_2D, n_mipmap, 0, /* xoffset */
   10063 						 0,							 /* yoffset */
   10064 						 m_texture_width >> n_mipmap, m_texture_height >> n_mipmap, GL_RGBA, GL_UNSIGNED_BYTE,
   10065 						 texel_data);
   10066 
   10067 		if (gl.getError() != GL_NO_ERROR)
   10068 		{
   10069 			delete[] texel_data;
   10070 			texel_data = NULL;
   10071 
   10072 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed");
   10073 		}
   10074 	} /* for (all mip-maps) */
   10075 
   10076 	delete[] texel_data;
   10077 	texel_data = NULL;
   10078 }
   10079 
   10080 /* Initialize all GL objects necessary to run the test */
   10081 void TextureViewTestReferenceCounting::initTest()
   10082 {
   10083 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10084 
   10085 	/* Initialize all texture objects */
   10086 	initTextures();
   10087 
   10088 	/* Initialize test program object */
   10089 	initProgram();
   10090 
   10091 	/* Initialize XFB */
   10092 	initXFB();
   10093 
   10094 	/* Generate and bind a vertex array object, since we'll be doing a number of
   10095 	 * draw calls later in the test */
   10096 	gl.genVertexArrays(1, &m_vao_id);
   10097 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   10098 
   10099 	gl.bindVertexArray(m_vao_id);
   10100 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   10101 }
   10102 
   10103 /** Initializes a buffer object later used for Transform Feedback and binds
   10104  *  it to both general and indexed Transform Feedback binding points.
   10105  **/
   10106 void TextureViewTestReferenceCounting::initXFB()
   10107 {
   10108 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10109 
   10110 	/* Sanity checks */
   10111 	DE_ASSERT(m_po_id != 0);
   10112 
   10113 	/* Generate a buffer object we'll use for Transform Feedback */
   10114 	gl.genBuffers(1, &m_bo_id);
   10115 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
   10116 
   10117 	/* Set up buffer object storage. We need it to be large enough to hold
   10118 	 * sizeof(glw::GLint) per mipmap level */
   10119 	const glw::GLint bo_size = (glw::GLint)(sizeof(glw::GLint) * m_mipmap_colors.size());
   10120 
   10121 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
   10122 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   10123 
   10124 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
   10125 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
   10126 
   10127 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL, /* data */
   10128 				  GL_STATIC_DRAW);
   10129 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
   10130 }
   10131 
   10132 /** Executes test iteration.
   10133  *
   10134  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   10135  */
   10136 tcu::TestNode::IterateResult TextureViewTestReferenceCounting::iterate()
   10137 {
   10138 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10139 
   10140 	/* Carry on only if GL_ARB_texture_view extension is supported */
   10141 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view"))
   10142 	{
   10143 		throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
   10144 	}
   10145 
   10146 	/* Initialize all GL objects used for the test */
   10147 	initTest();
   10148 
   10149 	/* Make sure texture unit 0 is currently active */
   10150 	gl.activeTexture(GL_TEXTURE0);
   10151 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
   10152 
   10153 	/* Activate the test program object */
   10154 	gl.useProgram(m_po_id);
   10155 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   10156 
   10157 	/* Run the test in three iterations:
   10158 	 *
   10159 	 * - Sample both the texture and all the views; once that's finished
   10160 	 *   successfully, delete the parent texture.
   10161 	 * - Sample both views; once that's finished successfully, delete
   10162 	 *   the first of the views;
   10163 	 * - Sample the only remaining view and make sure all mip-maps store
   10164 	 *   valid colors.
   10165 	 **/
   10166 	for (unsigned int n_iteration = 0; n_iteration < 3; /* iterations in total */
   10167 		 n_iteration++)
   10168 	{
   10169 		glw::GLuint to_ids_to_sample[3] = { 0, 0, 0 };
   10170 
   10171 		/* Configure IDs of textures we need to validate for current iteration */
   10172 		switch (n_iteration)
   10173 		{
   10174 		case 0:
   10175 		{
   10176 			to_ids_to_sample[0] = m_parent_to_id;
   10177 			to_ids_to_sample[1] = m_view_to_id;
   10178 			to_ids_to_sample[2] = m_view_view_to_id;
   10179 
   10180 			break;
   10181 		}
   10182 
   10183 		case 1:
   10184 		{
   10185 			to_ids_to_sample[0] = m_view_to_id;
   10186 			to_ids_to_sample[1] = m_view_view_to_id;
   10187 
   10188 			break;
   10189 		}
   10190 
   10191 		case 2:
   10192 		{
   10193 			to_ids_to_sample[0] = m_view_view_to_id;
   10194 
   10195 			break;
   10196 		}
   10197 
   10198 		default:
   10199 			TCU_FAIL("Invalid iteration index");
   10200 		} /* switch (n_iteration) */
   10201 
   10202 		/* Iterate through all texture objects of our concern */
   10203 		for (unsigned int n_texture = 0; n_texture < sizeof(to_ids_to_sample) / sizeof(to_ids_to_sample[0]);
   10204 			 n_texture++)
   10205 		{
   10206 			glw::GLint to_id = to_ids_to_sample[n_texture];
   10207 
   10208 			if (to_id == 0)
   10209 			{
   10210 				/* No texture object to sample from. */
   10211 				continue;
   10212 			}
   10213 
   10214 			/* Bind the texture object of our interest to GL_TEXTURE_2D */
   10215 			gl.bindTexture(GL_TEXTURE_2D, to_id);
   10216 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
   10217 
   10218 			/* Start XFB */
   10219 			gl.beginTransformFeedback(GL_POINTS);
   10220 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
   10221 
   10222 			/* Iterate through all mip-maps of the texture we're currently sampling */
   10223 			for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); ++n_mipmap)
   10224 			{
   10225 				const _norm_vec4& expected_mipmap_color = m_mipmap_colors[n_mipmap];
   10226 
   10227 				/* Update uniforms first */
   10228 				gl.uniform4f(m_po_expected_texel_uniform_location, (float)(expected_mipmap_color.rgba[0]) / 255.0f,
   10229 							 (float)(expected_mipmap_color.rgba[1]) / 255.0f,
   10230 							 (float)(expected_mipmap_color.rgba[2]) / 255.0f,
   10231 							 (float)(expected_mipmap_color.rgba[3]) / 255.0f);
   10232 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f() call failed.");
   10233 
   10234 				gl.uniform1i(m_po_lod_uniform_location, n_mipmap);
   10235 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
   10236 
   10237 				/* Draw a single point. That'll feed the XFB buffer object with a single bool
   10238 				 * indicating if the test passed for the mip-map, or not */
   10239 				gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
   10240 				GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   10241 			} /* for (all mip-maps) */
   10242 
   10243 			/* We're done - close XFB */
   10244 			gl.endTransformFeedback();
   10245 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
   10246 
   10247 			/* How did the sampling go? Map the buffer object containing the run
   10248 			 * results into process space.
   10249 			 */
   10250 			const glw::GLint* run_results_ptr =
   10251 				(const glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   10252 
   10253 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   10254 
   10255 			if (run_results_ptr == NULL)
   10256 			{
   10257 				TCU_FAIL("Pointer to mapped buffer object storage is NULL.");
   10258 			}
   10259 
   10260 			/* Make sure all mip-maps were sampled successfully */
   10261 			for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); ++n_mipmap)
   10262 			{
   10263 				if (run_results_ptr[n_mipmap] != 1)
   10264 				{
   10265 					/* Make sure the TF BO is unmapped before we throw the exception */
   10266 					gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   10267 
   10268 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled for mip-map level ["
   10269 									   << n_mipmap << "] and iteration [" << n_iteration << "]"
   10270 									   << tcu::TestLog::EndMessage;
   10271 
   10272 					TCU_FAIL("Mip-map sampling failed.");
   10273 				}
   10274 			} /* for (all mip-maps) */
   10275 
   10276 			/* Good to unmap the buffer object at this point */
   10277 			gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   10278 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
   10279 		} /* for (all initialized texture objects) */
   10280 
   10281 		/* Now that we're done with the iteration, we should delete iteration-specific texture
   10282 		 * object.
   10283 		 */
   10284 		switch (n_iteration)
   10285 		{
   10286 		case 0:
   10287 		{
   10288 			gl.deleteTextures(1, &m_parent_to_id);
   10289 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
   10290 
   10291 			m_parent_to_id = 0;
   10292 			break;
   10293 		}
   10294 
   10295 		case 1:
   10296 		{
   10297 			gl.deleteTextures(1, &m_view_to_id);
   10298 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
   10299 
   10300 			m_view_to_id = 0;
   10301 			break;
   10302 		}
   10303 
   10304 		case 2:
   10305 		{
   10306 			gl.deleteTextures(1, &m_view_view_to_id);
   10307 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
   10308 
   10309 			m_view_view_to_id = 0;
   10310 			break;
   10311 		}
   10312 
   10313 		default:
   10314 			TCU_FAIL("Invalid iteration index");
   10315 		} /* switch (n_iteration) */
   10316 	}	 /* for (all iterations) */
   10317 
   10318 	/* Test case passed */
   10319 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   10320 
   10321 	return STOP;
   10322 }
   10323 
   10324 /** Constructor.
   10325  *
   10326  *  @param context Rendering context.
   10327  **/
   10328 TextureViewTests::TextureViewTests(deqp::Context& context)
   10329 	: TestCaseGroup(context, "texture_view", "Verifies \"texture view\" functionality")
   10330 {
   10331 	/* Left blank on purpose */
   10332 }
   10333 
   10334 /** Initializes a texture_storage_multisample test group.
   10335  *
   10336  **/
   10337 void TextureViewTests::init(void)
   10338 {
   10339 	addChild(new TextureViewTestGetTexParameter(m_context));
   10340 	addChild(new TextureViewTestErrors(m_context));
   10341 	addChild(new TextureViewTestViewSampling(m_context));
   10342 	addChild(new TextureViewTestViewClasses(m_context));
   10343 	addChild(new TextureViewTestCoherency(m_context));
   10344 	addChild(new TextureViewTestBaseAndMaxLevels(m_context));
   10345 	addChild(new TextureViewTestReferenceCounting(m_context));
   10346 }
   10347 
   10348 } /* glcts namespace */
   10349