blob: 68bf5ab56beb350c4f48009ee4d38a6d95bd9f34 [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 gl4cTextureViewTests.cpp
* \brief Implements conformance tests for "texture view" functionality.
*/ /*-------------------------------------------------------------------*/
#include "gl4cTextureViewTests.hpp"
#include "deFloat16.h"
#include "deMath.h"
#include "gluContextInfo.hpp"
#include "glwFunctions.hpp"
#include "tcuFloat.hpp"
#include "tcuTestLog.hpp"
#include <algorithm>
/* Type definitions needed to handle GL_R11F_G11F_B10F internal format */
typedef tcu::Float<deUint32, 5, 5, 15, 0> Float10;
typedef tcu::Float<deUint32, 5, 6, 15, 0> Float11;
namespace gl4cts
{
using namespace TextureView;
/** Stores internalformat->view class associations */
const int internalformat_view_compatibility_array[] = {
/* [internalformat] [view class] */
GL_RGBA32F, VIEW_CLASS_128_BITS, GL_RGBA32UI, VIEW_CLASS_128_BITS, GL_RGBA32I, VIEW_CLASS_128_BITS, GL_RGB32F,
VIEW_CLASS_96_BITS, GL_RGB32UI, VIEW_CLASS_96_BITS, GL_RGB32I, VIEW_CLASS_96_BITS, GL_RGBA16F, VIEW_CLASS_64_BITS,
GL_RG32F, VIEW_CLASS_64_BITS, GL_RGBA16UI, VIEW_CLASS_64_BITS, GL_RG32UI, VIEW_CLASS_64_BITS, GL_RGBA16I,
VIEW_CLASS_64_BITS, GL_RG32I, VIEW_CLASS_64_BITS, GL_RGBA16, VIEW_CLASS_64_BITS, GL_RGBA16_SNORM,
VIEW_CLASS_64_BITS, GL_RGB16, VIEW_CLASS_48_BITS, GL_RGB16_SNORM, VIEW_CLASS_48_BITS, GL_RGB16F, VIEW_CLASS_48_BITS,
GL_RGB16UI, VIEW_CLASS_48_BITS, GL_RGB16I, VIEW_CLASS_48_BITS, GL_RG16F, VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F,
VIEW_CLASS_32_BITS, GL_R32F, VIEW_CLASS_32_BITS, GL_RGB10_A2UI, VIEW_CLASS_32_BITS, GL_RGBA8UI, VIEW_CLASS_32_BITS,
GL_RG16UI, VIEW_CLASS_32_BITS, GL_R32UI, VIEW_CLASS_32_BITS, GL_RGBA8I, VIEW_CLASS_32_BITS, GL_RG16I,
VIEW_CLASS_32_BITS, GL_R32I, VIEW_CLASS_32_BITS, GL_RGB10_A2, VIEW_CLASS_32_BITS, GL_RGBA8, VIEW_CLASS_32_BITS,
GL_RG16, VIEW_CLASS_32_BITS, GL_RGBA8_SNORM, VIEW_CLASS_32_BITS, GL_RG16_SNORM, VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8,
VIEW_CLASS_32_BITS, GL_RGB9_E5, VIEW_CLASS_32_BITS, GL_RGB8, VIEW_CLASS_24_BITS, GL_RGB8_SNORM, VIEW_CLASS_24_BITS,
GL_SRGB8, VIEW_CLASS_24_BITS, GL_RGB8UI, VIEW_CLASS_24_BITS, GL_RGB8I, VIEW_CLASS_24_BITS, GL_R16F,
VIEW_CLASS_16_BITS, GL_RG8UI, VIEW_CLASS_16_BITS, GL_R16UI, VIEW_CLASS_16_BITS, GL_RG8I, VIEW_CLASS_16_BITS,
GL_R16I, VIEW_CLASS_16_BITS, GL_RG8, VIEW_CLASS_16_BITS, GL_R16, VIEW_CLASS_16_BITS, GL_RG8_SNORM,
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,
VIEW_CLASS_8_BITS, GL_R8_SNORM, VIEW_CLASS_8_BITS,
/* Compressed texture formats. */
GL_COMPRESSED_RED_RGTC1, VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1, VIEW_CLASS_RGTC1_RED,
GL_COMPRESSED_RG_RGTC2, VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2, VIEW_CLASS_RGTC2_RG,
GL_COMPRESSED_RGBA_BPTC_UNORM, VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, VIEW_CLASS_BPTC_UNORM,
GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
VIEW_CLASS_BPTC_FLOAT
};
const int n_internalformat_view_compatibility_array_entries =
sizeof(internalformat_view_compatibility_array) / sizeof(internalformat_view_compatibility_array[0]);
/** Stores all internalformats valid in OpenGL 4.x. Information whether particular internalformat
* can be considered supported can be retrieved by calling TextureViewTests::isInternalformatSupported()
* function.
*/
const glw::GLenum valid_gl_internalformats[] = {
/* Section 8.5.1 */
GL_RGBA32F, /* >= GL 4.0 */
GL_RGBA32I, /* >= GL 4.0 */
GL_RGBA32UI, /* >= GL 4.0 */
GL_RGBA16, /* >= GL 4.0 */
GL_RGBA16F, /* >= GL 4.0 */
GL_RGBA16I, /* >= GL 4.0 */
GL_RGBA16UI, /* >= GL 4.0 */
GL_RGBA8, /* >= GL 4.0 */
GL_RGBA8I, /* >= GL 4.0 */
GL_RGBA8UI, /* >= GL 4.0 */
GL_SRGB8_ALPHA8, /* >= GL 4.0 */
GL_RGB10_A2, /* >= GL 4.0 */
GL_RGB10_A2UI, /* >= GL 4.0 */
GL_RGB5_A1, /* >= GL 4.0 */
GL_RGBA4, /* >= GL 4.0 */
GL_R11F_G11F_B10F, /* >= GL 4.0 */
GL_RGB565, /* >= GL 4.2 */
GL_RG32F, /* >= GL 4.0 */
GL_RG32I, /* >= GL 4.0 */
GL_RG32UI, /* >= GL 4.0 */
GL_RG16, /* >= GL 4.0 */
GL_RG16F, /* >= GL 4.0 */
GL_RG16I, /* >= GL 4.0 */
GL_RG16UI, /* >= GL 4.0 */
GL_RG8, /* >= GL 4.0 */
GL_RG8I, /* >= GL 4.0 */
GL_RG8UI, /* >= GL 4.0 */
GL_R32F, /* >= GL 4.0 */
GL_R32I, /* >= GL 4.0 */
GL_R32UI, /* >= GL 4.0 */
GL_R16F, /* >= GL 4.0 */
GL_R16I, /* >= GL 4.0 */
GL_R16UI, /* >= GL 4.0 */
GL_R16, /* >= GL 4.0 */
GL_R8, /* >= GL 4.0 */
GL_R8I, /* >= GL 4.0 */
GL_R8UI, /* >= GL 4.0 */
GL_RGBA16_SNORM, /* >= GL 4.0 */
GL_RGBA8_SNORM, /* >= GL 4.0 */
GL_RGB32F, /* >= GL 4.0 */
GL_RGB32I, /* >= GL 4.0 */
GL_RGB32UI, /* >= GL 4.0 */
GL_RGB16_SNORM, /* >= GL 4.0 */
GL_RGB16F, /* >= GL 4.0 */
GL_RGB16I, /* >= GL 4.0 */
GL_RGB16UI, /* >= GL 4.0 */
GL_RGB16, /* >= GL 4.0 */
GL_RGB8_SNORM, /* >= GL 4.0 */
GL_RGB8, /* >= GL 4.0 */
GL_RGB8I, /* >= GL 4.0 */
GL_RGB8UI, /* >= GL 4.0 */
GL_SRGB8, /* >= GL 4.0 */
GL_RGB9_E5, /* >= GL 4.0 */
GL_RG16_SNORM, /* >= GL 4.0 */
GL_RG8_SNORM, /* >= GL 4.0 */
GL_R16_SNORM, /* >= GL 4.0 */
GL_R8_SNORM, /* >= GL 4.0 */
GL_DEPTH_COMPONENT32F, /* >= GL 4.0 */
GL_DEPTH_COMPONENT24, /* >= GL 4.0 */
GL_DEPTH_COMPONENT16, /* >= GL 4.0 */
GL_DEPTH32F_STENCIL8, /* >= GL 4.0 */
GL_DEPTH24_STENCIL8, /* >= GL 4.0 */
/* Table 8.14: generic compressed internalformats have been removed */
GL_COMPRESSED_RED_RGTC1, /* >= GL 4.0 */
GL_COMPRESSED_SIGNED_RED_RGTC1, /* >= GL 4.0 */
GL_COMPRESSED_RG_RGTC2, /* >= GL 4.0 */
GL_COMPRESSED_SIGNED_RG_RGTC2, /* >= GL 4.0 */
GL_COMPRESSED_RGBA_BPTC_UNORM, /* >= GL 4.2 */
GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, /* >= GL 4.2 */
GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, /* >= GL 4.2 */
GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, /* >= GL 4.2 */
GL_COMPRESSED_RGB8_ETC2, /* >= GL 4.3 */
GL_COMPRESSED_SRGB8_ETC2, /* >= GL 4.3 */
GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, /* >= GL 4.3 */
GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, /* >= GL 4.3 */
GL_COMPRESSED_RGBA8_ETC2_EAC, /* >= GL 4.3 */
GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, /* >= GL 4.3 */
GL_COMPRESSED_R11_EAC, /* >= GL 4.3 */
GL_COMPRESSED_SIGNED_R11_EAC, /* >= GL 4.3 */
GL_COMPRESSED_RG11_EAC, /* >= GL 4.3 */
GL_COMPRESSED_SIGNED_RG11_EAC, /* >= GL 4.3 */
};
const int n_valid_gl_internalformats = sizeof(valid_gl_internalformats) / sizeof(valid_gl_internalformats[0]);
/** An array of texture targets that is used by a number of TextureViewUtilities methods. */
static glw::GLenum valid_texture_targets[] = { GL_TEXTURE_1D,
GL_TEXTURE_1D_ARRAY,
GL_TEXTURE_2D,
GL_TEXTURE_2D_ARRAY,
GL_TEXTURE_2D_MULTISAMPLE,
GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
GL_TEXTURE_3D,
GL_TEXTURE_BUFFER,
GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_CUBE_MAP_ARRAY,
GL_TEXTURE_RECTANGLE };
const unsigned int n_valid_texture_targets = sizeof(valid_texture_targets) / sizeof(valid_texture_targets[0]);
/** Retrieves amount of components defined by user-specified internalformat.
*
* This function throws TestError exception if @param internalformat is not recognized.
*
* @param internalformat Internalformat to use for the query.
*
* @return Requested value.
**/
unsigned int TextureViewUtilities::getAmountOfComponentsForInternalformat(const glw::GLenum internalformat)
{
unsigned int result = 0;
switch (internalformat)
{
case GL_COMPRESSED_RGBA_BPTC_UNORM:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
case GL_RGB10_A2:
case GL_RGB10_A2UI:
case GL_RGB5_A1:
case GL_RGBA16F:
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGBA16:
case GL_RGBA16_SNORM:
case GL_RGBA32F:
case GL_RGBA32I:
case GL_RGBA32UI:
case GL_RGBA4:
case GL_RGBA8I:
case GL_RGBA8UI:
case GL_RGBA8:
case GL_RGBA8_SNORM:
case GL_SRGB8_ALPHA8:
{
result = 4;
break;
}
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
case GL_R11F_G11F_B10F:
case GL_RGB16_SNORM:
case GL_RGB16F:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGB16:
case GL_RGB32F:
case GL_RGB32I:
case GL_RGB32UI:
case GL_RGB565:
case GL_RGB8:
case GL_RGB8_SNORM:
case GL_RGB8I:
case GL_RGB8UI:
case GL_RGB9_E5:
case GL_SRGB8:
{
result = 3;
break;
}
case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SIGNED_RG_RGTC2:
case GL_RG16:
case GL_RG16F:
case GL_RG16I:
case GL_RG16UI:
case GL_RG16_SNORM:
case GL_RG32F:
case GL_RG32I:
case GL_RG32UI:
case GL_RG8:
case GL_RG8_SNORM:
case GL_RG8I:
case GL_RG8UI:
{
result = 2;
break;
}
case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_SIGNED_RED_RGTC1:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH32F_STENCIL8: /* only one piece of information can be retrieved at a time */
case GL_DEPTH24_STENCIL8: /* only one piece of information can be retrieved at a time */
case GL_R16:
case GL_R16_SNORM:
case GL_R16F:
case GL_R16I:
case GL_R16UI:
case GL_R32F:
case GL_R32I:
case GL_R32UI:
case GL_R8_SNORM:
case GL_R8:
case GL_R8I:
case GL_R8UI:
{
result = 1;
break;
}
default:
{
TCU_FAIL("Unrecognized internalformat");
}
} /* switch (interalformat) */
return result;
}
/** Retrieves block size used by user-specified compressed internalformat.
*
* Throws TestError exception if @param internalformat is not recognized.
*
* @param internalformat Compressed internalformat to use for the query.
*
* @return Requested information (in bytes).
**/
unsigned int TextureViewUtilities::getBlockSizeForCompressedInternalformat(const glw::GLenum internalformat)
{
unsigned int result = 0;
switch (internalformat)
{
case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_SIGNED_RED_RGTC1:
{
result = 8;
break;
}
case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SIGNED_RG_RGTC2:
case GL_COMPRESSED_RGBA_BPTC_UNORM:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
{
result = 16;
break;
}
default:
{
TCU_FAIL("Unrecognized internalformat");
}
} /* switch (internalformat) */
return result;
}
/** Retrieves amount of bits used for R/G/B/A components by user-specified
* *non-compressed* internalformat.
*
* Throws TestError exception if @param internalformat is not recognized.
*
* @param internalformat Internalformat to use for the query. Must not describe
* compressed internalformat.
* @param out_rgba_size Must be spacious enough to hold 4 ints. Deref will be
* used to store requested information for R/G/B/A channels.
* Must not be NULL.
**/
void TextureViewUtilities::getComponentSizeForInternalformat(const glw::GLenum internalformat,
unsigned int* out_rgba_size)
{
/* Note: Compressed textures are not supported by this function */
/* Reset all the values before we continue. */
memset(out_rgba_size, 0, 4 /* rgba */ * sizeof(unsigned int));
/* Depending on the user-specified internalformat, update relevant arguments */
switch (internalformat)
{
case GL_RGBA32F:
case GL_RGBA32I:
case GL_RGBA32UI:
{
out_rgba_size[0] = 32;
out_rgba_size[1] = 32;
out_rgba_size[2] = 32;
out_rgba_size[3] = 32;
break;
}
case GL_RGBA16F:
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGBA16:
case GL_RGBA16_SNORM:
{
out_rgba_size[0] = 16;
out_rgba_size[1] = 16;
out_rgba_size[2] = 16;
out_rgba_size[3] = 16;
break;
}
case GL_RGBA8I:
case GL_RGBA8UI:
case GL_RGBA8:
case GL_RGBA8_SNORM:
case GL_SRGB8_ALPHA8:
{
out_rgba_size[0] = 8;
out_rgba_size[1] = 8;
out_rgba_size[2] = 8;
out_rgba_size[3] = 8;
break;
}
case GL_RGB10_A2:
case GL_RGB10_A2UI:
{
out_rgba_size[0] = 10;
out_rgba_size[1] = 10;
out_rgba_size[2] = 10;
out_rgba_size[3] = 2;
break;
}
case GL_RGB5_A1:
{
out_rgba_size[0] = 5;
out_rgba_size[1] = 5;
out_rgba_size[2] = 5;
out_rgba_size[3] = 1;
break;
}
case GL_RGBA4:
{
out_rgba_size[0] = 4;
out_rgba_size[1] = 4;
out_rgba_size[2] = 4;
out_rgba_size[3] = 4;
break;
}
case GL_RGB9_E5:
{
out_rgba_size[0] = 9;
out_rgba_size[1] = 9;
out_rgba_size[2] = 9;
out_rgba_size[3] = 5;
break;
}
case GL_R11F_G11F_B10F:
{
out_rgba_size[0] = 11;
out_rgba_size[1] = 11;
out_rgba_size[2] = 10;
break;
}
case GL_RGB565:
{
out_rgba_size[0] = 5;
out_rgba_size[1] = 6;
out_rgba_size[2] = 5;
break;
}
case GL_RGB32F:
case GL_RGB32I:
case GL_RGB32UI:
{
out_rgba_size[0] = 32;
out_rgba_size[1] = 32;
out_rgba_size[2] = 32;
break;
}
case GL_RGB16_SNORM:
case GL_RGB16F:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGB16:
{
out_rgba_size[0] = 16;
out_rgba_size[1] = 16;
out_rgba_size[2] = 16;
break;
}
case GL_RGB8_SNORM:
case GL_RGB8:
case GL_RGB8I:
case GL_RGB8UI:
case GL_SRGB8:
{
out_rgba_size[0] = 8;
out_rgba_size[1] = 8;
out_rgba_size[2] = 8;
break;
}
case GL_RG32F:
case GL_RG32I:
case GL_RG32UI:
{
out_rgba_size[0] = 32;
out_rgba_size[1] = 32;
break;
}
case GL_RG16:
case GL_RG16F:
case GL_RG16I:
case GL_RG16UI:
case GL_RG16_SNORM:
{
out_rgba_size[0] = 16;
out_rgba_size[1] = 16;
break;
}
case GL_RG8:
case GL_RG8I:
case GL_RG8UI:
case GL_RG8_SNORM:
{
out_rgba_size[0] = 8;
out_rgba_size[1] = 8;
break;
}
case GL_R32F:
case GL_R32I:
case GL_R32UI:
{
out_rgba_size[0] = 32;
break;
}
case GL_R16F:
case GL_R16I:
case GL_R16UI:
case GL_R16:
case GL_R16_SNORM:
case GL_DEPTH_COMPONENT16:
{
out_rgba_size[0] = 16;
break;
}
case GL_R8:
case GL_R8I:
case GL_R8UI:
case GL_R8_SNORM:
{
out_rgba_size[0] = 8;
break;
}
case GL_DEPTH_COMPONENT24:
{
out_rgba_size[0] = 24;
break;
}
case GL_DEPTH32F_STENCIL8:
{
out_rgba_size[0] = 32;
out_rgba_size[1] = 8;
break;
}
case GL_DEPTH24_STENCIL8:
{
out_rgba_size[0] = 24;
out_rgba_size[1] = 8;
break;
}
default:
{
TCU_FAIL("Unrecognized internalformat");
}
} /* switch (interalformat) */
}
/** Tells how many bits per components should be used to define input data with
* user-specified type.
*
* Throws TestError exception if @param type is not recognized.
*
* @param type Type to use for the query.
* @param out_rgba_size Deref will be used to store requested information. Must
* not be NULL. Must be capacious enough to hold 4 ints.
*
**/
void TextureViewUtilities::getComponentSizeForType(const glw::GLenum type, unsigned int* out_rgba_size)
{
memset(out_rgba_size, 0, sizeof(unsigned int) * 4 /* rgba */);
switch (type)
{
case GL_BYTE:
case GL_UNSIGNED_BYTE:
{
out_rgba_size[0] = 8;
out_rgba_size[1] = 8;
out_rgba_size[2] = 8;
out_rgba_size[3] = 8;
break;
}
case GL_FLOAT:
case GL_UNSIGNED_INT:
case GL_INT:
{
out_rgba_size[0] = 32;
out_rgba_size[1] = 32;
out_rgba_size[2] = 32;
out_rgba_size[3] = 32;
break;
}
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
{
out_rgba_size[0] = 8;
out_rgba_size[1] = 24;
out_rgba_size[2] = 32;
out_rgba_size[3] = 0;
break;
}
case GL_HALF_FLOAT:
case GL_UNSIGNED_SHORT:
case GL_SHORT:
{
out_rgba_size[0] = 16;
out_rgba_size[1] = 16;
out_rgba_size[2] = 16;
out_rgba_size[3] = 16;
break;
}
case GL_UNSIGNED_INT_10_10_10_2:
{
out_rgba_size[0] = 10;
out_rgba_size[1] = 10;
out_rgba_size[2] = 10;
out_rgba_size[3] = 2;
break;
}
case GL_UNSIGNED_INT_10F_11F_11F_REV:
{
out_rgba_size[0] = 11;
out_rgba_size[1] = 11;
out_rgba_size[2] = 10;
break;
}
case GL_UNSIGNED_INT_24_8:
{
out_rgba_size[0] = 24;
out_rgba_size[1] = 8;
out_rgba_size[2] = 0;
out_rgba_size[3] = 0;
break;
}
case GL_UNSIGNED_INT_2_10_10_10_REV:
{
out_rgba_size[0] = 10;
out_rgba_size[1] = 10;
out_rgba_size[2] = 10;
out_rgba_size[3] = 2;
break;
}
case GL_UNSIGNED_INT_5_9_9_9_REV:
{
out_rgba_size[0] = 9;
out_rgba_size[1] = 9;
out_rgba_size[2] = 9;
out_rgba_size[3] = 5;
break;
}
default:
{
TCU_FAIL("Unrecognized type");
}
} /* switch (type) */
}
/** Returns strings naming GL error codes.
*
* @param error_code GL error code.
*
* @return Requested strings or "[?]" if @param error_code was not
* recognized.
**/
const char* TextureViewUtilities::getErrorCodeString(const glw::GLint error_code)
{
switch (error_code)
{
case GL_INVALID_ENUM:
return "GL_INVALID_ENUM";
case GL_INVALID_FRAMEBUFFER_OPERATION:
return "GL_INVALID_FRAMEBUFFER_OPERATION";
case GL_INVALID_OPERATION:
return "GL_INVALID_OPERATION";
case GL_INVALID_VALUE:
return "GL_INVALID_VALUE";
case GL_NO_ERROR:
return "GL_NO_ERROR";
case GL_OUT_OF_MEMORY:
return "GL_OUT_OF_MEMORY";
case GL_STACK_OVERFLOW:
return "GL_STACK_OVERFLOW";
case GL_STACK_UNDERFLOW:
return "GL_STACK_UNDERFLOW";
default:
return "[?]";
}
}
/** Tells what the format of user-specified internalformat is (eg. whether it's a FP,
* unorm, snorm, etc.). Note: this is NOT the GL-speak format.
*
* Supports both compressed and non-compressed internalformats.
* Throws TestError exception if @param internalformat is not recognized.
*
* @param internalformat Internalformat to use for the query.
*
* @return Requested information.
*
**/
_format TextureViewUtilities::getFormatOfInternalformat(const glw::GLenum internalformat)
{
_format result = FORMAT_UNDEFINED;
switch (internalformat)
{
case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_RGBA_BPTC_UNORM:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
case GL_COMPRESSED_RED_RGTC1:
case GL_RGBA16:
case GL_RGBA4:
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGB16:
case GL_RGB5_A1:
case GL_RGB565:
case GL_RGB8:
case GL_RG16:
case GL_RG8:
case GL_R16:
case GL_R8:
case GL_SRGB8:
case GL_SRGB8_ALPHA8:
{
result = FORMAT_UNORM;
break;
}
case GL_COMPRESSED_SIGNED_RED_RGTC1:
case GL_COMPRESSED_SIGNED_RG_RGTC2:
case GL_RGBA16_SNORM:
case GL_RGBA8_SNORM:
case GL_RGB16_SNORM:
case GL_RGB8_SNORM:
case GL_RG16_SNORM:
case GL_RG8_SNORM:
case GL_R16_SNORM:
case GL_R8_SNORM:
{
result = FORMAT_SNORM;
break;
}
case GL_RGB10_A2UI:
case GL_RGBA16UI:
case GL_RGBA32UI:
case GL_RGBA8UI:
case GL_RGB16UI:
case GL_RGB32UI:
case GL_RGB8UI:
case GL_RG16UI:
case GL_RG32UI:
case GL_RG8UI:
case GL_R16UI:
case GL_R32UI:
case GL_R8UI:
{
result = FORMAT_UNSIGNED_INTEGER;
break;
}
case GL_RGB9_E5:
{
result = FORMAT_RGBE;
break;
}
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32F:
case GL_R11F_G11F_B10F:
case GL_RGBA16F:
case GL_RGBA32F:
case GL_RGB16F:
case GL_RGB32F:
case GL_RG16F:
case GL_RG32F:
case GL_R16F:
case GL_R32F:
{
result = FORMAT_FLOAT;
break;
}
case GL_RGBA16I:
case GL_RGBA32I:
case GL_RGBA8I:
case GL_RGB16I:
case GL_RGB32I:
case GL_RGB8I:
case GL_RG16I:
case GL_RG32I:
case GL_RG8I:
case GL_R16I:
case GL_R32I:
case GL_R8I:
{
result = FORMAT_SIGNED_INTEGER;
break;
}
default:
{
TCU_FAIL("Unrecognized internalformat");
}
} /* switch (interalformat) */
return result;
}
/** Returns GL format that is compatible with user-specified internalformat.
*
* Throws TestError exception if @param internalformat is not recognized.
*
* @param internalformat Internalformat to use for the query.
*
* @return Requested information.
**/
glw::GLenum TextureViewUtilities::getGLFormatOfInternalformat(const glw::GLenum internalformat)
{
glw::GLenum result = FORMAT_UNDEFINED;
switch (internalformat)
{
case GL_COMPRESSED_RGBA_BPTC_UNORM:
case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case GL_COMPRESSED_RGBA8_ETC2_EAC:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
{
result = GL_COMPRESSED_RGBA;
break;
}
case GL_RGB10_A2:
case GL_RGB5_A1:
case GL_RGBA16:
case GL_RGBA16F:
case GL_RGBA16_SNORM:
case GL_RGBA32F:
case GL_RGBA4:
case GL_RGBA8:
case GL_RGBA8_SNORM:
case GL_SRGB8_ALPHA8:
{
result = GL_RGBA;
break;
}
case GL_RGB10_A2UI:
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGBA32I:
case GL_RGBA32UI:
case GL_RGBA8I:
case GL_RGBA8UI:
{
result = GL_RGBA_INTEGER;
break;
}
case GL_COMPRESSED_RGB8_ETC2:
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
case GL_COMPRESSED_SRGB8_ETC2:
{
result = GL_COMPRESSED_RGB;
break;
}
case GL_R11F_G11F_B10F:
case GL_RGB16:
case GL_RGB16_SNORM:
case GL_RGB16F:
case GL_RGB32F:
case GL_RGB565:
case GL_RGB8:
case GL_RGB8_SNORM:
case GL_RGB9_E5:
case GL_SRGB8:
{
result = GL_RGB;
break;
}
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGB32I:
case GL_RGB32UI:
case GL_RGB8I:
case GL_RGB8UI:
{
result = GL_RGB_INTEGER;
break;
}
case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_RG11_EAC:
case GL_COMPRESSED_SIGNED_RG_RGTC2:
case GL_COMPRESSED_SIGNED_RG11_EAC:
{
result = GL_COMPRESSED_RG;
break;
}
case GL_RG16:
case GL_RG16_SNORM:
case GL_RG16F:
case GL_RG32F:
case GL_RG8:
case GL_RG8_SNORM:
{
result = GL_RG;
break;
}
case GL_RG16I:
case GL_RG16UI:
case GL_RG32I:
case GL_RG32UI:
case GL_RG8I:
case GL_RG8UI:
{
result = GL_RG_INTEGER;
break;
}
case GL_COMPRESSED_R11_EAC:
case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_SIGNED_R11_EAC:
case GL_COMPRESSED_SIGNED_RED_RGTC1:
{
result = GL_COMPRESSED_RED;
break;
}
case GL_R16:
case GL_R16F:
case GL_R16_SNORM:
case GL_R32F:
case GL_R8:
case GL_R8_SNORM:
{
result = GL_RED;
break;
}
case GL_R16I:
case GL_R16UI:
case GL_R32I:
case GL_R32UI:
case GL_R8I:
case GL_R8UI:
{
result = GL_RED_INTEGER;
break;
}
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32F:
{
result = GL_DEPTH_COMPONENT;
break;
}
case GL_DEPTH24_STENCIL8:
case GL_DEPTH32F_STENCIL8:
{
result = GL_DEPTH_STENCIL;
break;
}
default:
{
TCU_FAIL("Unrecognized internalformat");
}
} /* switch (internalformat) */
return result;
}
/** Returns a string that corresponds to a GLSL type that can act as input to user-specified
* sampler type, and which can hold user-specified amount of components.
*
* Throws TestError exception if either of the arguments was found invalid.
*
* @param sampler_type Type of the sampler to use for the query.
* @param n_components Amount of components to use for the query.
*
* @return Requested string.
**/
const char* TextureViewUtilities::getGLSLDataTypeForSamplerType(const _sampler_type sampler_type,
const unsigned int n_components)
{
const char* result = "";
switch (sampler_type)
{
case SAMPLER_TYPE_FLOAT:
{
switch (n_components)
{
case 1:
result = "float";
break;
case 2:
result = "vec2";
break;
case 3:
result = "vec3";
break;
case 4:
result = "vec4";
break;
default:
{
TCU_FAIL("Unsupported number of components");
}
} /* switch (n_components) */
break;
}
case SAMPLER_TYPE_SIGNED_INTEGER:
{
switch (n_components)
{
case 1:
result = "int";
break;
case 2:
result = "ivec2";
break;
case 3:
result = "ivec3";
break;
case 4:
result = "ivec4";
break;
default:
{
TCU_FAIL("Unsupported number of components");
}
} /* switch (n_components) */
break;
}
case SAMPLER_TYPE_UNSIGNED_INTEGER:
{
switch (n_components)
{
case 1:
result = "uint";
break;
case 2:
result = "uvec2";
break;
case 3:
result = "uvec3";
break;
case 4:
result = "uvec4";
break;
default:
{
TCU_FAIL("Unsupported number of components");
}
} /* switch (n_components) */
break;
}
default:
{
TCU_FAIL("Unrecognized sampler type");
}
} /* switch (sampler_type) */
return result;
}
/** Retrieves a string defining a sampler type in GLSL which corresponds to user-specified internal
* sampler type.
*
* Throws TestError exception if @param sampler_type was not recognized.
*
* @param sampler_type Internal sampler type to use for the query.
*
* @return Requested string.
**/
const char* TextureViewUtilities::getGLSLTypeForSamplerType(const _sampler_type sampler_type)
{
const char* result = "";
switch (sampler_type)
{
case SAMPLER_TYPE_FLOAT:
result = "sampler2D";
break;
case SAMPLER_TYPE_SIGNED_INTEGER:
result = "isampler2D";
break;
case SAMPLER_TYPE_UNSIGNED_INTEGER:
result = "usampler2D";
break;
default:
{
TCU_FAIL("Unrecognized sampler type");
}
} /* switch (sampler_type) */
return result;
}
/** Returns a vector of texture+view internalformat combinations that are known to be incompatible.
*
* @return Requested information.
**/
TextureViewUtilities::_incompatible_internalformat_pairs TextureViewUtilities::
getIllegalTextureAndViewInternalformatCombinations()
{
TextureViewUtilities::_incompatible_internalformat_pairs result;
/* Iterate in two loops over the set of supported internalformats */
for (int n_texture_internalformat = 0;
n_texture_internalformat <
(n_internalformat_view_compatibility_array_entries / 2); /* the array stores two values per entry */
++n_texture_internalformat)
{
glw::GLenum src_internalformat = internalformat_view_compatibility_array[(n_texture_internalformat * 2) + 0];
_view_class src_view_class =
(_view_class)internalformat_view_compatibility_array[(n_texture_internalformat * 2) + 1];
for (int n_view_internalformat = n_texture_internalformat + 1;
n_view_internalformat < (n_internalformat_view_compatibility_array_entries >> 1); ++n_view_internalformat)
{
glw::GLenum view_internalformat = internalformat_view_compatibility_array[(n_view_internalformat * 2) + 0];
_view_class view_view_class =
(_view_class)internalformat_view_compatibility_array[(n_view_internalformat * 2) + 1];
if (src_view_class != view_view_class)
{
result.push_back(_internalformat_pair(src_internalformat, view_internalformat));
}
} /* for (all internalformats we can use for the texture view) */
} /* for (all internalformats we can use for the parent texture) */
return result;
}
/** Returns a vector of texture+view target texture combinations that are known to be incompatible.
*
* @return Requested information.
**/
TextureViewUtilities::_incompatible_texture_target_pairs TextureViewUtilities::
getIllegalTextureAndViewTargetCombinations()
{
_incompatible_texture_target_pairs result;
/* Iterate through all combinations of texture targets and store those that are
* reported as invalid
*/
for (unsigned int n_parent_texture_target = 0; n_parent_texture_target < n_valid_texture_targets;
++n_parent_texture_target)
{
glw::GLenum parent_texture_target = valid_texture_targets[n_parent_texture_target];
for (unsigned int n_view_texture_target = 0; n_view_texture_target < n_valid_texture_targets;
++n_view_texture_target)
{
glw::GLenum view_texture_target = valid_texture_targets[n_view_texture_target];
if (!isLegalTextureTargetForTextureView(parent_texture_target, view_texture_target))
{
result.push_back(_internalformat_pair(parent_texture_target, view_texture_target));
}
} /* for (all texture targets considered for views) */
} /* for (all texture targets considered for parent texture) */
return result;
}
/** Returns internalformats associated with user-specified view class.
*
* @param view_class View class to use for the query.
*
* @return Requested information.
**/
TextureViewUtilities::_internalformats TextureViewUtilities::getInternalformatsFromViewClass(_view_class view_class)
{
_internalformats result;
/* Iterate over the data array and push those internalformats that match the requested view class */
const unsigned int n_array_elements = n_internalformat_view_compatibility_array_entries;
for (unsigned int n_array_pair = 0; n_array_pair < (n_array_elements >> 1); ++n_array_pair)
{
const glw::GLenum internalformat = internalformat_view_compatibility_array[n_array_pair * 2 + 0];
const _view_class current_view_class =
(_view_class)internalformat_view_compatibility_array[n_array_pair * 2 + 1];
if (current_view_class == view_class)
{
result.push_back(internalformat);
}
} /* for (all pairs in the data array) */
return result;
}
/** Returns a string defining user-specified internalformat.
*
* Throws a TestError exception if @param internalformat was not recognized.
*
* @param internalformat Internalformat to use for the query.
*
* @return Requested string.
**/
const char* TextureViewUtilities::getInternalformatString(const glw::GLenum internalformat)
{
const char* result = "[?]";
switch (internalformat)
{
case GL_RGBA32F:
result = "GL_RGBA32F";
break;
case GL_RGBA32I:
result = "GL_RGBA32I";
break;
case GL_RGBA32UI:
result = "GL_RGBA32UI";
break;
case GL_RGBA16:
result = "GL_RGBA16";
break;
case GL_RGBA16F:
result = "GL_RGBA16F";
break;
case GL_RGBA16I:
result = "GL_RGBA16I";
break;
case GL_RGBA16UI:
result = "GL_RGBA16UI";
break;
case GL_RGBA8:
result = "GL_RGBA8";
break;
case GL_RGBA8I:
result = "GL_RGBA8I";
break;
case GL_RGBA8UI:
result = "GL_RGBA8UI";
break;
case GL_SRGB8_ALPHA8:
result = "GL_SRGB8_ALPHA8";
break;
case GL_RGB10_A2:
result = "GL_RGB10_A2";
break;
case GL_RGB10_A2UI:
result = "GL_RGB10_A2UI";
break;
case GL_RGB5_A1:
result = "GL_RGB5_A1";
break;
case GL_RGBA4:
result = "GL_RGBA4";
break;
case GL_R11F_G11F_B10F:
result = "GL_R11F_G11F_B10F";
break;
case GL_RGB565:
result = "GL_RGB565";
break;
case GL_RG32F:
result = "GL_RG32F";
break;
case GL_RG32I:
result = "GL_RG32I";
break;
case GL_RG32UI:
result = "GL_RG32UI";
break;
case GL_RG16:
result = "GL_RG16";
break;
case GL_RG16F:
result = "GL_RG16F";
break;
case GL_RG16I:
result = "GL_RG16I";
break;
case GL_RG16UI:
result = "GL_RG16UI";
break;
case GL_RG8:
result = "GL_RG8";
break;
case GL_RG8I:
result = "GL_RG8I";
break;
case GL_RG8UI:
result = "GL_RG8UI";
break;
case GL_R32F:
result = "GL_R32F";
break;
case GL_R32I:
result = "GL_R32I";
break;
case GL_R32UI:
result = "GL_R32UI";
break;
case GL_R16F:
result = "GL_R16F";
break;
case GL_R16I:
result = "GL_R16I";
break;
case GL_R16UI:
result = "GL_R16UI";
break;
case GL_R16:
result = "GL_R16";
break;
case GL_R8:
result = "GL_R8";
break;
case GL_R8I:
result = "GL_R8I";
break;
case GL_R8UI:
result = "GL_R8UI";
break;
case GL_RGBA16_SNORM:
result = "GL_RGBA16_SNORM";
break;
case GL_RGBA8_SNORM:
result = "GL_RGBA8_SNORM";
break;
case GL_RGB32F:
result = "GL_RGB32F";
break;
case GL_RGB32I:
result = "GL_RGB32I";
break;
case GL_RGB32UI:
result = "GL_RGB32UI";
break;
case GL_RGB16_SNORM:
result = "GL_RGB16_SNORM";
break;
case GL_RGB16F:
result = "GL_RGB16F";
break;
case GL_RGB16I:
result = "GL_RGB16I";
break;
case GL_RGB16UI:
result = "GL_RGB16UI";
break;
case GL_RGB16:
result = "GL_RGB16";
break;
case GL_RGB8_SNORM:
result = "GL_RGB8_SNORM";
break;
case GL_RGB8:
result = "GL_RGB8";
break;
case GL_RGB8I:
result = "GL_RGB8I";
break;
case GL_RGB8UI:
result = "GL_RGB8UI";
break;
case GL_SRGB8:
result = "GL_SRGB8";
break;
case GL_RGB9_E5:
result = "GL_RGB9_E5";
break;
case GL_RG16_SNORM:
result = "GL_RG16_SNORM";
break;
case GL_RG8_SNORM:
result = "GL_RG8_SNORM";
break;
case GL_R16_SNORM:
result = "GL_R16_SNORM";
break;
case GL_R8_SNORM:
result = "GL_R8_SNORM";
break;
case GL_DEPTH_COMPONENT32F:
result = "GL_DEPTH_COMPONENT32F";
break;
case GL_DEPTH_COMPONENT24:
result = "GL_DEPTH_COMPONENT24";
break;
case GL_DEPTH_COMPONENT16:
result = "GL_DEPTH_COMPONENT16";
break;
case GL_DEPTH32F_STENCIL8:
result = "GL_DEPTH32F_STENCIL8";
break;
case GL_DEPTH24_STENCIL8:
result = "GL_DEPTH24_STENCIL8";
break;
case GL_COMPRESSED_RED_RGTC1:
result = "GL_COMPRESSED_RED_RGTC1";
break;
case GL_COMPRESSED_SIGNED_RED_RGTC1:
result = "GL_COMPRESSED_SIGNED_RED_RGTC1";
break;
case GL_COMPRESSED_RG_RGTC2:
result = "GL_COMPRESSED_RG_RGTC2";
break;
case GL_COMPRESSED_SIGNED_RG_RGTC2:
result = "GL_COMPRESSED_SIGNED_RG_RGTC2";
break;
case GL_COMPRESSED_RGBA_BPTC_UNORM:
result = "GL_COMPRESSED_RGBA_BPTC_UNORM";
break;
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
result = "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM";
break;
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
result = "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT";
break;
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
result = "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT";
break;
case GL_COMPRESSED_RGB8_ETC2:
result = "GL_COMPRESSED_RGB8_ETC2";
break;
case GL_COMPRESSED_SRGB8_ETC2:
result = "GL_COMPRESSED_SRGB8_ETC2";
break;
case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
result = "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2";
break;
case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
result = "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2";
break;
case GL_COMPRESSED_RGBA8_ETC2_EAC:
result = "GL_COMPRESSED_RGBA8_ETC2_EAC";
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
result = "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC";
break;
case GL_COMPRESSED_R11_EAC:
result = "GL_COMPRESSED_R11_EAC";
break;
case GL_COMPRESSED_SIGNED_R11_EAC:
result = "GL_COMPRESSED_SIGNED_R11_EAC";
break;
case GL_COMPRESSED_RG11_EAC:
result = "GL_COMPRESSED_RG11_EAC";
break;
case GL_COMPRESSED_SIGNED_RG11_EAC:
result = "GL_COMPRESSED_SIGNED_RG11_EAC";
break;
default:
TCU_FAIL("Unrecognized internalformat");
}
return result;
}
/** Returns all texture+view internalformat pairs that are valid in light of GL_ARB_texture_view specification.
*
* @return As described.
**/
TextureViewUtilities::_compatible_internalformat_pairs TextureViewUtilities::
getLegalTextureAndViewInternalformatCombinations()
{
_compatible_internalformat_pairs result;
/* Iterate over all view classes */
for (int current_view_class_it = static_cast<int>(VIEW_CLASS_FIRST);
current_view_class_it != static_cast<int>(VIEW_CLASS_COUNT); current_view_class_it++)
{
_view_class current_view_class = static_cast<_view_class>(current_view_class_it);
_internalformats view_class_internalformats = getInternalformatsFromViewClass(current_view_class);
/* Store all combinations in the result vector */
for (_internalformats_const_iterator left_iterator = view_class_internalformats.begin();
left_iterator != view_class_internalformats.end(); left_iterator++)
{
for (_internalformats_const_iterator right_iterator = view_class_internalformats.begin();
right_iterator != view_class_internalformats.end(); ++right_iterator)
{
result.push_back(_internalformat_pair(*left_iterator, *right_iterator));
} /* for (all internalformats to be used as right-side values) */
} /* for (all internalformats to be used as left-side values) */
} /* for (all view classes) */
return result;
}
/** Returns all valid texture+view texture targets pairs.
*
* @return As per description.
**/
TextureViewUtilities::_compatible_texture_target_pairs TextureViewUtilities::getLegalTextureAndViewTargetCombinations()
{
_compatible_texture_target_pairs result;
/* Iterate over all texture targets valid for a glTextureView() call. Consider each one of them as
* original texture target.
*/
for (unsigned int n_original_texture_target = 0; n_original_texture_target < n_valid_texture_targets;
++n_original_texture_target)
{
const glw::GLenum original_texture_target = valid_texture_targets[n_original_texture_target];
/* Iterate again, but this time consider each texture target as a valid new target */
for (unsigned int n_compatible_texture_target = 0; n_compatible_texture_target < n_valid_texture_targets;
++n_compatible_texture_target)
{
const glw::GLenum view_texture_target = valid_texture_targets[n_compatible_texture_target];
if (TextureViewUtilities::isLegalTextureTargetForTextureView(original_texture_target, view_texture_target))
{
result.push_back(_texture_target_pair(original_texture_target, view_texture_target));
}
} /* for (all texture targets that are potentially compatible) */
} /* for (all original texture targets) */
return result;
}
/** Returns major & minor version for user-specified CTS rendering context type.
*
* @param context_type CTS rendering context type.
* @param out_major_version Deref will be used to store major version. Must not be NULL.
* @param out_minor_version Deref will be used to store minor version. Must not be NULL.
*
**/
void TextureViewUtilities::getMajorMinorVersionFromContextVersion(const glu::ContextType& context_type,
glw::GLint* out_major_version,
glw::GLint* out_minor_version)
{
if (context_type.getAPI() == glu::ApiType::core(4, 0))
{
*out_major_version = 4;
*out_minor_version = 0;
}
else if (context_type.getAPI() == glu::ApiType::core(4, 1))
{
*out_major_version = 4;
*out_minor_version = 1;
}
else if (context_type.getAPI() == glu::ApiType::core(4, 2))
{
*out_major_version = 4;
*out_minor_version = 2;
}
else if (context_type.getAPI() == glu::ApiType::core(4, 3))
{
*out_major_version = 4;
*out_minor_version = 3;
}
else if (context_type.getAPI() == glu::ApiType::core(4, 4))
{
*out_major_version = 4;
*out_minor_version = 4;
}
else if (context_type.getAPI() == glu::ApiType::core(4, 5))
{
*out_major_version = 4;
*out_minor_version = 5;
}
else if (context_type.getAPI() == glu::ApiType::core(4, 6))
{
*out_major_version = 4;
*out_minor_version = 6;
}
else
{
TCU_FAIL("Unrecognized rendering context version");
}
}
/** Tells which sampler can be used to sample a texture defined with user-specified
* internalformat.
*
* Supports both compressed and non-compressed internalformats.
* Throws TestError exception if @param internalformat was not recognized.
*
* @param internalformat Internalformat to use for the query.
*
* @return Requested information.
**/
_sampler_type TextureViewUtilities::getSamplerTypeForInternalformat(const glw::GLenum internalformat)
{
_sampler_type result = SAMPLER_TYPE_UNDEFINED;
/* Compressed internalformats not supported at the moment */
switch (internalformat)
{
case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_SIGNED_RED_RGTC1:
case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SIGNED_RG_RGTC2:
case GL_COMPRESSED_RGBA_BPTC_UNORM:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32F:
case GL_RGBA16:
case GL_RGBA16_SNORM:
case GL_RGBA16F:
case GL_RGBA32F:
case GL_RGBA4:
case GL_RGBA8:
case GL_RGBA8_SNORM:
case GL_RGB10_A2:
case GL_RGB16:
case GL_RGB16_SNORM:
case GL_RGB16F:
case GL_RGB32F:
case GL_RGB5_A1:
case GL_RGB565:
case GL_RGB8:
case GL_RGB8_SNORM:
case GL_RGB9_E5:
case GL_RG16:
case GL_RG16_SNORM:
case GL_RG16F:
case GL_RG32F:
case GL_RG8:
case GL_RG8_SNORM:
case GL_R11F_G11F_B10F:
case GL_R16:
case GL_R16F:
case GL_R16_SNORM:
case GL_R32F:
case GL_R8:
case GL_R8_SNORM:
case GL_SRGB8_ALPHA8:
case GL_SRGB8:
{
result = SAMPLER_TYPE_FLOAT;
break;
}
case GL_RGB10_A2UI:
case GL_RGBA32UI:
case GL_RGBA16UI:
case GL_RGBA8UI:
case GL_RGB16UI:
case GL_RGB32UI:
case GL_RGB8UI:
case GL_RG16UI:
case GL_RG32UI:
case GL_RG8UI:
case GL_R16UI:
case GL_R32UI:
case GL_R8UI:
{
result = SAMPLER_TYPE_UNSIGNED_INTEGER;
break;
}
case GL_RGBA16I:
case GL_RGBA32I:
case GL_RGBA8I:
case GL_RGB16I:
case GL_RGB32I:
case GL_RGB8I:
case GL_RG16I:
case GL_RG32I:
case GL_RG8I:
case GL_R16I:
case GL_R32I:
case GL_R8I:
{
result = SAMPLER_TYPE_SIGNED_INTEGER;
break;
}
default:
{
TCU_FAIL("Unrecognized internalformat");
}
} /* switch (interalformat) */
return result;
}
/** Tells how many bytes are required to define a texture mip-map using
* user-specified internalformat and type, assuming user-defined mip-map
* resolution. Compressed internalformats are NOT supported.
*
* Throws TestError exception if @param internalformat or @param type are
* found invalid.
*
* @param internalformat Internalformat to use for the query.
* @param type Type to use for the query.
* @param width Mip-map width to use for the query.
* @param height Mip-map height to use for the query.
*
* @return Requested information.
**/
unsigned int TextureViewUtilities::getTextureDataSize(const glw::GLenum internalformat, const glw::GLenum type,
const unsigned int width, const unsigned int height)
{
unsigned int internalformat_rgba_size[4] = { 0 };
unsigned int type_rgba_size[4] = { 0 };
unsigned int texel_size = 0;
TextureViewUtilities::getComponentSizeForInternalformat(internalformat, internalformat_rgba_size);
TextureViewUtilities::getComponentSizeForType(type, type_rgba_size);
if (internalformat_rgba_size[0] == 0)
{
type_rgba_size[0] = 0;
}
if (internalformat_rgba_size[1] == 0)
{
type_rgba_size[1] = 0;
}
if (internalformat_rgba_size[2] == 0)
{
type_rgba_size[2] = 0;
}
if (internalformat_rgba_size[3] == 0)
{
type_rgba_size[3] = 0;
}
texel_size = type_rgba_size[0] + type_rgba_size[1] + type_rgba_size[2] + type_rgba_size[3];
/* Current implementation assumes we do not need to use bit resolution when
* preparing texel data. Make extra sure we're not wrong. */
DE_ASSERT((texel_size % 8) == 0);
texel_size /= 8; /* bits per byte */
return texel_size * width * height;
}
/** Returns a string corresponding to a GL enum describing a texture target.
*
* @return As per description or "[?]" if the enum was not recognized.
**/
const char* TextureViewUtilities::getTextureTargetString(const glw::GLenum texture_target)
{
const char* result = "[?]";
switch (texture_target)
{
case GL_TEXTURE_1D:
result = "GL_TEXTURE_1D";
break;
case GL_TEXTURE_1D_ARRAY:
result = "GL_TEXTURE_1D_ARRAY";
break;
case GL_TEXTURE_2D:
result = "GL_TEXTURE_2D";
break;
case GL_TEXTURE_2D_ARRAY:
result = "GL_TEXTURE_2D_ARRAY";
break;
case GL_TEXTURE_2D_MULTISAMPLE:
result = "GL_TEXTURE_2D_MULTISAMPLE";
break;
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
result = "GL_TEXTURE_2D_MULTISAMPLE_ARRAY";
break;
case GL_TEXTURE_3D:
result = "GL_TEXTURE_3D";
break;
case GL_TEXTURE_BUFFER:
result = "GL_TEXTURE_BUFFER";
break;
case GL_TEXTURE_CUBE_MAP:
result = "GL_TEXTURE_CUBE_MAP";
break;
case GL_TEXTURE_CUBE_MAP_ARRAY:
result = "GL_TEXTURE_CUBE_MAP_ARRAY";
break;
case GL_TEXTURE_RECTANGLE:
result = "GL_TEXTURE_RECTANGLE";
break;
}
return result;
}
/** Returns GL type that can be used to define a texture mip-map defined
* with an internalformat of @param internalformat.
*
* Throws TestError exception if @param internalformat was found to be invalid.
*
* @param internalformat Internalformat to use for the query.
*
* @return Requested information.
**/
glw::GLenum TextureViewUtilities::getTypeCompatibleWithInternalformat(const glw::GLenum internalformat)
{
glw::GLenum result = GL_NONE;
/* Compressed internalformats not supported at the moment */
switch (internalformat)
{
case GL_RGBA8_SNORM:
case GL_RGB8_SNORM:
case GL_RG8_SNORM:
case GL_R8_SNORM:
case GL_RGBA8I:
case GL_RGB8I:
case GL_RG8I:
case GL_R8I:
{
result = GL_BYTE;
break;
}
case GL_DEPTH24_STENCIL8:
{
result = GL_UNSIGNED_INT_24_8;
break;
}
case GL_DEPTH32F_STENCIL8:
{
result = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
break;
}
case GL_RGBA16F:
case GL_RGB16F:
case GL_RG16F:
case GL_R16F:
{
result = GL_HALF_FLOAT;
break;
}
case GL_DEPTH_COMPONENT32F:
case GL_RGBA32F:
case GL_RGB32F:
case GL_RG32F:
case GL_R11F_G11F_B10F:
case GL_R32F:
{
result = GL_FLOAT;
break;
}
case GL_RGBA16_SNORM:
case GL_RGB16_SNORM:
case GL_RG16_SNORM:
case GL_R16_SNORM:
{
result = GL_SHORT;
break;
}
case GL_RGBA4:
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGB5_A1:
case GL_RGB565:
case GL_RGB8:
case GL_RGB9_E5:
case GL_RG8:
case GL_R8:
case GL_SRGB8_ALPHA8:
case GL_SRGB8:
case GL_RGBA8UI:
case GL_RGB8UI:
case GL_RG8UI:
case GL_R8UI:
{
result = GL_UNSIGNED_BYTE;
break;
}
case GL_R16I:
case GL_RGBA16I:
case GL_RGB16I:
case GL_RG16I:
{
result = GL_SHORT;
break;
}
case GL_DEPTH_COMPONENT16:
case GL_RGBA16:
case GL_RGB16:
case GL_RG16:
case GL_R16:
case GL_RGBA16UI:
case GL_RGB16UI:
case GL_RG16UI:
case GL_R16UI:
{
result = GL_UNSIGNED_SHORT;
break;
}
case GL_RGBA32I:
case GL_RGB32I:
case GL_RG32I:
case GL_R32I:
{
result = GL_INT;
break;
}
case GL_DEPTH_COMPONENT24:
case GL_RGBA32UI:
case GL_RGB32UI:
case GL_RG32UI:
case GL_R32UI:
{
result = GL_UNSIGNED_INT;
break;
}
case GL_RGB10_A2UI:
{
result = GL_UNSIGNED_INT_2_10_10_10_REV;
break;
}
default:
{
TCU_FAIL("Unrecognized internalformat");
}
} /* switch (interalformat) */
return result;
}
/** Tells what view class is the user-specified internalformat associated with.
*
* Implements Table 8.21 from OpenGL Specification 4.3
*
* @param internalformat Internalformat to use for the query.
*
* @return Requested information or VIEW_CLASS_UNDEFINED if @param internalformat
* has not been recognized.
**/
_view_class TextureViewUtilities::getViewClassForInternalformat(const glw::GLenum internalformat)
{
_view_class result = VIEW_CLASS_UNDEFINED;
/* Note that n_internalformat_view_compatibility_array_entries needs to be divided by 2
* because the value refers to a total number of entries in the array, not to the number
* of pairs that can be read.
*/
for (int n_entry = 0; n_entry < (n_internalformat_view_compatibility_array_entries >> 1); n_entry++)
{
glw::GLenum array_internalformat = internalformat_view_compatibility_array[(n_entry * 2) + 0];
_view_class view_class = (_view_class)internalformat_view_compatibility_array[(n_entry * 2) + 1];
if (array_internalformat == internalformat)
{
result = view_class;
break;
}
} /* for (all pairs in data array) */
return result;
}
/** Initializes texture storage for either an immutable or mutable texture object,
* depending on configuration of the test run the storage is to be initialized for.
*
* @param gl GL entry-points to use for storage initialization.
* @param init_mutable_to true if a mutable texture storage should be initialized,
* false to initialize immutable texture storage.
* @param texture_target Texture target to be used.
* @param texture_depth Depth to be used for texture storage. Only used
* for texture targets that use the depth information.
* @param texture_height Height to be used for texture storage. Only used
* for texture targets that use the height information.
* @param texture_width Width to be used for texture storage.
* @param texture_internalformat Internalformat to be used for texture storage.
* @param texture_format Format to be used for texture storage.
* @param texture_type Type to be used for texture storage.
* @param n_levels_needed Amount of mip-map levels that should be used for texture storage.
* Only used for texture targets that support mip-maps.
* @param n_cubemaps_needed Amount of cube-maps to be used for initialization of cube map
* array texture storage. Only used if @param texture_internalformat
* is set to GL_TEXTURE_CUBE_MAP_ARRAY.
* @param bo_id ID of a buffer object to be used for initialization of
* buffer texture storage. Only used if @param texture_internalformat
* is set to GL_TEXTURE_BUFFEER.
*
**/
void TextureViewUtilities::initTextureStorage(const glw::Functions& gl, bool init_mutable_to,
glw::GLenum texture_target, glw::GLint texture_depth,
glw::GLint texture_height, glw::GLint texture_width,
glw::GLenum texture_internalformat, glw::GLenum texture_format,
glw::GLenum texture_type, unsigned int n_levels_needed,
unsigned int n_cubemaps_needed, glw::GLint bo_id)
{
const glw::GLenum cubemap_texture_targets[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
const unsigned int n_cubemap_texture_targets = sizeof(cubemap_texture_targets) / sizeof(cubemap_texture_targets[0]);
/* If we're going to be initializing a multisample texture object,
* determine how many samples can be used for GL_RGBA8 internalformat,
* given texture target that is of our interest */
glw::GLint gl_max_color_texture_samples_value = 0;
gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &gl_max_color_texture_samples_value);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES");
if (texture_target == GL_TEXTURE_BUFFER)
{
gl.texBuffer(GL_TEXTURE_BUFFER, texture_internalformat, bo_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexBuffer() call failed for GL_TEXTURE_BUFFER target");
}
else if (init_mutable_to)
{
for (unsigned int n_level = 0; n_level < n_levels_needed; ++n_level)
{
/* If level != 0 and we're trying to initialize a texture target which
* only accepts a single level, leave now
*/
if (n_level != 0 &&
(texture_target == GL_TEXTURE_RECTANGLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || texture_target == GL_TEXTURE_BUFFER))
{
break;
}
/* Initialize mutable texture storage */
switch (texture_target)
{
case GL_TEXTURE_1D:
{
gl.texImage1D(texture_target, n_level, texture_internalformat, texture_width >> n_level, 0, /* border */
texture_format, texture_type, DE_NULL); /* pixels */
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D() call failed for GL_TEXTURE_1D texture target");
break;
}
case GL_TEXTURE_1D_ARRAY:
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE:
{
gl.texImage2D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
texture_height >> n_level, 0, /* border */
texture_format, texture_type, DE_NULL); /* pixels */
GLU_EXPECT_NO_ERROR(gl.getError(),
(texture_target == GL_TEXTURE_1D_ARRAY) ?
"glTexImage2D() call failed for GL_TEXTURE_1D_ARRAY texture target" :
(texture_target == GL_TEXTURE_2D) ?
"glTexImage2D() call failed for GL_TEXTURE_2D texture target" :
"glTexImage2D() call failed for GL_TEXTURE_RECTANGLE texture target");
break;
}
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_3D:
{
gl.texImage3D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
texture_height >> n_level, texture_depth >> n_level, 0, /* border */
texture_format, texture_type, DE_NULL); /* pixels */
GLU_EXPECT_NO_ERROR(gl.getError(),
(texture_target == GL_TEXTURE_2D_ARRAY) ?
"glTexImage3D() call failed for GL_TEXTURE_2D_ARRAY texture target" :
"glTexImage3D() call failed for GL_TEXTURE_3D texture target");
break;
}
case GL_TEXTURE_2D_MULTISAMPLE:
{
gl.texImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_color_texture_samples_value,
texture_internalformat, texture_width >> n_level, texture_height >> n_level,
GL_TRUE); /* fixedsamplelocations */
GLU_EXPECT_NO_ERROR(
gl.getError(),
"glTexImage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
break;
}
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
{
gl.texImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, gl_max_color_texture_samples_value,
texture_internalformat, texture_width >> n_level, texture_height >> n_level,
texture_depth >> n_level, GL_TRUE); /* fixedsamplelocations */
GLU_EXPECT_NO_ERROR(
gl.getError(),
"glTexImage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY texture target");
break;
}
case GL_TEXTURE_CUBE_MAP:
{
for (unsigned int n_cubemap_texture_target = 0; n_cubemap_texture_target < n_cubemap_texture_targets;
++n_cubemap_texture_target)
{
glw::GLenum cubemap_texture_target = cubemap_texture_targets[n_cubemap_texture_target];
gl.texImage2D(cubemap_texture_target, n_level, texture_internalformat, texture_width >> n_level,
texture_height >> n_level, 0, /* border */
texture_format, texture_type, DE_NULL); /* pixels */
GLU_EXPECT_NO_ERROR(gl.getError(),
"glTexImage2D() call failed for one of the cube-map texture targets");
break;
} /* for (all cube-map texture targets) */
break;
}
case GL_TEXTURE_CUBE_MAP_ARRAY:
{
gl.texImage3D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
texture_height >> n_level, 6 /* layer-faces */ * n_cubemaps_needed, 0, /* border */
texture_format, texture_type, DE_NULL); /* pixels */
GLU_EXPECT_NO_ERROR(gl.getError(),
"glTexImage3D() call failed for GL_TEXTURE_CUBE_MAP_ARRAY texture target");
break;
}
default:
{
TCU_FAIL("Unrecognized texture target");
}
} /* switch (texture_target) */
} /* for (all levels) */
} /* if (texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT) */
else
{
/* Initialize immutable texture storage */
switch (texture_target)
{
case GL_TEXTURE_1D:
{
gl.texStorage1D(texture_target, n_levels_needed, texture_internalformat, texture_width);
GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed for GL_TEXTURE_1D texture target");
break;
}
case GL_TEXTURE_1D_ARRAY:
case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_RECTANGLE:
{
const unsigned n_levels = (texture_target == GL_TEXTURE_RECTANGLE) ? 1 : n_levels_needed;
gl.texStorage2D(texture_target, n_levels, texture_internalformat, texture_width, texture_height);
GLU_EXPECT_NO_ERROR(gl.getError(),
(texture_target == GL_TEXTURE_1D_ARRAY) ?
"glTexStorage2D() call failed for GL_TEXTURE_1D_ARRAY texture target" :
(texture_target == GL_TEXTURE_2D) ?
"glTexStorage2D() call failed for GL_TEXTURE_2D texture target" :
(texture_target == GL_TEXTURE_CUBE_MAP) ?
"glTexStorage2D() call failed for GL_TEXTURE_CUBE_MAP texture target" :
"glTexStorage2D() call failed for GL_TEXTURE_RECTANGLE texture target");
break;
}
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_3D:
{
gl.texStorage3D(texture_target, n_levels_needed, texture_internalformat, texture_width, texture_height,
texture_depth);
GLU_EXPECT_NO_ERROR(gl.getError(),
(texture_target == GL_TEXTURE_2D_ARRAY) ?
"glTexStorage3D() call failed for GL_TEXTURE_2D_ARRAY texture target" :
"glTexStorage3D() call failed for GL_TEXTURE_3D texture target");
break;
}
case GL_TEXTURE_2D_MULTISAMPLE:
{
gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_color_texture_samples_value,
texture_internalformat, texture_width, texture_height,
GL_TRUE); /* fixedsamplelocations */
GLU_EXPECT_NO_ERROR(gl.getError(),
"glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
break;
}
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
{
gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, gl_max_color_texture_samples_value,
texture_internalformat, texture_width, texture_height, texture_depth,
GL_TRUE); /* fixedsamplelocations */
GLU_EXPECT_NO_ERROR(
gl.getError(),
"glTexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY texture target");
break;
}
case GL_TEXTURE_CUBE_MAP_ARRAY:
{
const unsigned int actual_texture_depth = 6 /* layer-faces */ * n_cubemaps_needed;
gl.texStorage3D(texture_target, n_levels_needed, texture_internalformat, texture_width, texture_height,
actual_texture_depth);
GLU_EXPECT_NO_ERROR(gl.getError(),
"glTexStorage3D() call failed for GL_TEXTURE_CUBE_MAP_ARRAY texture target");
break;
}
default:
{
TCU_FAIL("Unrecognized texture target");
}
} /* switch (texture_target) */
}
}
/** Tells whether a parent texture object, storage of which uses @param original_internalformat
* internalformat, can be used to generate a texture view using @param view_internalformat
* internalformat.
*
* @param original_internalformat Internalformat used for parent texture object storage.
* @param view_internalformat Internalformat to be used for view texture object storage.
*
* @return true if the internalformats are compatible, false otherwise.
**/
bool TextureViewUtilities::isInternalformatCompatibleForTextureView(glw::GLenum original_internalformat,
glw::GLenum view_internalformat)
{
const _view_class original_internalformat_view_class = getViewClassForInternalformat(original_internalformat);
const _view_class view_internalformat_view_class = getViewClassForInternalformat(view_internalformat);
return (original_internalformat_view_class == view_internalformat_view_class);
}
/** Tells whether user-specified internalformat is compressed.
*
* @param internalformat Internalformat to use for the query.
*
* @return true if @param internalformat is a known compressed internalformat,
* false otherwise.
**/
bool TextureViewUtilities::isInternalformatCompressed(const glw::GLenum internalformat)
{
bool result = false;
switch (internalformat)
{
case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_SIGNED_RED_RGTC1:
case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SIGNED_RG_RGTC2:
case GL_COMPRESSED_RGBA_BPTC_UNORM:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
case GL_COMPRESSED_RGB8_ETC2:
case GL_COMPRESSED_SRGB8_ETC2:
case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case GL_COMPRESSED_RGBA8_ETC2_EAC:
case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
case GL_COMPRESSED_R11_EAC:
case GL_COMPRESSED_SIGNED_R11_EAC:
case GL_COMPRESSED_RG11_EAC:
case GL_COMPRESSED_SIGNED_RG11_EAC:
{
result = true;
break;
}
} /* switch (internalformat) */
return result;
}
/** Tells whether user-specified internalformat operates in sRGB color space.
*
* @param internalformat Internalformat to use for the query.
*
* @return true if @param internalformat is a known sRGB internalformat,
* false otherwise.
**/
bool TextureViewUtilities::isInternalformatSRGB(const glw::GLenum internalformat)
{
return (internalformat == GL_SRGB8 || internalformat == GL_SRGB8_ALPHA8 ||
internalformat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM);
}
/** Tells whether user-specified internalformat is supported by OpenGL of a given version.
*
* @param internalformat Internalformat to use for the query.
* @param major_version Major version of the rendering context.
* @param minor_version Minor version of the rendering context.
*
* @return true if the internalformat is supported, false otherwise.
**/
bool TextureViewUtilities::isInternalformatSupported(glw::GLenum internalformat, const glw::GLint major_version,
const glw::GLint minor_version)
{
(void)major_version;
/* NOTE: This function, as it stands right now, does not consider OpenGL contexts
* lesser than 4.
**/
glw::GLint minimum_minor_version = 0;
DE_ASSERT(major_version >= 4);
switch (internalformat)
{
/* >= OpenGL 4.0 */
case GL_RGBA32F:
case GL_RGBA32I:
case GL_RGBA32UI:
case GL_RGBA16:
case GL_RGBA16F:
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGBA8:
case GL_RGBA8I:
case GL_RGBA8UI:
case GL_SRGB8_ALPHA8:
case GL_RGB10_A2:
case GL_RGB10_A2UI:
case GL_RGB5_A1:
case GL_RGBA4:
case GL_R11F_G11F_B10F:
case GL_RG32F:
case GL_RG32I:
case GL_RG32UI:
case GL_RG16:
case GL_RG16F:
case GL_RG16I:
case GL_RG16UI:
case GL_RG8:
case GL_RG8I:
case GL_RG8UI:
case GL_R32F:
case GL_R32I:
case GL_R32UI:
case GL_R16F:
case GL_R16I:
case GL_R16UI:
case GL_R16:
case GL_R8:
case GL_R8I:
case GL_R8UI:
case GL_RGBA16_SNORM:
case GL_RGBA8_SNORM:
case GL_RGB32F:
case GL_RGB32I:
case GL_RGB32UI:
case GL_RGB16_SNORM:
case GL_RGB16F:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGB16:
case GL_RGB8_SNORM:
case GL_RGB8:
case GL_RGB8I:
case GL_RGB8UI:
case GL_SRGB8:
case GL_RGB9_E5:
case GL_RG16_SNORM:
case GL_RG8_SNORM:
case GL_R16_SNORM:
case GL_R8_SNORM:
case GL_DEPTH_COMPONENT32F:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH32F_STENCIL8:
case GL_DEPTH24_STENCIL8:
case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_SIGNED_RED_RGTC1:
case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SIGNED_RG_RGTC2:
{
/* Already covered by default value of minimum_minor_version */
break;
}
/* >= OpenGL 4.2 */
case GL_RGB565:
case GL_COMPRESSED_RGBA_BPTC_UNORM:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
{
minimum_minor_version = 2;
break;
}
/* >= OpenGL 4.3 */
case GL_COMPRESSED_RGB8_ETC2:
case GL_COMPRESSED_SRGB8_ETC2:
case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case GL_COMPRESSED_RGBA8_ETC2_EAC:
case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
case GL_COMPRESSED_R11_EAC:
case GL_COMPRESSED_SIGNED_R11_EAC:
case GL_COMPRESSED_RG11_EAC:
case GL_COMPRESSED_SIGNED_RG11_EAC:
{
minimum_minor_version = 3;
break;
}
default:
TCU_FAIL("Unrecognized internalformat");
}
return (minor_version >= minimum_minor_version);
}
/** Tells whether a parent texture object using @param original_texture_target texture target
* can be used to generate a texture view of @param view_texture_target texture target.
*
* @param original_texture_target Texture target used by parent texture;
* @param view_texture_target Texture target to be used for view texture;
*
* @return true if the texture targets are compatible, false otherwise.
**/
bool TextureViewUtilities::isLegalTextureTargetForTextureView(glw::GLenum original_texture_target,
glw::GLenum view_texture_target)
{
bool result = false;
switch (original_texture_target)
{
case GL_TEXTURE_1D:
{
result = (view_texture_target == GL_TEXTURE_1D || view_texture_target == GL_TEXTURE_1D_ARRAY);
break;
}
case GL_TEXTURE_2D:
{
result = (view_texture_target == GL_TEXTURE_2D || view_texture_target == GL_TEXTURE_2D_ARRAY);
break;
}
case GL_TEXTURE_3D:
{
result = (view_texture_target == GL_TEXTURE_3D);
break;
}
case GL_TEXTURE_CUBE_MAP:
{
result = (view_texture_target == GL_TEXTURE_CUBE_MAP || view_texture_target == GL_TEXTURE_2D ||
view_texture_target == GL_TEXTURE_2D_ARRAY || view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
break;
}
case GL_TEXTURE_RECTANGLE:
{
result = (view_texture_target == GL_TEXTURE_RECTANGLE);
break;
}
case GL_TEXTURE_BUFFER:
{
/* No targets supported */
break;
}
case GL_TEXTURE_1D_ARRAY:
{
result = (view_texture_target == GL_TEXTURE_1D_ARRAY || view_texture_target == GL_TEXTURE_1D);
break;
}
case GL_TEXTURE_2D_ARRAY:
{
result = (view_texture_target == GL_TEXTURE_2D_ARRAY || view_texture_target == GL_TEXTURE_2D ||
view_texture_target == GL_TEXTURE_CUBE_MAP || view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
break;
}
case GL_TEXTURE_CUBE_MAP_ARRAY:
{
result = (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY || view_texture_target == GL_TEXTURE_2D_ARRAY ||
view_texture_target == GL_TEXTURE_2D || view_texture_target == GL_TEXTURE_CUBE_MAP);
break;
}
case GL_TEXTURE_2D_MULTISAMPLE:
{
result = (view_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
break;
}
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
{
result = (view_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
break;
}
} /* switch (original_texture_target) */
return result;
}
/** Constructor.
*
* @param context Rendering context.
**/
TextureViewTestGetTexParameter::TextureViewTestGetTexParameter(deqp::Context& context)
: TestCase(context, "gettexparameter", "Verifies glGetTexParameterfv() and glGetTexParameteriv() "
"work as specified")
{
/* Left blank on purpose */
}
/** De-initializes all GL objects created for the test. */
void TextureViewTestGetTexParameter::deinit()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Deinitialize all test runs */
for (_test_runs_iterator it = m_test_runs.begin(); it != m_test_runs.end(); ++it)
{
_test_run& test_run = *it;
if (test_run.parent_texture_object_id != 0)
{
gl.deleteTextures(1, &test_run.parent_texture_object_id);
test_run.parent_texture_object_id = 0;
}
if (test_run.texture_view_object_created_from_immutable_to_id != 0)
{
gl.deleteTextures(1, &test_run.texture_view_object_created_from_immutable_to_id);
test_run.texture_view_object_created_from_immutable_to_id = 0;
}
if (test_run.texture_view_object_created_from_view_to_id != 0)
{
gl.deleteTextures(1, &test_run.texture_view_object_created_from_view_to_id);
test_run.texture_view_object_created_from_view_to_id = 0;
}
}
m_test_runs.clear();
}
/** Initializes test run descriptors used by the test. This also includes
* all GL objects used by all the iterations.
**/
void TextureViewTestGetTexParameter::initTestRuns()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
const int n_cubemaps_needed = 4; /* only used for GL_TEXTURE_CUBE_MAP_ARRAY */
const int texture_depth = 16;
const int texture_height = 32;
const int texture_width = 64;
const glw::GLenum texture_targets[] = {
GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D,
GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY,
GL_TEXTURE_RECTANGLE
};
const _test_texture_type texture_types[] = { TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED,
TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT,
TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT,
TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT,
TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW };
const unsigned int n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
const unsigned int n_texture_types = sizeof(texture_types) / sizeof(texture_types[0]);
/* Iterate through all texture types supported by the test */
for (unsigned int n_texture_type = 0; n_texture_type < n_texture_types; ++n_texture_type)
{
const _test_texture_type texture_type = texture_types[n_texture_type];
/* Iterate through all texture targets supported by the test */
for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
{
_test_run new_test_run;
const glw::GLenum texture_target = texture_targets[n_texture_target];
/* Texture buffers are neither immutable nor mutable. In order to avoid testing
* them in both cases, let's assume they are immutable objects */
if (texture_target == GL_TEXTURE_BUFFER && texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT)
{
continue;
}
/* Set up test run properties. Since we're only testing a single
* configuration, we can set these to predefined values..
*/
const int n_levels_needed = 6;
glw::GLint n_min_layer = 1;
glw::GLint n_num_layers = 2;
glw::GLint n_min_level = 2;
glw::GLint n_num_levels = 3;
int parent_texture_depth = texture_depth;
int parent_texture_height = texture_height;
int parent_texture_width = texture_width;
new_test_run.texture_target = texture_target;
new_test_run.texture_type = texture_type;
/* Take note of target-specific restrictions */
if (texture_target == GL_TEXTURE_CUBE_MAP || texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
{
n_num_layers = 6 /* layer-faces */ * 2; /* as per spec */
/* Make sure that cube face width matches its height */
parent_texture_height = 64;
parent_texture_width = 64;
/* Also change the depth so that there's at least a few layers
* we can use in the test for GL_TEXTURE_CUBE_MAP_ARRAY case
*/
parent_texture_depth = 64;
}
if (texture_target == GL_TEXTURE_CUBE_MAP)
{
/* Texture views created from a cube map texture should always
* use a minimum layer of zero
*/
n_min_layer = 0;
n_num_layers = 6;
}
if (texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
{
/* Slightly modify the values we'll use for <minlayer>
* and <numlayers> arguments passed to glTextureView() calls
* so that we can test the "view from view from texture" case
*/
n_min_layer = 0;
}
if (texture_target == GL_TEXTURE_1D || texture_target == GL_TEXTURE_2D ||
texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_3D ||
texture_target == GL_TEXTURE_RECTANGLE)
{
/* All these texture targets are single-layer only. glTextureView()
* also requires <numlayers> argument to be set to 1 for them, so
* take this into account.
**/
n_min_layer = 0;
n_num_layers = 1;
}
if (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
texture_target == GL_TEXTURE_RECTANGLE)
{
/* All these texture targets do not support mip-maps */
n_min_level = 0;
}
/* Initialize parent texture object */
gl.genTextures(1, &new_test_run.parent_texture_object_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
gl.bindTexture(texture_target, new_test_run.parent_texture_object_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
if (texture_type != TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED)
{
TextureViewUtilities::initTextureStorage(gl, (texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT),
texture_target, parent_texture_depth, parent_texture_height,
parent_texture_width, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
n_levels_needed, n_cubemaps_needed, 0); /* bo_id */
}
/* Update expected view-specific property values to include interactions
* with immutable textures. */
if (texture_type == TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT ||
texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW)
{
/* Set expected GL_TEXTURE_IMMUTABLE_LEVELS property value to the number
* of levels we'll be using for the immutable texture storage. For selected
* texture targets that do no take <levels> argument, we'll change this
* value on a case-by-case basis.
*/
new_test_run.expected_n_immutable_levels = n_levels_needed;
/* Set expected GL_TEXTURE_VIEW_NUM_LAYERS property value to 1, as per GL spec.
* This value will be modified for selected texture targets */
new_test_run.expected_n_num_layers = 1;
/* Configured expected GL_TEXTURE_VIEW_NUM_LEVELS value as per GL spec */
new_test_run.expected_n_num_levels = n_levels_needed;
/* Initialize immutable texture storage */
switch (texture_target)
{
case GL_TEXTURE_1D_ARRAY:
{
/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
new_test_run.expected_n_num_layers = texture_height;
break;
}
case GL_TEXTURE_CUBE_MAP:
{
/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
new_test_run.expected_n_num_layers = 6;
break;
}
case GL_TEXTURE_RECTANGLE:
{
new_test_run.expected_n_immutable_levels = 1;
new_test_run.expected_n_num_levels = 1;
break;
}
case GL_TEXTURE_2D_ARRAY:
{
/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
new_test_run.expected_n_num_layers = texture_depth;
break;
}
case GL_TEXTURE_2D_MULTISAMPLE:
{
/* 2D multisample texture are not mip-mapped, so update
* expected GL_TEXTURE_IMMUTABLE_LEVELS and GL_TEXTURE_VIEW_NUM_LEVELS
* value accordingly */
new_test_run.expected_n_immutable_levels = 1;
new_test_run.expected_n_num_levels = 1;
break;
}
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
{
/* 2D multisample array textures are not mip-mapped, so update
* expected GL_TEXTURE_IMMUTABLE_LEVELS and GL_TEXTURE_VIEW_NUM_LEVELS
* values accordingly */
new_test_run.expected_n_immutable_levels = 1;
new_test_run.expected_n_num_levels = 1;
/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
new_test_run.expected_n_num_layers = texture_depth;
break;
}
case GL_TEXTURE_CUBE_MAP_ARRAY:
{
const unsigned int actual_texture_depth = 6 /* layer-faces */ * n_cubemaps_needed;
/* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
new_test_run.expected_n_num_layers = actual_texture_depth;
break;
}
} /* switch (texture_target) */
}
/* Initialize the view(s) */
if (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW)
{
const unsigned int n_iterations =
(texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) ? 2 : 1;
for (unsigned int n_iteration = 0; n_iteration < n_iterations; ++n_iteration)
{
glw::GLuint* parent_id_ptr = (n_iteration == 0) ?
&new_test_run.parent_texture_object_id :
&new_test_run.texture_view_object_created_from_immutable_to_id;
glw::GLuint* view_id_ptr = (n_iteration == 0) ?
&new_test_run.texture_view_object_created_from_immutable_to_id :
&new_test_run.texture_view_object_created_from_view_to_id;
gl.genTextures(1, view_id_ptr);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
gl.textureView(*view_id_ptr, new_test_run.texture_target, *parent_id_ptr,
GL_RGBA8, /* use the parent texture object's internalformat */
n_min_level, n_num_levels, n_min_layer, n_num_layers);
GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
/* Query parent object's properties */
glw::GLint parent_min_level = -1;
glw::GLint parent_min_layer = -1;
glw::GLint parent_num_layers = -1;
glw::GLint parent_num_levels = -1;
glw::GLint parent_n_immutable_levels = -1;
gl.bindTexture(texture_target, *parent_id_ptr);
GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
gl.getTexParameteriv(texture_target, GL_TEXTURE_IMMUTABLE_LEVELS, &parent_n_immutable_levels);
GLU_EXPECT_NO_ERROR(
gl.getError(),
"glGetTexParameteriv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname queried for parent object");
gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_MIN_LAYER, &parent_min_layer);
GLU_EXPECT_NO_ERROR(
gl.getError(),
"glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname queried for parent object");
gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_MIN_LEVEL, &parent_min_level);
GLU_EXPECT_NO_ERROR(
gl.getError(),
"glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname queried for parent object");
gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_NUM_LAYERS, &parent_num_layers);
GLU_EXPECT_NO_ERROR(
gl.getError(),
"glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname queried for parent object");
gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_NUM_LEVELS, &parent_num_levels);
GLU_EXPECT_NO_ERROR(
gl.getError(),
"glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname queried for parent object");
/* Update test run-specific expected values as per GL_ARB_texture_view extension specification */
/*
* - TEXTURE_IMMUTABLE_LEVELS is set to the value of TEXTURE_IMMUTABLE_LEVELS
* from the original texture.
*/
new_test_run.expected_n_immutable_levels = parent_n_immutable_levels;
/*
* - TEXTURE_VIEW_MIN_LEVEL is set to <minlevel> plus the value of
* TEXTURE_VIEW_MIN_LEVEL from the original texture.
*/
new_test_run.expected_n_min_level = n_min_level + parent_min_level;
/*
* - TEXTURE_VIEW_MIN_LAYER is set to <minlayer> plus the value of
* TEXTURE_VIEW_MIN_LAYER from the original texture.
*/
new_test_run.expected_n_min_layer = n_min_layer + parent_min_layer;
/*
* - TEXTURE_VIEW_NUM_LAYERS is set to the lesser of <numlayers> and the
* value of TEXTURE_VIEW_NUM_LAYERS from the original texture minus
* <minlayer>.
*
*/
if ((parent_num_layers - n_min_layer) < n_num_layers)
{
new_test_run.expected_n_num_layers = parent_num_layers - n_min_layer;
}
else
{
new_test_run.expected_n_num_layers = n_num_layers;
}
/*
* - TEXTURE_VIEW_NUM_LEVELS is set to the lesser of <numlevels> and the
* value of TEXTURE_VIEW_NUM_LEVELS from the original texture minus
* <minlevels>.
*
*/
if ((parent_num_levels - n_min_level) < n_num_levels)
{
new_test_run.expected_n_num_levels = parent_num_levels - n_min_level;
}
else
{
new_test_run.expected_n_num_levels = n_num_levels;
}
} /* for (all iterations) */
} /* if (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) */
/* Store the descriptor */
m_test_runs.push_back(new_test_run);
} /* for (all texture targets) */
} /* for (all texture types) */
}
/** Executes test iteration.
*
* @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
*/
tcu::TestNode::IterateResult TextureViewTestGetTexParameter::iterate()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Make sure GL_ARB_texture_view is reported as supported before carrying on
* with actual execution */
const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
{
throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
}
/* Initialize all objects necessary to execute the test */
initTestRuns();
/* Iterate through all test runs and issue the queries */
for (_test_runs_const_iterator test_run_iterator = m_test_runs.begin(); test_run_iterator != m_test_runs.end();
test_run_iterator++)
{
glw::GLfloat query_texture_immutable_levels_value_float = -1.0f;
glw::GLint query_texture_immutable_levels_value_int = -1;
glw::GLfloat query_texture_view_min_layer_value_float = -1.0f;
glw::GLint query_texture_view_min_layer_value_int = -1;
glw::GLfloat query_texture_view_min_level_value_float = -1.0f;
glw::GLint query_texture_view_min_level_value_int = -1;
glw::GLfloat query_texture_view_num_layers_value_float = -1.0f;
glw::GLint query_texture_view_num_layers_value_int = -1;
glw::GLfloat query_texture_view_num_levels_value_float = -1.0f;
glw::GLint query_texture_view_num_levels_value_int = -1;
const _test_run& test_run = *test_run_iterator;
glw::GLint texture_object_id = 0;
switch (test_run.texture_type)
{
case TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT:
texture_object_id = test_run.parent_texture_object_id;
break;
case TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT:
texture_object_id = test_run.parent_texture_object_id;
break;
case TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED:
texture_object_id = test_run.parent_texture_object_id;
break;
case TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT:
texture_object_id = test_run.texture_view_object_created_from_immutable_to_id;
break;
case TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW:
texture_object_id = test_run.texture_view_object_created_from_view_to_id;
break;
default:
{
TCU_FAIL("Unrecognized texture type");
}
}
/* Bind the texture object of our interest to the target */
gl.bindTexture(test_run.texture_target, texture_object_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
/* Run all the queries */
gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_IMMUTABLE_LEVELS,
&query_texture_immutable_levels_value_float);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname");
gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_IMMUTABLE_LEVELS,
&query_texture_immutable_levels_value_int);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexPrameteriv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname");
gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LAYER,
&query_texture_view_min_layer_value_float);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname");
gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LAYER,
&query_texture_view_min_layer_value_int);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname");
gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LEVEL,
&query_texture_view_min_level_value_float);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname");
gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LEVEL,
&query_texture_view_min_level_value_int);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname");
gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LAYERS,
&query_texture_view_num_layers_value_float);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname");
gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LAYERS,
&query_texture_view_num_layers_value_int);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname");
gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LEVELS,
&query_texture_view_num_levels_value_float);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname");
gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LEVELS,
&query_texture_view_num_levels_value_int);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname");
/* Verify the results */
const float epsilon = 1e-5f;
if (de::abs(query_texture_immutable_levels_value_float - (float)test_run.expected_n_immutable_levels) > epsilon)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid floating-point value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname "
<< "(expected: " << test_run.expected_n_immutable_levels
<< " found: " << query_texture_immutable_levels_value_float << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname");
}
if (query_texture_immutable_levels_value_int != test_run.expected_n_immutable_levels)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid integer value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname "
<< "(expected: " << test_run.expected_n_immutable_levels
<< " found: " << query_texture_immutable_levels_value_int << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname");
}
if (de::abs(query_texture_view_min_layer_value_float - (float)test_run.expected_n_min_layer) > epsilon)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid floating-point value reported for GL_TEXTURE_VIEW_MIN_LAYER pname "
<< "(expected: " << test_run.expected_n_min_layer
<< " found: " << query_texture_view_min_layer_value_float << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LAYER pname");
}
if (query_texture_view_min_layer_value_int != test_run.expected_n_min_layer)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid integer value reported for GL_TEXTURE_VIEW_MIN_LAYER pname "
<< "(expected: " << test_run.expected_n_min_layer
<< " found: " << query_texture_view_min_layer_value_int << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LAYER pname");
}
if (de::abs(query_texture_view_min_level_value_float - (float)test_run.expected_n_min_level) > epsilon)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid floating-point value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname "
<< "(expected: " << test_run.expected_n_min_level
<< " found: " << query_texture_view_min_level_value_float << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname");
}
if (query_texture_view_min_level_value_int != test_run.expected_n_min_level)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid integer value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname "
<< "(expected: " << test_run.expected_n_min_level
<< " found: " << query_texture_view_min_level_value_int << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname");
}
if (de::abs(query_texture_view_num_layers_value_float - (float)test_run.expected_n_num_layers) > epsilon)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid floating-point value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname "
<< "(expected: " << test_run.expected_n_num_layers
<< " found: " << query_texture_view_num_layers_value_float << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname");
}
if (query_texture_view_num_layers_value_int != test_run.expected_n_num_layers)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid integer value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname "
<< "(expected: " << test_run.expected_n_num_layers
<< " found: " << query_texture_view_num_layers_value_int << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname");
}
if (de::abs(query_texture_view_num_levels_value_float - (float)test_run.expected_n_num_levels) > epsilon)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid floating-point value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname "
<< "(expected: " << test_run.expected_n_num_levels
<< " found: " << query_texture_view_num_levels_value_float << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname");
}
if (query_texture_view_num_levels_value_int != test_run.expected_n_num_levels)
{
m_testCtx.getLog() << tcu::TestLog::Message
<< "Invalid integer value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname "
<< "(expected: " << test_run.expected_n_num_levels
<< " found: " << query_texture_view_num_levels_value_int << ")."
<< tcu::TestLog::EndMessage;
TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname");
}
} /* for (all test runs) */
/* Test case passed */
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
return STOP;
}
/** Constructor.
*
* @param context Rendering context
**/
TextureViewTestErrors::TextureViewTestErrors(deqp::Context& context)
: TestCase(context, "errors", "test_description")
, m_bo_id(0)
, m_reference_immutable_to_1d_id(0)
, m_reference_immutable_to_2d_id(0)
, m_reference_immutable_to_2d_array_id(0)
, m_reference_immutable_to_2d_array_32_by_33_id(0)
, m_reference_immutable_to_2d_multisample_id(0)
, m_reference_immutable_to_3d_id(0)
, m_reference_immutable_to_cube_map_id(0)
, m_reference_immutable_to_cube_map_array_id(0)
, m_reference_immutable_to_rectangle_id(0)
, m_reference_mutable_to_2d_id(0)
, m_test_modified_to_id_1(0)
, m_test_modified_to_id_2(0)
, m_test_modified_to_id_3(0)
, m_view_bound_to_id(0)
, m_view_never_bound_to_id(0)
{
/* Left blank on purpose */
}
/** Deinitializes all GL objects that may have been generated for the test. */
void TextureViewTestErrors::deinit()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
if (m_bo_id != 0)
{
gl.deleteBuffers(1, &m_bo_id);
m_bo_id = 0;
}
if (m_reference_immutable_to_1d_id != 0)
{
gl.deleteTextures(1, &m_reference_immutable_to_1d_id);
m_reference_immutable_to_1d_id = 0;
}
if (m_reference_immutable_to_2d_id != 0)
{
gl.deleteTextures(1, &m_reference_immutable_to_2d_id);
m_reference_immutable_to_2d_id = 0;
}
if (m_reference_immutable_to_2d_array_id != 0)
{
gl.deleteTextures(1, &m_reference_immutable_to_2d_array_id);
m_reference_immutable_to_2d_array_id = 0;
}
if (m_reference_immutable_to_2d_array_32_by_33_id != 0)
{
gl.deleteTextures(1, &m_reference_immutable_to_2d_array_32_by_33_id);
m_reference_immutable_to_2d_array_32_by_33_id = 0;
}
if (m_reference_immutable_to_2d_multisample_id != 0)
{
gl.deleteTextures(1, &m_reference_immutable_to_2d_multisample_id);
m_reference_immutable_to_2d_multisample_id = 0;
}
if (m_reference_immutable_to_3d_id != 0)
{
gl.deleteTextures(1, &m_reference_immutable_to_3d_id);
m_reference_immutable_to_3d_id = 0;
}
if (m_reference_immutable_to_cube_map_id != 0)
{
gl.deleteTextures(1, &m_reference_immutable_to_cube_map_id);
m_reference_immutable_to_cube_map_id = 0;
}
if (m_reference_immutable_to_cube_map_array_id != 0)
{
gl.deleteTextures(1, &m_reference_immutable_to_cube_map_array_id);