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 esextcTextureCubeMapArrayGenerateMipMap.cpp 26 * \brief texture_cube_map_array extenstion - glGenerateMipmap() (Test 7) 27 */ /*-------------------------------------------------------------------*/ 28 29 #include "esextcTextureCubeMapArrayGenerateMipMap.hpp" 30 31 #include "gluContextInfo.hpp" 32 #include "glwEnums.hpp" 33 #include "glwFunctions.hpp" 34 #include "tcuTestLog.hpp" 35 #include <cmath> 36 #include <cstring> 37 #include <vector> 38 39 namespace glcts 40 { 41 42 /* Defines two pattern colors for each layer-face */ 43 const unsigned char TextureCubeMapArrayGenerateMipMapFilterable::m_layer_face_data 44 [m_n_max_faces][m_n_colors_per_layer_face][m_n_components] = { 45 /* Color 1 --- Color 2 */ 46 { { 0, 0, 0, 0 }, { 255, 255, 255, 255 } }, /* Layer-face 0 */ 47 { { 255, 0, 0, 0 }, { 0, 255, 255, 255 } }, /* Layer-face 1 */ 48 { { 0, 255, 0, 0 }, { 255, 0, 255, 255 } }, /* Layer-face 2 */ 49 { { 0, 0, 255, 0 }, { 255, 255, 0, 255 } }, /* Layer-face 3 */ 50 { { 0, 0, 0, 255 }, { 255, 255, 255, 0 } }, /* Layer-face 4 */ 51 { { 255, 255, 0, 0 }, { 0, 0, 255, 255 } }, /* Layer-face 5 */ 52 { { 255, 0, 255, 0 }, { 0, 255, 0, 255 } }, /* Layer-face 6 */ 53 { { 255, 0, 0, 255 }, { 0, 255, 255, 0 } }, /* Layer-face 7 */ 54 { { 0, 255, 255, 0 }, { 255, 0, 0, 255 } }, /* Layer-face 8 */ 55 { { 0, 255, 0, 255 }, { 255, 0, 255, 0 } }, /* Layer-face 9 */ 56 { { 255, 255, 255, 0 }, { 0, 0, 0, 255 } }, /* Layer-face 10 */ 57 { { 255, 255, 0, 255 }, { 0, 0, 255, 0 } }, /* Layer-face 11 */ 58 { { 255, 255, 255, 255 }, { 0, 0, 0, 0 } }, /* Layer-face 12 */ 59 { { 0, 0, 0, 255 }, { 255, 0, 0, 0 } }, /* Layer-face 13 */ 60 { { 0, 0, 0, 255 }, { 255, 255, 0, 0 } }, /* Layer-face 14 */ 61 { { 0, 0, 255, 0 }, { 255, 255, 255, 0 } }, /* Layer-face 15 */ 62 { { 0, 255, 0, 0 }, { 255, 255, 255, 255 } }, /* Layer-face 16 */ 63 { { 255, 0, 0, 0 }, { 255, 0, 255, 255 } } /* Layer-face 17 */ 64 }; 65 66 /** Retrieves maximum amount of levels that should be defined for 67 * a texture of user-provided dimensions. 68 * 69 * @param width Width of the texture in question. 70 * @param height Height of the texture in question. 71 * 72 * @return Requested value. 73 **/ 74 static int getAmountOfLevelsForTexture(int width, int height) 75 { 76 return (int)floor(log((float)(de::max(width, height))) / log(2.0f)) + 1; 77 } 78 79 /** Constructor 80 * 81 * @param context Test context; 82 * @param name Test case's name; 83 * @param description Test case's description; 84 * @param storageType Precises whether texture objects used by this 85 * test instance should be created as immutable or 86 * mutable objects. 87 **/ 88 TextureCubeMapArrayGenerateMipMapFilterable::TextureCubeMapArrayGenerateMipMapFilterable(Context& context, 89 const ExtParameters& extParams, 90 const char* name, 91 const char* description, 92 STORAGE_TYPE storageType) 93 : TestCaseBase(context, extParams, name, description) 94 , m_fbo_id(0) 95 , m_storage_type(storageType) 96 , m_reference_data_ptr(DE_NULL) 97 , m_rendered_data_ptr(DE_NULL) 98 { 99 /* Nothing to be done here */ 100 } 101 102 /** Deinitialize test case **/ 103 void TextureCubeMapArrayGenerateMipMapFilterable::deinit() 104 { 105 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 106 107 /* Reset texture and FBO bindings */ 108 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0); 109 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); 110 111 /* Release any ES objects that may have been created. */ 112 if (m_fbo_id != 0) 113 { 114 gl.deleteFramebuffers(1, &m_fbo_id); 115 116 m_fbo_id = 0; 117 } 118 119 for (unsigned int i = 0; i < m_storage_configs.size(); ++i) 120 { 121 if (m_storage_configs[i].m_to_id != 0) 122 { 123 gl.deleteTextures(1, &m_storage_configs[i].m_to_id); 124 125 m_storage_configs[i].m_to_id = 0; 126 } 127 } 128 129 /* Release buffers the test may have allocated */ 130 if (m_reference_data_ptr != DE_NULL) 131 { 132 delete[] m_reference_data_ptr; 133 134 m_reference_data_ptr = DE_NULL; 135 } 136 137 if (m_rendered_data_ptr != DE_NULL) 138 { 139 delete[] m_rendered_data_ptr; 140 141 m_rendered_data_ptr = DE_NULL; 142 } 143 144 /* Restore pixel pack/unpack settings */ 145 gl.pixelStorei(GL_PACK_ALIGNMENT, 4); 146 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4); 147 148 /* Call base class' deinitialization routine. */ 149 TestCaseBase::deinit(); 150 } 151 152 /** Fills user-provided buffer with expected pixel data for user-specified 153 * layer index. 154 * 155 * @param n_layer Layer index to return expected data for. 156 * @param data Pointer to a buffer that will be filled with 157 * result data. Must not be NULL. 158 * @param width Render-target width. 159 * @param height Render-target height. 160 */ 161 void TextureCubeMapArrayGenerateMipMapFilterable::generateTestData(int n_layer, unsigned char* data, int width, 162 int height) 163 { 164 DE_ASSERT(data != DE_NULL); 165 166 for (int x = 0; x < width; ++x) 167 { 168 for (int y = 0; y < height; ++y) 169 { 170 for (int n_component = 0; n_component < m_n_components; ++n_component) 171 { 172 const unsigned int pixel_size = m_n_components; 173 unsigned char* result_ptr = data + ((y * width + x) * pixel_size + n_component); 174 unsigned int n_color = ((x % m_n_colors_per_layer_face) + y) % m_n_colors_per_layer_face; 175 176 *result_ptr = m_layer_face_data[n_layer][n_color][n_component]; 177 } 178 } 179 } 180 } 181 182 /** Initialize test case **/ 183 void TextureCubeMapArrayGenerateMipMapFilterable::init() 184 { 185 /* Base class initialization */ 186 TestCaseBase::init(); 187 188 /* Check if texture_cube_map_array extension is supported */ 189 if (!m_is_texture_cube_map_array_supported) 190 { 191 throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED); 192 } 193 } 194 195 /** Initializes all ES objects that will be used by the test */ 196 void TextureCubeMapArrayGenerateMipMapFilterable::initTest() 197 { 198 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 199 200 /* Make sure the storage config container is empty */ 201 m_storage_configs.clear(); 202 203 /* Update pixel pack/unpack settings */ 204 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 205 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 206 207 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed"); 208 209 /* Define following texture configurations 210 * 211 * [width x height x depth] 212 * 1) 64 x 64 x 18; 213 * 2) 117 x 117 x 6; 214 * 3) 256 x 256 x 6; 215 * 4) 173 x 173 x 12; 216 * 217 * We use GL_RGBA8 internal format in all cases. 218 */ 219 220 /* Resolution 64 x 64 x 18 */ 221 StorageConfig storage_config_1; 222 223 storage_config_1.m_width = 64; 224 storage_config_1.m_height = 64; 225 storage_config_1.m_depth = 18; 226 storage_config_1.m_to_id = 0; 227 storage_config_1.m_levels = getAmountOfLevelsForTexture(storage_config_1.m_width, storage_config_1.m_height); 228 229 /* Resolution 117 x 117 x 6 */ 230 StorageConfig storage_config_2; 231 232 storage_config_2.m_width = 117; 233 storage_config_2.m_height = 117; 234 storage_config_2.m_depth = 6; 235 storage_config_2.m_to_id = 0; 236 storage_config_2.m_levels = getAmountOfLevelsForTexture(storage_config_2.m_width, storage_config_2.m_height); 237 238 /* Resolution 256 x 256 x 6 */ 239 StorageConfig storage_config_3; 240 241 storage_config_3.m_width = 256; 242 storage_config_3.m_height = 256; 243 storage_config_3.m_depth = 6; 244 storage_config_3.m_to_id = 0; 245 storage_config_3.m_levels = getAmountOfLevelsForTexture(storage_config_3.m_width, storage_config_3.m_height); 246 247 /* Resolution 173 x 173 x 12 */ 248 StorageConfig storage_config_4; 249 250 storage_config_4.m_width = 173; 251 storage_config_4.m_height = 173; 252 storage_config_4.m_depth = 12; 253 storage_config_4.m_to_id = 0; 254 storage_config_4.m_levels = getAmountOfLevelsForTexture(storage_config_4.m_width, storage_config_4.m_height); 255 256 m_storage_configs.push_back(storage_config_1); 257 m_storage_configs.push_back(storage_config_2); 258 m_storage_configs.push_back(storage_config_3); 259 m_storage_configs.push_back(storage_config_4); 260 261 /* Generate and configure a texture object for each storage config. */ 262 for (unsigned int n_storage_config = 0; n_storage_config < m_storage_configs.size(); n_storage_config++) 263 { 264 StorageConfig& config = m_storage_configs[n_storage_config]; 265 266 gl.genTextures(1, &config.m_to_id); 267 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed"); 268 269 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, config.m_to_id); 270 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 271 272 gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 273 gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 274 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed"); 275 276 if (m_storage_type == ST_MUTABLE) 277 { 278 gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, /* level */ 279 GL_RGBA8, config.m_width, config.m_height, config.m_depth, 0, /* border */ 280 GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); 281 282 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D() call failed"); 283 } 284 else 285 { 286 DE_ASSERT(m_storage_type == ST_IMMUTABLE); 287 288 gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, config.m_levels, GL_RGBA8, config.m_width, config.m_height, 289 config.m_depth); 290 291 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed"); 292 } 293 } /* for (all storage configs) */ 294 295 /* Generate a frame-buffer object */ 296 gl.genFramebuffers(1, &m_fbo_id); 297 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed"); 298 } 299 300 /** Executes the test. 301 * 302 * Note the function throws exception should an error occur! 303 * 304 * @return Always STOP. 305 **/ 306 tcu::TestCase::IterateResult TextureCubeMapArrayGenerateMipMapFilterable::iterate() 307 { 308 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 309 310 /* Initialize ES objects we will need to run the test */ 311 initTest(); 312 313 /* Iterate through all configuration descriptors */ 314 unsigned int n_storage_config = 0; 315 316 for (std::vector<StorageConfig>::const_iterator storage_config_iterator = m_storage_configs.begin(); 317 storage_config_iterator != m_storage_configs.end(); storage_config_iterator++, n_storage_config++) 318 { 319 const StorageConfig& storage_config = *storage_config_iterator; 320 321 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, storage_config.m_to_id); 322 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed"); 323 324 /* Fill each base layer-face with pattern data */ 325 for (unsigned int n_layer_face = 0; n_layer_face < storage_config.m_depth; ++n_layer_face) 326 { 327 /* Allocate buffer we will use to store the layer data */ 328 const int data_size = static_cast<int>(storage_config.m_width * storage_config.m_height * m_n_components * 329 sizeof(unsigned char)); 330 unsigned char* data_ptr = new unsigned char[data_size]; 331 332 if (data_ptr == DE_NULL) 333 { 334 TCU_FAIL("Out of memory"); 335 } 336 337 generateTestData(n_layer_face, data_ptr, storage_config.m_width, storage_config.m_height); 338 339 /* Fill base texture-layer Texture */ 340 gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, /* level */ 341 0, /* xoffset */ 342 0, /* yoffset */ 343 n_layer_face, /* zoffset */ 344 storage_config.m_width, storage_config.m_height, 1, /* depth */ 345 GL_RGBA, GL_UNSIGNED_BYTE, data_ptr); 346 347 /* Release the data buffer */ 348 delete[] data_ptr; 349 350 data_ptr = DE_NULL; 351 352 /* Make sure the call was successful */ 353 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed"); 354 } 355 356 /* Generate mip-maps */ 357 gl.generateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY); 358 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed"); 359 360 /* Attach a FBO to GL_READ_FRAMEBUFFER binding point. */ 361 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id); 362 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed"); 363 364 /* Allocate buffers to hold reference & rendered data */ 365 unsigned char last_level_data_buffer[m_n_components] = { 0 }; 366 const unsigned int size = 367 static_cast<int>(storage_config.m_width * storage_config.m_height * m_n_components * sizeof(unsigned char)); 368 369 m_reference_data_ptr = new unsigned char[size]; 370 m_rendered_data_ptr = new unsigned char[size]; 371 372 if (m_reference_data_ptr == DE_NULL || m_rendered_data_ptr == DE_NULL) 373 { 374 TCU_FAIL("Out of memory"); 375 } 376 377 /* Verify correctness of layer-face data */ 378 for (unsigned int n_layer_face = 0; n_layer_face < storage_config.m_depth; ++n_layer_face) 379 { 380 /* Generate reference data */ 381 generateTestData(n_layer_face, m_reference_data_ptr, storage_config.m_width, storage_config.m_height); 382 383 /* Attach iteration-specific base layer-face to the read frame-buffer */ 384 gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, storage_config.m_to_id, 0, /* level */ 385 n_layer_face); 386 387 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed."); 388 389 /* Read the layer-face data */ 390 gl.readPixels(0, /* x */ 391 0, /* y */ 392 storage_config.m_width, storage_config.m_height, GL_RGBA, GL_UNSIGNED_BYTE, 393 m_rendered_data_ptr); 394 395 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed."); 396 397 /* Make sure the base layer-face contents reported with the call is as was uploaded */ 398 const unsigned int base_layer_data_size = static_cast<int>( 399 storage_config.m_width * storage_config.m_height * m_n_components * sizeof(unsigned char)); 400 401 if (memcmp(m_reference_data_ptr, m_rendered_data_ptr, base_layer_data_size)) 402 { 403 m_testCtx.getLog() << tcu::TestLog::Message << "Data stored in base layer mip-map for storage config [" 404 << n_storage_config << "]" 405 "and layer-face index [" 406 << n_layer_face << "]" 407 " is different than was uploaded" 408 << tcu::TestLog::EndMessage; 409 410 TCU_FAIL("Invalid data found for base layer mip-map"); 411 } 412 413 /* Update the read framebuffer's color attachment to read from 414 * the last mip-map available for currently processed layer-face 415 */ 416 gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, storage_config.m_to_id, /* texture */ 417 storage_config.m_levels - 1, /* level */ 418 n_layer_face); /* layer */ 419 420 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed."); 421 422 /* Read the data */ 423 gl.readPixels(0, /* x */ 424 0, /* y */ 425 1, /* width */ 426 1, /* height */ 427 GL_RGBA, GL_UNSIGNED_BYTE, last_level_data_buffer); 428 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed"); 429 430 /* Make sure that the data read from the last layer is not equal to either 431 * of the pattern colors used for the layer-face 432 */ 433 for (int n_pattern_color = 0; n_pattern_color < m_n_colors_per_layer_face; ++n_pattern_color) 434 { 435 if (!memcmp(m_layer_face_data[n_layer_face][n_pattern_color], last_level_data_buffer, 436 m_n_components * sizeof(unsigned char))) 437 { 438 m_testCtx.getLog() 439 << tcu::TestLog::Message << "Texel stored in layer-face's smallest mip-map for storage config [" 440 << n_storage_config << "]" 441 "and layer-face index [" 442 << n_layer_face 443 << "]" 444 "describes one of the colors used for the pattern used in base mip-map, which is invalid." 445 << tcu::TestLog::EndMessage; 446 447 TCU_FAIL("Invalid color found in the layer-face's smallest mip-map"); 448 } 449 } /* for (all pattern colors) */ 450 } /* for (all layer-faces) */ 451 452 /* Release the buffers we allocated specifically for currently processed 453 * storage config. 454 */ 455 if (m_reference_data_ptr != DE_NULL) 456 { 457 delete[] m_reference_data_ptr; 458 459 m_reference_data_ptr = DE_NULL; 460 } 461 462 if (m_rendered_data_ptr != DE_NULL) 463 { 464 delete[] m_rendered_data_ptr; 465 466 m_rendered_data_ptr = DE_NULL; 467 } 468 } /* for (all storage configs) */ 469 470 /* Test has passed */ 471 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 472 return STOP; 473 } 474 475 /** Constructor 476 * 477 * @param context Test context 478 * @param name Test case's name 479 * @param description Test case's description 480 * @param storageType Precises whether texture objects used by this 481 * test instance should be created as immutable or 482 * mutable objects. 483 **/ 484 TextureCubeMapArrayGenerateMipMapNonFilterable::TextureCubeMapArrayGenerateMipMapNonFilterable( 485 Context& context, const ExtParameters& extParams, const char* name, const char* description, 486 STORAGE_TYPE storageType) 487 : TestCaseBase(context, extParams, name, description), m_storage_type(storageType) 488 { 489 /* Nothing to be done here */ 490 } 491 492 /** Deinitialize test case **/ 493 void TextureCubeMapArrayGenerateMipMapNonFilterable::deinit() 494 { 495 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 496 497 /* Restore default bindings */ 498 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); 499 500 /* Restore default pixel pack/unpack settings */ 501 gl.pixelStorei(GL_PACK_ALIGNMENT, 4); 502 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4); 503 504 /* Delete all textures the test may have created. */ 505 for (unsigned int n_storage_config = 0; n_storage_config < m_non_filterable_texture_configs.size(); 506 ++n_storage_config) 507 { 508 if (m_non_filterable_texture_configs[n_storage_config].m_to_id != 0) 509 { 510 gl.deleteTextures(1, &m_non_filterable_texture_configs[n_storage_config].m_to_id); 511 512 m_non_filterable_texture_configs[n_storage_config].m_to_id = 0; 513 } 514 } 515 516 /* Call base class' deinit() implementation */ 517 TestCaseBase::deinit(); 518 } 519 520 /** Initialize test case **/ 521 void TextureCubeMapArrayGenerateMipMapNonFilterable::init() 522 { 523 /* Base class initialization */ 524 TestCaseBase::init(); 525 526 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 527 { 528 throw tcu::NotSupportedError("The test can be run only in ES context"); 529 } 530 531 /* Check if texture_cube_map_array extension is supported */ 532 if (!m_is_texture_cube_map_array_supported) 533 { 534 throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED); 535 } 536 } 537 538 /** Initializes all ES objects used by the test **/ 539 void TextureCubeMapArrayGenerateMipMapNonFilterable::initTest() 540 { 541 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 542 543 /* Make sure no configs are already in place */ 544 m_non_filterable_texture_configs.clear(); 545 546 /* Update pixel pack/unpack settings */ 547 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 548 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 549 550 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed"); 551 552 /* Define a number of storage configurations, all using GL_RGBA32I 553 * internalformat: 554 * 555 * [width x height x depth] 556 * 1) 64 x 64 x 18; 557 * 2) 117 x 117 x 6; 558 * 3) 256 x 256 x 6; 559 * 4) 173 x 173 x 12; 560 */ 561 562 /* Size 64 x 64 x 18 */ 563 StorageConfig storage_config1; 564 565 storage_config1.m_width = 64; 566 storage_config1.m_height = 64; 567 storage_config1.m_depth = 18; 568 storage_config1.m_to_id = 0; 569 storage_config1.m_levels = getAmountOfLevelsForTexture(storage_config1.m_width, storage_config1.m_height); 570 571 /* Size 117 x 117 x 6 */ 572 StorageConfig storage_config2; 573 574 storage_config2.m_width = 117; 575 storage_config2.m_height = 117; 576 storage_config2.m_depth = 6; 577 storage_config2.m_to_id = 0; 578 storage_config2.m_levels = getAmountOfLevelsForTexture(storage_config2.m_width, storage_config2.m_height); 579 580 /* Size 256 x 256 x 6 */ 581 StorageConfig storage_config3; 582 583 storage_config3.m_width = 256; 584 storage_config3.m_height = 256; 585 storage_config3.m_depth = 6; 586 storage_config3.m_to_id = 0; 587 storage_config3.m_levels = getAmountOfLevelsForTexture(storage_config3.m_width, storage_config3.m_height); 588 589 /* Size 173 x 173 x 12 */ 590 StorageConfig storage_config4; 591 592 storage_config4.m_width = 173; 593 storage_config4.m_height = 173; 594 storage_config4.m_depth = 12; 595 storage_config4.m_to_id = 0; 596 storage_config4.m_levels = getAmountOfLevelsForTexture(storage_config4.m_width, storage_config4.m_height); 597 598 m_non_filterable_texture_configs.push_back(storage_config1); 599 m_non_filterable_texture_configs.push_back(storage_config2); 600 m_non_filterable_texture_configs.push_back(storage_config3); 601 m_non_filterable_texture_configs.push_back(storage_config4); 602 603 /* Generate and configure a texture object for each storage config. */ 604 for (std::vector<StorageConfig>::iterator storage_config_iterator = m_non_filterable_texture_configs.begin(); 605 storage_config_iterator != m_non_filterable_texture_configs.end(); storage_config_iterator++) 606 { 607 StorageConfig& storage_config = *storage_config_iterator; 608 609 gl.genTextures(1, &storage_config.m_to_id); 610 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 611 612 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, storage_config.m_to_id); 613 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 614 615 gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 616 gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 617 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed."); 618 619 /* Initialize texture storage. */ 620 if (m_storage_type == ST_MUTABLE) 621 { 622 gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, /* level */ 623 GL_RGBA32I, storage_config.m_width, storage_config.m_height, storage_config.m_depth, 0, 624 GL_RGBA_INTEGER, GL_INT, 0); /* data */ 625 626 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D() call failed."); 627 } 628 else 629 { 630 gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, storage_config.m_levels, GL_RGBA32I, storage_config.m_width, 631 storage_config.m_height, storage_config.m_depth); 632 633 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed."); 634 } 635 } /* for (all storage configs) */ 636 } 637 638 /** Executes the test. 639 * 640 * Note the function throws exception should an error occur! 641 * 642 * @return Always STOP. 643 **/ 644 tcu::TestCase::IterateResult TextureCubeMapArrayGenerateMipMapNonFilterable::iterate() 645 { 646 /* Initialize ES objects used by the test */ 647 initTest(); 648 649 /* Verify that glGenerateMipmap() always throws GL_INVALID_OPERATION, if the 650 * texture object the call would operate on uses non-filterable internalformat. 651 */ 652 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 653 654 for (unsigned int n_storage_config = 0; n_storage_config < m_non_filterable_texture_configs.size(); 655 ++n_storage_config) 656 { 657 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_non_filterable_texture_configs[n_storage_config].m_to_id); 658 659 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 660 661 gl.generateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY); 662 663 /* What's the error code at this point? */ 664 int error_code = gl.getError(); 665 666 if (error_code != GL_INVALID_OPERATION) 667 { 668 m_testCtx.getLog() << tcu::TestLog::Message 669 << "glGenerateMipmap() operating on an non-filterable internalformat " 670 "did not report GL_INVALID_OPERATION as per spec but " 671 << error_code << " instead." << tcu::TestLog::EndMessage; 672 673 TCU_FAIL("Invalid error code reported for an invalid glGenerateMipmap() call."); 674 } 675 } /* for (all storage configs) */ 676 677 /* The test has passed */ 678 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 679 680 return STOP; 681 } 682 683 } /* glcts */ 684