blob: cf27f7b148cea89cb3e87a6a23f25d412a2682af [file] [log] [blame]
/*-------------------------------------------------------------------------
* OpenGL Conformance Test Suite
* -----------------------------
*
* Copyright (c) 2014-2016 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/ /*!
* \file
* \brief
*/ /*-------------------------------------------------------------------*/
/*!
* \file esextcTextureCubeMapArrayGenerateMipMap.cpp
* \brief texture_cube_map_array extenstion - glGenerateMipmap() (Test 7)
*/ /*-------------------------------------------------------------------*/
#include "esextcTextureCubeMapArrayGenerateMipMap.hpp"
#include "gluContextInfo.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"
#include <cmath>
#include <cstring>
#include <vector>
namespace glcts
{
/* Defines two pattern colors for each layer-face */
const unsigned char TextureCubeMapArrayGenerateMipMapFilterable::m_layer_face_data
[m_n_max_faces][m_n_colors_per_layer_face][m_n_components] = {
/* Color 1 --- Color 2 */
{ { 0, 0, 0, 0 }, { 255, 255, 255, 255 } }, /* Layer-face 0 */
{ { 255, 0, 0, 0 }, { 0, 255, 255, 255 } }, /* Layer-face 1 */
{ { 0, 255, 0, 0 }, { 255, 0, 255, 255 } }, /* Layer-face 2 */
{ { 0, 0, 255, 0 }, { 255, 255, 0, 255 } }, /* Layer-face 3 */
{ { 0, 0, 0, 255 }, { 255, 255, 255, 0 } }, /* Layer-face 4 */
{ { 255, 255, 0, 0 }, { 0, 0, 255, 255 } }, /* Layer-face 5 */
{ { 255, 0, 255, 0 }, { 0, 255, 0, 255 } }, /* Layer-face 6 */
{ { 255, 0, 0, 255 }, { 0, 255, 255, 0 } }, /* Layer-face 7 */
{ { 0, 255, 255, 0 }, { 255, 0, 0, 255 } }, /* Layer-face 8 */
{ { 0, 255, 0, 255 }, { 255, 0, 255, 0 } }, /* Layer-face 9 */
{ { 255, 255, 255, 0 }, { 0, 0, 0, 255 } }, /* Layer-face 10 */
{ { 255, 255, 0, 255 }, { 0, 0, 255, 0 } }, /* Layer-face 11 */
{ { 255, 255, 255, 255 }, { 0, 0, 0, 0 } }, /* Layer-face 12 */
{ { 0, 0, 0, 255 }, { 255, 0, 0, 0 } }, /* Layer-face 13 */
{ { 0, 0, 0, 255 }, { 255, 255, 0, 0 } }, /* Layer-face 14 */
{ { 0, 0, 255, 0 }, { 255, 255, 255, 0 } }, /* Layer-face 15 */
{ { 0, 255, 0, 0 }, { 255, 255, 255, 255 } }, /* Layer-face 16 */
{ { 255, 0, 0, 0 }, { 255, 0, 255, 255 } } /* Layer-face 17 */
};
/** Retrieves maximum amount of levels that should be defined for
* a texture of user-provided dimensions.
*
* @param width Width of the texture in question.
* @param height Height of the texture in question.
*
* @return Requested value.
**/
static int getAmountOfLevelsForTexture(int width, int height)
{
return (int)floor(log((float)(de::max(width, height))) / log(2.0f)) + 1;
}
/** Constructor
*
* @param context Test context;
* @param name Test case's name;
* @param description Test case's description;
* @param storageType Precises whether texture objects used by this
* test instance should be created as immutable or
* mutable objects.
**/
TextureCubeMapArrayGenerateMipMapFilterable::TextureCubeMapArrayGenerateMipMapFilterable(Context& context,
const ExtParameters& extParams,
const char* name,
const char* description,
STORAGE_TYPE storageType)
: TestCaseBase(context, extParams, name, description)
, m_fbo_id(0)
, m_storage_type(storageType)
, m_reference_data_ptr(DE_NULL)
, m_rendered_data_ptr(DE_NULL)
{
/* Nothing to be done here */
}
/** Deinitialize test case **/
void TextureCubeMapArrayGenerateMipMapFilterable::deinit()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Reset texture and FBO bindings */
gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
/* Release any ES objects that may have been created. */
if (m_fbo_id != 0)
{
gl.deleteFramebuffers(1, &m_fbo_id);
m_fbo_id = 0;
}
for (unsigned int i = 0; i < m_storage_configs.size(); ++i)
{
if (m_storage_configs[i].m_to_id != 0)
{
gl.deleteTextures(1, &m_storage_configs[i].m_to_id);
m_storage_configs[i].m_to_id = 0;
}
}
/* Release buffers the test may have allocated */
if (m_reference_data_ptr != DE_NULL)
{
delete[] m_reference_data_ptr;
m_reference_data_ptr = DE_NULL;
}
if (m_rendered_data_ptr != DE_NULL)
{
delete[] m_rendered_data_ptr;
m_rendered_data_ptr = DE_NULL;
}
/* Restore pixel pack/unpack settings */
gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4);
/* Call base class' deinitialization routine. */
TestCaseBase::deinit();
}
/** Fills user-provided buffer with expected pixel data for user-specified
* layer index.
*
* @param n_layer Layer index to return expected data for.
* @param data Pointer to a buffer that will be filled with
* result data. Must not be NULL.
* @param width Render-target width.
* @param height Render-target height.
*/
void TextureCubeMapArrayGenerateMipMapFilterable::generateTestData(int n_layer, unsigned char* data, int width,
int height)
{
DE_ASSERT(data != DE_NULL);
for (int x = 0; x < width; ++x)
{
for (int y = 0; y < height; ++y)
{
for (int n_component = 0; n_component < m_n_components; ++n_component)
{
const unsigned int pixel_size = m_n_components;
unsigned char* result_ptr = data + ((y * width + x) * pixel_size + n_component);
unsigned int n_color = ((x % m_n_colors_per_layer_face) + y) % m_n_colors_per_layer_face;
*result_ptr = m_layer_face_data[n_layer][n_color][n_component];
}
}
}
}
/** Initialize test case **/
void TextureCubeMapArrayGenerateMipMapFilterable::init()
{
/* Base class initialization */
TestCaseBase::init();
/* Check if texture_cube_map_array extension is supported */
if (!m_is_texture_cube_map_array_supported)
{
throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED);
}
}
/** Initializes all ES objects that will be used by the test */
void TextureCubeMapArrayGenerateMipMapFilterable::initTest()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Make sure the storage config container is empty */
m_storage_configs.clear();
/* Update pixel pack/unpack settings */
gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed");
/* Define following texture configurations
*
* [width x height x depth]
* 1) 64 x 64 x 18;
* 2) 117 x 117 x 6;
* 3) 256 x 256 x 6;
* 4) 173 x 173 x 12;
*
* We use GL_RGBA8 internal format in all cases.
*/
/* Resolution 64 x 64 x 18 */
StorageConfig storage_config_1;
storage_config_1.m_width = 64;
storage_config_1.m_height = 64;
storage_config_1.m_depth = 18;
storage_config_1.m_to_id = 0;
storage_config_1.m_levels = getAmountOfLevelsForTexture(storage_config_1.m_width, storage_config_1.m_height);
/* Resolution 117 x 117 x 6 */
StorageConfig storage_config_2;
storage_config_2.m_width = 117;
storage_config_2.m_height = 117;
storage_config_2.m_depth = 6;
storage_config_2.m_to_id = 0;
storage_config_2.m_levels = getAmountOfLevelsForTexture(storage_config_2.m_width, storage_config_2.m_height);
/* Resolution 256 x 256 x 6 */
StorageConfig storage_config_3;
storage_config_3.m_width = 256;
storage_config_3.m_height = 256;
storage_config_3.m_depth = 6;
storage_config_3.m_to_id = 0;
storage_config_3.m_levels = getAmountOfLevelsForTexture(storage_config_3.m_width, storage_config_3.m_height);
/* Resolution 173 x 173 x 12 */
StorageConfig storage_config_4;
storage_config_4.m_width = 173;
storage_config_4.m_height = 173;
storage_config_4.m_depth = 12;
storage_config_4.m_to_id = 0;
storage_config_4.m_levels = getAmountOfLevelsForTexture(storage_config_4.m_width, storage_config_4.m_height);
m_storage_configs.push_back(storage_config_1);
m_storage_configs.push_back(storage_config_2);
m_storage_configs.push_back(storage_config_3);
m_storage_configs.push_back(storage_config_4);
/* Generate and configure a texture object for each storage config. */
for (unsigned int n_storage_config = 0; n_storage_config < m_storage_configs.size(); n_storage_config++)
{
StorageConfig& config = m_storage_configs[n_storage_config];
gl.genTextures(1, &config.m_to_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, config.m_to_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed");
if (m_storage_type == ST_MUTABLE)
{
gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, /* level */
GL_RGBA8, config.m_width, config.m_height, config.m_depth, 0, /* border */
GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D() call failed");
}
else
{
DE_ASSERT(m_storage_type == ST_IMMUTABLE);
gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, config.m_levels, GL_RGBA8, config.m_width, config.m_height,
config.m_depth);
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed");
}
} /* for (all storage configs) */
/* Generate a frame-buffer object */
gl.genFramebuffers(1, &m_fbo_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed");
}
/** Executes the test.
*
* Note the function throws exception should an error occur!
*
* @return Always STOP.
**/
tcu::TestCase::IterateResult TextureCubeMapArrayGenerateMipMapFilterable::iterate()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Initialize ES objects we will need to run the test */
initTest();
/* Iterate through all configuration descriptors */
unsigned int n_storage_config = 0;
for (std::vector<StorageConfig>::const_iterator storage_config_iterator = m_storage_configs.begin();
storage_config_iterator != m_storage_configs.end(); storage_config_iterator++, n_storage_config++)
{
const StorageConfig& storage_config = *storage_config_iterator;
gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, storage_config.m_to_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
/* Fill each base layer-face with pattern data */
for (unsigned int n_layer_face = 0; n_layer_face < storage_config.m_depth; ++n_layer_face)
{
/* Allocate buffer we will use to store the layer data */
const int data_size = static_cast<int>(storage_config.m_width * storage_config.m_height * m_n_components *
sizeof(unsigned char));
unsigned char* data_ptr = new unsigned char[data_size];
if (data_ptr == DE_NULL)
{
TCU_FAIL("Out of memory");
}
generateTestData(n_layer_face, data_ptr, storage_config.m_width, storage_config.m_height);
/* Fill base texture-layer Texture */
gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, /* level */
0, /* xoffset */
0, /* yoffset */
n_layer_face, /* zoffset */
storage_config.m_width, storage_config.m_height, 1, /* depth */
GL_RGBA, GL_UNSIGNED_BYTE, data_ptr);
/* Release the data buffer */
delete[] data_ptr;
data_ptr = DE_NULL;
/* Make sure the call was successful */
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed");
}
/* Generate mip-maps */
gl.generateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed");
/* Attach a FBO to GL_READ_FRAMEBUFFER binding point. */
gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed");
/* Allocate buffers to hold reference & rendered data */
unsigned char last_level_data_buffer[m_n_components] = { 0 };
const unsigned int size =
static_cast<int>(storage_config.m_width * storage_config.m_height * m_n_components * sizeof(unsigned char));
m_reference_data_ptr = new unsigned char[size];
m_rendered_data_ptr = new unsigned char[size];
if (m_reference_data_ptr == DE_NULL || m_rendered_data_ptr == DE_NULL)
{
TCU_FAIL("Out of memory");
}
/* Verify correctness of layer-face data */
for (unsigned int n_layer_face = 0; n_layer_face < storage_config.m_depth; ++n_layer_face)
{
/* Generate reference data */
generateTestData(n_layer_face, m_reference_data_ptr, storage_config.m_width, storage_config.m_height);
/* Attach iteration-specific base layer-face to the read frame-buffer */
gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, storage_config.m_to_id, 0, /* level */
n_layer_face);
GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
/* Read the layer-face data */
gl.readPixels(0, /* x */
0, /* y */
storage_config.m_width, storage_config.m_height, GL_RGBA, GL_UNSIGNED_BYTE,
m_rendered_data_ptr);
GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
/* Make sure the base layer-face contents reported with the call is as was uploaded */
const unsigned int base_layer_data_size = static_cast<int>(
storage_config.m_width * storage_config.m_height * m_n_components * sizeof(unsigned char));
if (memcmp(m_reference_data_ptr, m_rendered_data_ptr, base_layer_data_size))
{
m_testCtx.getLog() << tcu::TestLog::Message << "Data stored in base layer mip-map for storage config ["
<< n_storage_config << "]"
"and layer-face index ["
<< n_layer_face << "]"
" is different than was uploaded"
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid data found for base layer mip-map");
}
/* Update the read framebuffer's color attachment to read from
* the last mip-map available for currently processed layer-face
*/
gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, storage_config.m_to_id, /* texture */
storage_config.m_levels - 1, /* level */
n_layer_face); /* layer */
GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
/* Read the data */
gl.readPixels(0, /* x */
0, /* y */
1, /* width */
1, /* height */
GL_RGBA, GL_UNSIGNED_BYTE, last_level_data_buffer);
GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
/* Make sure that the data read from the last layer is not equal to either
* of the pattern colors used for the layer-face
*/
for (int n_pattern_color = 0; n_pattern_color < m_n_colors_per_layer_face; ++n_pattern_color)
{
if (!memcmp(m_layer_face_data[n_layer_face][n_pattern_color], last_level_data_buffer,
m_n_components * sizeof(unsigned char)))
{
m_testCtx.getLog()
<< tcu::TestLog::Message << "Texel stored in layer-face's smallest mip-map for storage config ["
<< n_storage_config << "]"
"and layer-face index ["
<< n_layer_face
<< "]"
"describes one of the colors used for the pattern used in base mip-map, which is invalid."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid color found in the layer-face's smallest mip-map");
}
} /* for (all pattern colors) */
} /* for (all layer-faces) */
/* Release the buffers we allocated specifically for currently processed
* storage config.
*/
if (m_reference_data_ptr != DE_NULL)
{
delete[] m_reference_data_ptr;
m_reference_data_ptr = DE_NULL;
}
if (m_rendered_data_ptr != DE_NULL)
{
delete[] m_rendered_data_ptr;
m_rendered_data_ptr = DE_NULL;
}
} /* for (all storage configs) */
/* Test has passed */
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
return STOP;
}
/** Constructor
*
* @param context Test context
* @param name Test case's name
* @param description Test case's description
* @param storageType Precises whether texture objects used by this
* test instance should be created as immutable or
* mutable objects.
**/
TextureCubeMapArrayGenerateMipMapNonFilterable::TextureCubeMapArrayGenerateMipMapNonFilterable(
Context& context, const ExtParameters& extParams, const char* name, const char* description,
STORAGE_TYPE storageType)
: TestCaseBase(context, extParams, name, description), m_storage_type(storageType)
{
/* Nothing to be done here */
}
/** Deinitialize test case **/
void TextureCubeMapArrayGenerateMipMapNonFilterable::deinit()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Restore default bindings */
gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
/* Restore default pixel pack/unpack settings */
gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4);
/* Delete all textures the test may have created. */
for (unsigned int n_storage_config = 0; n_storage_config < m_non_filterable_texture_configs.size();
++n_storage_config)
{
if (m_non_filterable_texture_configs[n_storage_config].m_to_id != 0)
{
gl.deleteTextures(1, &m_non_filterable_texture_configs[n_storage_config].m_to_id);
m_non_filterable_texture_configs[n_storage_config].m_to_id = 0;
}
}
/* Call base class' deinit() implementation */
TestCaseBase::deinit();
}
/** Initialize test case **/
void TextureCubeMapArrayGenerateMipMapNonFilterable::init()
{
/* Base class initialization */
TestCaseBase::init();
if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
{
throw tcu::NotSupportedError("The test can be run only in ES context");
}
/* Check if texture_cube_map_array extension is supported */
if (!m_is_texture_cube_map_array_supported)
{
throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED);
}
}
/** Initializes all ES objects used by the test **/
void TextureCubeMapArrayGenerateMipMapNonFilterable::initTest()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Make sure no configs are already in place */
m_non_filterable_texture_configs.clear();
/* Update pixel pack/unpack settings */
gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed");
/* Define a number of storage configurations, all using GL_RGBA32I
* internalformat:
*
* [width x height x depth]
* 1) 64 x 64 x 18;
* 2) 117 x 117 x 6;
* 3) 256 x 256 x 6;
* 4) 173 x 173 x 12;
*/
/* Size 64 x 64 x 18 */
StorageConfig storage_config1;
storage_config1.m_width = 64;
storage_config1.m_height = 64;
storage_config1.m_depth = 18;
storage_config1.m_to_id = 0;
storage_config1.m_levels = getAmountOfLevelsForTexture(storage_config1.m_width, storage_config1.m_height);
/* Size 117 x 117 x 6 */
StorageConfig storage_config2;
storage_config2.m_width = 117;
storage_config2.m_height = 117;
storage_config2.m_depth = 6;
storage_config2.m_to_id = 0;
storage_config2.m_levels = getAmountOfLevelsForTexture(storage_config2.m_width, storage_config2.m_height);
/* Size 256 x 256 x 6 */
StorageConfig storage_config3;
storage_config3.m_width = 256;
storage_config3.m_height = 256;
storage_config3.m_depth = 6;
storage_config3.m_to_id = 0;
storage_config3.m_levels = getAmountOfLevelsForTexture(storage_config3.m_width, storage_config3.m_height);
/* Size 173 x 173 x 12 */
StorageConfig storage_config4;
storage_config4.m_width = 173;
storage_config4.m_height = 173;
storage_config4.m_depth = 12;
storage_config4.m_to_id = 0;
storage_config4.m_levels = getAmountOfLevelsForTexture(storage_config4.m_width, storage_config4.m_height);
m_non_filterable_texture_configs.push_back(storage_config1);
m_non_filterable_texture_configs.push_back(storage_config2);
m_non_filterable_texture_configs.push_back(storage_config3);
m_non_filterable_texture_configs.push_back(storage_config4);
/* Generate and configure a texture object for each storage config. */
for (std::vector<StorageConfig>::iterator storage_config_iterator = m_non_filterable_texture_configs.begin();
storage_config_iterator != m_non_filterable_texture_configs.end(); storage_config_iterator++)
{
StorageConfig& storage_config = *storage_config_iterator;
gl.genTextures(1, &storage_config.m_to_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, storage_config.m_to_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed.");
/* Initialize texture storage. */
if (m_storage_type == ST_MUTABLE)
{
gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, /* level */
GL_RGBA32I, storage_config.m_width, storage_config.m_height, storage_config.m_depth, 0,
GL_RGBA_INTEGER, GL_INT, 0); /* data */
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D() call failed.");
}
else
{
gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, storage_config.m_levels, GL_RGBA32I, storage_config.m_width,
storage_config.m_height, storage_config.m_depth);
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
}
} /* for (all storage configs) */
}
/** Executes the test.
*
* Note the function throws exception should an error occur!
*
* @return Always STOP.
**/
tcu::TestCase::IterateResult TextureCubeMapArrayGenerateMipMapNonFilterable::iterate()
{
/* Initialize ES objects used by the test */
initTest();
/* Verify that glGenerateMipmap() always throws GL_INVALID_OPERATION, if the
* texture object the call would operate on uses non-filterable internalformat.
*/
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
for (unsigned int n_storage_config = 0; n_storage_config < m_non_filterable_texture_configs.size();
++n_storage_config)
{
gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_non_filterable_texture_configs[n_storage_config].m_to_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
gl.generateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY);
/* What's the error code at this point? */
int error_code = gl.getError();
if (error_code != GL_INVALID_OPERATION)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "glGenerateMipmap() operating on an non-filterable internalformat "
"did not report GL_INVALID_OPERATION as per spec but "
<< error_code << " instead." << tcu::TestLog::EndMessage;
TCU_FAIL("Invalid error code reported for an invalid glGenerateMipmap() call.");
}
} /* for (all storage configs) */
/* The test has passed */
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
return STOP;
}
} /* glcts */