// // Copyright 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. //
// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
{ // Table 1.1 from the CHROMIUM_copy_texture spec switch (GetUnsizedFormat(internalFormat))
{ case GL_RED: case GL_ALPHA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: case GL_RGB: case GL_RGBA: case GL_RGB8: case GL_RGBA8: case GL_BGRA_EXT: case GL_BGRA8_EXT: returntrue;
bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
{ // Table 1.0 from the CHROMIUM_copy_texture spec switch (internalFormat)
{ case GL_ALPHA: case GL_BGRA8_EXT: case GL_BGRA_EXT: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: case GL_R11F_G11F_B10F: case GL_R16F: case GL_R32F: case GL_R8: case GL_R8UI: case GL_RG16F: case GL_RG32F: case GL_RG8: case GL_RG8UI: case GL_RGB: case GL_RGB10_A2: case GL_RGB16F: case GL_RGB32F: case GL_RGB565: case GL_RGB5_A1: case GL_RGB8: case GL_RGB8UI: case GL_RGB9_E5: case GL_RGBA: case GL_RGBA16F: case GL_RGBA32F: case GL_RGBA4: case GL_RGBA8: case GL_RGBA8UI: case GL_RGBX8_ANGLE: case GL_SRGB8: case GL_SRGB8_ALPHA8: case GL_SRGB_ALPHA_EXT: case GL_SRGB_EXT: returntrue;
bool IsValidCopyTextureDestinationTargetEnum(const Context *context, TextureTarget target)
{ switch (target)
{ case TextureTarget::_2D: case TextureTarget::CubeMapNegativeX: case TextureTarget::CubeMapNegativeY: case TextureTarget::CubeMapNegativeZ: case TextureTarget::CubeMapPositiveX: case TextureTarget::CubeMapPositiveY: case TextureTarget::CubeMapPositiveZ: returntrue;
case TextureTarget::Rectangle: return context->getExtensions().textureRectangleANGLE;
bool IsValidStencilFunc(GLenum func)
{ switch (func)
{ case GL_NEVER: case GL_ALWAYS: case GL_LESS: case GL_LEQUAL: case GL_EQUAL: case GL_GEQUAL: case GL_GREATER: case GL_NOTEQUAL: returntrue;
default: returnfalse;
}
}
bool IsValidStencilFace(GLenum face)
{ switch (face)
{ case GL_FRONT: case GL_BACK: case GL_FRONT_AND_BACK: returntrue;
default: returnfalse;
}
}
bool IsValidStencilOp(GLenum op)
{ switch (op)
{ case GL_ZERO: case GL_KEEP: case GL_REPLACE: case GL_INCR: case GL_DECR: case GL_INVERT: case GL_INCR_WRAP: case GL_DECR_WRAP: returntrue;
default: returnfalse;
}
}
staticinlinebool Valid1to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
{ return (context->getExtensions().textureFloatOES &&
(format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F ||
format == GL_R32F)) ||
(context->getExtensions().textureHalfFloatOES &&
(format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F ||
format == GL_R16F));
}
staticinlinebool Valid2to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
{ return (context->getExtensions().textureFloatOES &&
(format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F)) ||
(context->getExtensions().textureHalfFloatOES &&
(format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F));
}
// If width or height is zero, it is a no-op. Return false without setting an error. return (width > 0 && height > 0);
}
bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
{ switch (cap)
{ // EXT_multisample_compatibility case GL_MULTISAMPLE_EXT: case GL_SAMPLE_ALPHA_TO_ONE_EXT: return context->getExtensions().multisampleCompatibilityEXT;
case GL_CULL_FACE: case GL_POLYGON_OFFSET_FILL: case GL_SAMPLE_ALPHA_TO_COVERAGE: case GL_SAMPLE_COVERAGE: case GL_SCISSOR_TEST: case GL_STENCIL_TEST: case GL_DEPTH_TEST: case GL_BLEND: case GL_DITHER: returntrue;
case GL_PRIMITIVE_RESTART_FIXED_INDEX: case GL_RASTERIZER_DISCARD: return (context->getClientMajorVersion() >= 3);
case GL_DEBUG_OUTPUT_SYNCHRONOUS: case GL_DEBUG_OUTPUT: return context->getExtensions().debugKHR;
case GL_BIND_GENERATES_RESOURCE_CHROMIUM: return queryOnly && context->getExtensions().bindGeneratesResourceCHROMIUM;
case GL_CLIENT_ARRAYS_ANGLE: return queryOnly && context->getExtensions().clientArraysANGLE;
case GL_FRAMEBUFFER_SRGB_EXT: return context->getExtensions().sRGBWriteControlEXT;
case GL_SAMPLE_MASK: return context->getClientVersion() >= Version(3, 1);
case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: return queryOnly && context->getExtensions().robustResourceInitializationANGLE;
case GL_TEXTURE_RECTANGLE_ANGLE: return context->isWebGL();
// GL_APPLE_clip_distance/GL_EXT_clip_cull_distance case GL_CLIP_DISTANCE0_EXT: case GL_CLIP_DISTANCE1_EXT: case GL_CLIP_DISTANCE2_EXT: case GL_CLIP_DISTANCE3_EXT: case GL_CLIP_DISTANCE4_EXT: case GL_CLIP_DISTANCE5_EXT: case GL_CLIP_DISTANCE6_EXT: case GL_CLIP_DISTANCE7_EXT: if (context->getExtensions().clipDistanceAPPLE ||
context->getExtensions().clipCullDistanceEXT)
{ returntrue;
} break; case GL_SAMPLE_SHADING: return context->getExtensions().sampleShadingOES; case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM: return context->getExtensions().shadingRateQCOM;
// COLOR_LOGIC_OP is in GLES1, but exposed through an ANGLE extension. case GL_COLOR_LOGIC_OP: return context->getClientVersion() < Version(2, 0) ||
context->getExtensions().logicOpANGLE;
default: break;
}
// GLES1 emulation: GLES1-specific caps after this point if (context->getClientVersion().major != 1)
{ returnfalse;
}
switch (cap)
{ case GL_ALPHA_TEST: case GL_VERTEX_ARRAY: case GL_NORMAL_ARRAY: case GL_COLOR_ARRAY: case GL_TEXTURE_COORD_ARRAY: case GL_TEXTURE_2D: case GL_LIGHTING: case GL_LIGHT0: case GL_LIGHT1: case GL_LIGHT2: case GL_LIGHT3: case GL_LIGHT4: case GL_LIGHT5: case GL_LIGHT6: case GL_LIGHT7: case GL_NORMALIZE: case GL_RESCALE_NORMAL: case GL_COLOR_MATERIAL: case GL_CLIP_PLANE0: case GL_CLIP_PLANE1: case GL_CLIP_PLANE2: case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: case GL_FOG: case GL_POINT_SMOOTH: case GL_LINE_SMOOTH: return context->getClientVersion() < Version(2, 0); case GL_POINT_SIZE_ARRAY_OES: return context->getClientVersion() < Version(2, 0) &&
context->getExtensions().pointSizeArrayOES; case GL_TEXTURE_CUBE_MAP: return context->getClientVersion() < Version(2, 0) &&
context->getExtensions().textureCubeMapOES; case GL_POINT_SPRITE_OES: return context->getClientVersion() < Version(2, 0) &&
context->getExtensions().pointSpriteOES; default: returnfalse;
}
}
// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section // 3.1. bool IsValidESSLCharacter(unsignedchar c)
{ // Printing characters are valid except " $ ` @ \ ' DEL. if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
c != '\'')
{ returntrue;
}
// Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid. if (c >= 9 && c <= 13)
{ returntrue;
}
returnfalse;
}
bool IsValidESSLString(constchar *str, size_t len)
{ for (size_t i = 0; i < len; i++)
{ if (!IsValidESSLCharacter(str[i]))
{ returnfalse;
}
}
if (context->isWebGL1() && length > 256)
{ // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute // locations.
context->validationError(entryPoint, GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
returnfalse;
} elseif (length > 1024)
{ // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of // uniform and attribute locations.
context->validationError(entryPoint, GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded); returnfalse;
}
// these are always valid for src and dst. switch (val)
{ case GL_ZERO: case GL_ONE: case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: case GL_DST_COLOR: case GL_ONE_MINUS_DST_COLOR: case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: case GL_DST_ALPHA: case GL_ONE_MINUS_DST_ALPHA: case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: returntrue;
// EXT_blend_func_extended. case GL_SRC1_COLOR_EXT: case GL_SRC1_ALPHA_EXT: case GL_ONE_MINUS_SRC1_COLOR_EXT: case GL_ONE_MINUS_SRC1_ALPHA_EXT: case GL_SRC_ALPHA_SATURATE_EXT: return ext.blendFuncExtendedEXT;
if (!internalFormatInfo.textureSupport(context->getClientVersion(),
context->getExtensions()))
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kInvalidInternalFormat,
internalformat); returnfalse;
}
if (isSubImage)
{ // From OpenGL ES Version 1.1.12, section 3.7.4 Compressed Paletted // Textures: // // Subimages may not be specified for compressed paletted textures. // Calling CompressedTexSubImage2D with any of the PALETTE* // arguments in table 3.11 will generate an INVALID OPERATION error. if (internalFormatInfo.paletted)
{
context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
internalformat); returnfalse;
}
// From the OES_compressed_ETC1_RGB8_texture spec: // // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format // ETC1_RGB8_OES. // // This is relaxed if GL_EXT_compressed_ETC1_RGB8_sub_texture is supported. if (IsETC1Format(actualInternalFormat) &&
!context->getExtensions().compressedETC1RGB8SubTextureEXT)
{
context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
internalformat); returnfalse;
}
if (format != actualInternalFormat)
{
context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); returnfalse;
}
} else
{ if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height, 1))
{
context->validationError(entryPoint, GL_INVALID_OPERATION,
kInvalidCompressedImageSize); returnfalse;
}
}
} else
{ // validate <type> by itself (used as secondary key below) switch (type)
{ case GL_UNSIGNED_BYTE: case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT: case GL_UNSIGNED_INT: case GL_UNSIGNED_INT_24_8_OES: case GL_HALF_FLOAT_OES: case GL_FLOAT: break; case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: if (!context->getExtensions().textureType2101010REVEXT)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, type); returnfalse;
} break; default:
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); returnfalse;
}
// validate <format> + <type> combinations // - invalid <format> -> sets INVALID_ENUM // - invalid <format>+<type> combination -> sets INVALID_OPERATION switch (format)
{ case GL_ALPHA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: switch (type)
{ case GL_UNSIGNED_BYTE: case GL_FLOAT: case GL_HALF_FLOAT_OES: break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; case GL_RED: case GL_RG: if (!context->getExtensions().textureRgEXT)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
format); returnfalse;
} switch (type)
{ case GL_UNSIGNED_BYTE: break; case GL_FLOAT: if (!context->getExtensions().textureFloatOES)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM,
kEnumNotSupported, type); returnfalse;
} break; case GL_HALF_FLOAT_OES: if (!context->getExtensions().textureFloatOES &&
!context->getExtensions().textureHalfFloatOES)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM,
kEnumNotSupported, type); returnfalse;
} break; case GL_SHORT: case GL_UNSIGNED_SHORT: if (!context->getExtensions().textureNorm16EXT)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM,
kEnumNotSupported, type); returnfalse;
} break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; case GL_RGB: switch (type)
{ case GL_UNSIGNED_BYTE: case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: case GL_FLOAT: case GL_HALF_FLOAT_OES: break; case GL_SHORT: case GL_UNSIGNED_SHORT: if (!context->getExtensions().textureNorm16EXT)
{
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; case GL_RGBA: switch (type)
{ case GL_UNSIGNED_BYTE: case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_5_5_5_1: case GL_FLOAT: case GL_HALF_FLOAT_OES: case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: break; case GL_SHORT: case GL_UNSIGNED_SHORT: if (!context->getExtensions().textureNorm16EXT)
{
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; case GL_BGRA_EXT: if (!context->getExtensions().textureFormatBGRA8888EXT)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
format); returnfalse;
} switch (type)
{ case GL_UNSIGNED_BYTE: break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; case GL_SRGB_EXT: case GL_SRGB_ALPHA_EXT: if (!context->getExtensions().sRGBEXT)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
format); returnfalse;
} switch (type)
{ case GL_UNSIGNED_BYTE: break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; case GL_DEPTH_COMPONENT: switch (type)
{ case GL_UNSIGNED_SHORT: case GL_UNSIGNED_INT: break; case GL_FLOAT: if (!context->getExtensions().depthBufferFloat2NV)
{
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; case GL_DEPTH_STENCIL_OES: switch (type)
{ case GL_UNSIGNED_INT_24_8_OES: break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; case GL_STENCIL_INDEX: switch (type)
{ case GL_UNSIGNED_BYTE: break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
} break; default:
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, format); returnfalse;
}
switch (format)
{ case GL_DEPTH_COMPONENT: case GL_DEPTH_STENCIL_OES: if (!context->getExtensions().depthTextureANGLE &&
!((context->getExtensions().packedDepthStencilOES ||
context->getExtensions().depthTextureCubeMapOES) &&
context->getExtensions().depthTextureOES))
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
format); returnfalse;
}
switch (target)
{ case TextureTarget::_2D: break; case TextureTarget::CubeMapNegativeX: case TextureTarget::CubeMapNegativeY: case TextureTarget::CubeMapNegativeZ: case TextureTarget::CubeMapPositiveX: case TextureTarget::CubeMapPositiveY: case TextureTarget::CubeMapPositiveZ: if (!context->getExtensions().depthTextureCubeMapOES)
{
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTargetAndFormat); returnfalse;
} break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTargetAndFormat); returnfalse;
}
// OES_depth_texture supports loading depth data and multiple levels, // but ANGLE_depth_texture does not if (!context->getExtensions().depthTextureOES)
{ if (pixels != nullptr)
{
context->validationError(entryPoint, GL_INVALID_OPERATION,
kPixelDataNotNull); returnfalse;
} if (level != 0)
{
context->validationError(entryPoint, GL_INVALID_OPERATION, kLevelNotZero); returnfalse;
}
} break; case GL_STENCIL_INDEX: if (!context->getExtensions().textureStencil8OES)
{
context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat); returnfalse;
}
switch (target)
{ case TextureTarget::_2D: case TextureTarget::_2DArray: case TextureTarget::CubeMapNegativeX: case TextureTarget::CubeMapNegativeY: case TextureTarget::CubeMapNegativeZ: case TextureTarget::CubeMapPositiveX: case TextureTarget::CubeMapPositiveY: case TextureTarget::CubeMapPositiveZ: break; default:
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTargetAndFormat); returnfalse;
}
if (!isSubImage)
{ switch (internalformat)
{ // Core ES 2.0 formats case GL_ALPHA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: case GL_RGB: case GL_RGBA: break;
case GL_RGBA32F: if (!context->getExtensions().colorBufferFloatRgbaCHROMIUM)
{
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); returnfalse;
}
case GL_RGB32F: if (!context->getExtensions().colorBufferFloatRgbCHROMIUM)
{
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); returnfalse;
}
case GL_BGRA_EXT: if (!context->getExtensions().textureFormatBGRA8888EXT)
{
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); returnfalse;
} break;
case GL_DEPTH_COMPONENT: if (!(context->getExtensions().depthTextureAny()))
{
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); returnfalse;
} break;
case GL_DEPTH_STENCIL: if (!(context->getExtensions().depthTextureANGLE ||
context->getExtensions().packedDepthStencilOES ||
context->getExtensions().depthTextureCubeMapOES))
{
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); returnfalse;
} break;
case GL_STENCIL_INDEX8: if (!context->getExtensions().textureStencil8OES)
{
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); returnfalse;
} break;
case GL_RED: case GL_RG: if (!context->getExtensions().textureRgEXT)
{
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); returnfalse;
} break;
case GL_SRGB_EXT: case GL_SRGB_ALPHA_EXT: if (!context->getExtensions().sRGBEXT)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
internalformat); returnfalse;
} break;
case GL_RGB10_A2_EXT: if (!context->getExtensions().textureType2101010REVEXT)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
internalformat); returnfalse;
}
if (type != GL_UNSIGNED_INT_2_10_10_10_REV_EXT || format != GL_RGBA)
{
context->validationError(entryPoint, GL_INVALID_OPERATION,
kMismatchedTypeAndFormat); returnfalse;
}
nonEqualFormatsAllowed = true;
break;
case GL_RGB5_A1: if (context->getExtensions().textureType2101010REVEXT &&
type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGBA)
{
nonEqualFormatsAllowed = true;
}
break;
case GL_RGBX8_ANGLE: if (context->getExtensions().rgbxInternalFormatANGLE &&
type == GL_UNSIGNED_BYTE && format == GL_RGB)
{
nonEqualFormatsAllowed = true;
}
break;
case GL_R16_EXT: case GL_RG16_EXT: case GL_RGB16_EXT: case GL_RGBA16_EXT: case GL_R16_SNORM_EXT: case GL_RG16_SNORM_EXT: case GL_RGB16_SNORM_EXT: case GL_RGBA16_SNORM_EXT: if (!context->getExtensions().textureNorm16EXT)
{
context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
internalformat); returnfalse;
} break; default: // Compressed formats are not valid internal formats for glTexImage*D
context->validationErrorF(entryPoint, GL_INVALID_VALUE, kInvalidInternalFormat,
internalformat); returnfalse;
}
}
// From GL_CHROMIUM_color_buffer_float_rgb[a]: // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the // internalformat parameter and format parameter of TexImage2D must match is lifted for this // case. if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
{
context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormatCombination); returnfalse;
}
if (levels != 1 && !context->getExtensions().textureNpotOES)
{ if (!isPow2(width) || !isPow2(height))
{
context->validationError(entryPoint, GL_INVALID_OPERATION, kDimensionsMustBePow2); returnfalse;
}
}
if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
{
context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); returnfalse;
}
// Even with OES_texture_npot, some compressed formats may impose extra restrictions. if (formatInfo.compressed)
{ if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, 1))
{
context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCompressedImageSize); returnfalse;
}
}
switch (internalformat)
{ case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT32_OES: switch (target)
{ case TextureType::_2D: break; case TextureType::CubeMap: if (!context->getExtensions().depthTextureCubeMapOES)
{
context->validationError(entryPoint, GL_INVALID_OPERATION,
kInvalidTextureTarget); returnfalse;
} break; default:
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.25 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.