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 **/
getAmountOfLevelsForTexture(int width,int height)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 **/
TextureCubeMapArrayGenerateMipMapFilterable(Context & context,const ExtParameters & extParams,const char * name,const char * description,STORAGE_TYPE storageType)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 **/
deinit()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 */
generateTestData(int n_layer,unsigned char * data,int width,int height)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 **/
init()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 */
initTest()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 **/
iterate()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 **/
TextureCubeMapArrayGenerateMipMapNonFilterable(Context & context,const ExtParameters & extParams,const char * name,const char * description,STORAGE_TYPE storageType)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 **/
deinit()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 **/
init()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 **/
initTest()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 **/
iterate()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