// // 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. //
// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the // implementation can decide the true, sized, internal format. The ES2FormatMap determines the // internal format for all valid format and type combinations.
GLenum GetSizedFormatInternal(GLenum format, GLenum type);
// Check support for a single extension template <ExtensionBool bool1> staticbool RequireExt(const Version &, const Extensions &extensions)
{ return extensions.*bool1;
}
// Check for a minimum client version or a single extension template <GLuint minCoreGLMajorVersion, GLuint minCoreGLMinorVersion, ExtensionBool bool1> staticbool RequireESOrExt(const Version &clientVersion, const Extensions &extensions)
{ return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
extensions.*bool1;
}
// Check for a minimum client version or two extensions template <GLuint minCoreGLMajorVersion,
GLuint minCoreGLMinorVersion,
ExtensionBool bool1,
ExtensionBool bool2> staticbool RequireESOrExtAndExt(const Version &clientVersion, const Extensions &extensions)
{ return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
(extensions.*bool1 && extensions.*bool2);
}
// Check for a minimum client version or at least one of two extensions template <GLuint minCoreGLMajorVersion,
GLuint minCoreGLMinorVersion,
ExtensionBool bool1,
ExtensionBool bool2> staticbool RequireESOrExtOrExt(const Version &clientVersion, const Extensions &extensions)
{ return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
extensions.*bool1 || extensions.*bool2;
}
// Check support for two extensions template <ExtensionBool bool1, ExtensionBool bool2> staticbool RequireExtAndExt(const Version &, const Extensions &extensions)
{ return extensions.*bool1 && extensions.*bool2;
}
// Check support for either of two extensions template <ExtensionBool bool1, ExtensionBool bool2> staticbool RequireExtOrExt(const Version &, const Extensions &extensions)
{ return extensions.*bool1 || extensions.*bool2;
}
// Check support for any of three extensions template <ExtensionBool bool1, ExtensionBool bool2, ExtensionBool bool3> staticbool RequireExtOrExtOrExt(const Version &, const Extensions &extensions)
{ return extensions.*bool1 || extensions.*bool2 || extensions.*bool3;
}
staticbool SizedHalfFloatRGBTextureAttachmentSupport(const Version &clientVersion, const Extensions &extensions)
{ // HALF_FLOAT if (clientVersion >= Version(3, 0))
{ // It is unclear how EXT_color_buffer_half_float applies to ES3.0 and above, however, // dEQP GLES3 es3fFboColorbufferTests.cpp verifies that texture attachment of GL_RGB16F // is possible, so assume that all GLES implementations support it. // The WebGL version of the extension explicitly forbids RGB formats. return extensions.colorBufferHalfFloatEXT && !extensions.webglCompatibilityANGLE;
} // HALF_FLOAT_OES else
{ return SizedHalfFloatOESTextureAttachmentSupport(clientVersion, extensions);
}
}
staticbool SizedFloatRGBARenderableSupport(const Version &clientVersion, const Extensions &extensions)
{ // This logic is the same for both Renderbuffers and TextureAttachment. return extensions.colorBufferFloatRgbaCHROMIUM || // ES2
extensions.colorBufferFloatEXT; // ES3
}
staticbool Float32BlendableSupport(const Version &clientVersion, const Extensions &extensions)
{ // EXT_float_blend may be exposed on ES2 client contexts. Ensure that RGBA32F is renderable. return (extensions.colorBufferFloatRgbaCHROMIUM || extensions.colorBufferFloatEXT) &&
extensions.floatBlendEXT;
}
template <ExtensionBool bool1> staticbool ETC2EACSupport(const Version &clientVersion, const Extensions &extensions)
{ if (extensions.compressedTextureEtcANGLE)
{ returntrue;
}
// ETC2/EAC formats are always available in ES 3.0+ but require an extension (checked above) // in WebGL. If that extension is not available, hide these formats from WebGL contexts. return !extensions.webglCompatibilityANGLE &&
(clientVersion >= Version(3, 0) || extensions.*bool1);
}
GLenum InternalFormat::getReadPixelsFormat(const Extensions &extensions) const
{ switch (format)
{ case GL_BGRA_EXT: // BGRA textures may be enabled but calling glReadPixels with BGRA is disallowed without // GL_EXT_texture_format_BGRA8888. Read as RGBA instead. if (!extensions.readFormatBgraEXT)
{ return GL_RGBA;
} return GL_BGRA_EXT;
default: return format;
}
}
GLenum InternalFormat::getReadPixelsType(const Version &version) const
{ switch (type)
{ case GL_HALF_FLOAT: case GL_HALF_FLOAT_OES: if (version < Version(3, 0))
{ // The internal format may have a type of GL_HALF_FLOAT but when exposing this type // as the IMPLEMENTATION_READ_TYPE, only HALF_FLOAT_OES is allowed by // OES_texture_half_float. HALF_FLOAT becomes core in ES3 and is acceptable to use // as an IMPLEMENTATION_READ_TYPE. return GL_HALF_FLOAT_OES;
} return GL_HALF_FLOAT;
bool InternalFormat::isRequiredRenderbufferFormat(const Version &version) const
{ // GLES 3.0.5 section 4.4.2.2: // "Implementations are required to support the same internal formats for renderbuffers as the // required formats for textures enumerated in section 3.8.3.1, with the exception of the color // formats labelled "texture-only"." if (!sized || compressed)
{ returnfalse;
}
// Required formats in all versions. switch (internalFormat)
{ case GL_DEPTH_COMPONENT16: case GL_STENCIL_INDEX8: // Note that STENCIL_INDEX8 is not mentioned in GLES 3.0.5 section 3.8.3.1, but it // is in section 4.4.2.2. returntrue; default: break;
} if (version.major < 3)
{ returnfalse;
} // Required formats in GLES 3.0 and up. switch (internalFormat)
{ case GL_DEPTH_COMPONENT32F: case GL_DEPTH_COMPONENT24: case GL_DEPTH32F_STENCIL8: case GL_DEPTH24_STENCIL8: returntrue; default: returnfalse;
}
}
// Required formats in all versions. switch (internalFormat)
{ case GL_RGBA4: case GL_RGB5_A1: case GL_RGB565: returntrue; default: break;
} if (version.major < 3)
{ returnfalse;
}
if (format == GL_BGRA_EXT)
{ returnfalse;
}
switch (componentType)
{ case GL_SIGNED_NORMALIZED: case GL_FLOAT: returnfalse; case GL_UNSIGNED_INT: case GL_INT: // Integer RGB formats are not required renderbuffer formats. if (alphaBits == 0 && blueBits != 0)
{ returnfalse;
} // All integer R and RG formats are required. // Integer RGBA formats including RGB10_A2_UI are required. returntrue; case GL_UNSIGNED_NORMALIZED: if (internalFormat == GL_SRGB8)
{ returnfalse;
} returntrue; default:
UNREACHABLE(); returnfalse;
}
}
// static bool Format::SameSized(const Format &a, const Format &b)
{ return a.info->sizedInternalFormat == b.info->sizedInternalFormat;
}
static GLenum EquivalentBlitInternalFormat(GLenum internalformat)
{ // BlitFramebuffer works if the color channels are identically // sized, even if there is a swizzle (for example, blitting from a // multisampled RGBA8 renderbuffer to a BGRA8 texture). This could // be expanded and/or autogenerated if that is found necessary. if (internalformat == GL_BGRA8_EXT)
{ return GL_RGBA8;
}
// GL_ANGLE_rgbx_internal_format: Treat RGBX8 as RGB8, since the X channel is ignored. if (internalformat == GL_RGBX8_ANGLE)
{ return GL_RGB8;
}
// Treat ANGLE's BGRX8 as RGB8 since it's swizzled and the X channel is ignored. if (internalformat == GL_BGRX8_ANGLEX)
{ return GL_RGB8;
}
return internalformat;
}
// static bool Format::EquivalentForBlit(const Format &a, const Format &b)
{ return (EquivalentBlitInternalFormat(a.info->sizedInternalFormat) ==
EquivalentBlitInternalFormat(b.info->sizedInternalFormat));
}
// static
Format Format::Invalid()
{ static Format invalid(GL_NONE, GL_NONE); return invalid;
}
std::ostream &operator<<(std::ostream &os, const Format &fmt)
{ // TODO(ynovikov): return string representation when available return FmtHex(os, fmt.info->sizedInternalFormat);
}
bool InternalFormat::operator==(const InternalFormat &other) const
{ // We assume all internal formats are unique if they have the same internal format and type return internalFormat == other.internalFormat && type == other.type;
}
// Chroma planes of a YUV format can be subsampled int horizontalSubsampleFactor = 0; int verticalSubsampleFactor = 0;
gl::GetSubSampleFactor(internalFormat, &horizontalSubsampleFactor, &verticalSubsampleFactor);
// YUV format related helpers bool IsYuvFormat(GLenum format)
{ switch (format)
{ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: returntrue; default: returnfalse;
}
}
uint32_t GetPlaneCount(GLenum format)
{ switch (format)
{ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: return 2; case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: return 3; default:
UNREACHABLE(); return 0;
}
}
uint32_t GetYPlaneBpp(GLenum format)
{ switch (format)
{ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: return 1; case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: return 2; default:
UNREACHABLE(); return 0;
}
}
uint32_t GetChromaPlaneBpp(GLenum format)
{ // 2 plane 420 YUV formats have CbCr channels interleaved. // 3 plane 420 YUV formats have separate Cb and Cr planes. switch (format)
{ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: return 1; case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE: return 2; case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: return 4; default:
UNREACHABLE(); return 0;
}
}
void GetSubSampleFactor(GLenum format, int *horizontalSubsampleFactor, int *verticalSubsampleFactor)
{
ASSERT(horizontalSubsampleFactor && verticalSubsampleFactor);
switch (format)
{ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE: case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE: case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE: case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE: case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE: case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE:
*horizontalSubsampleFactor = 2;
*verticalSubsampleFactor = 2; break; default:
UNREACHABLE(); break;
}
}
// Notes: // 1. "Texture supported" includes all the means by which texture can be created, however, // GL_EXT_texture_storage in ES2 is a special case, when only glTexStorage* is allowed. // The assumption is that ES2 validation will not check textureSupport for sized formats. // // 2. Sized half float types are a combination of GL_HALF_FLOAT and GL_HALF_FLOAT_OES support, // due to a limitation that only one type for sized formats is allowed. // // TODO(ynovikov): http://anglebug.com/2846 Verify support fields of BGRA, depth, stencil // and compressed formats. Perform texturable check as part of filterable and attachment checks. static InternalFormatInfoMap BuildInternalFormatInfoMap()
{
InternalFormatInfoMap map;
// From ES 3.0.1 spec, table 3.12
map[GL_NONE][GL_NONE] = InternalFormat();
// Special format that is used for D3D textures that are used within ANGLE via the // EGL_ANGLE_d3d_texture_client_buffer extension. We don't allow uploading texture images with // this format, but textures in this format can be created from D3D textures, and filtering them // and rendering to them is allowed.
AddRGBAFormat(&map, GL_BGRA8_SRGB_ANGLEX, true, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, NeverSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported);
// Special format which is not really supported, so always false for all supports.
AddRGBAFormat(&map, GL_BGR565_ANGLEX, true, 5, 6, 5, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
AddRGBAFormat(&map, GL_BGR10_A2_ANGLEX, true, 10, 10, 10, 2, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
// Special format to emulate RGB8 with RGBA8 within ANGLE.
AddRGBAFormat(&map, GL_RGBX8_ANGLE, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, NeverSupported);
// Special format to emulate BGR8 with BGRA8 within ANGLE.
AddRGBAFormat(&map, GL_BGRX8_ANGLEX, true, 8, 8, 8, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
// This format is supported on ES 2.0 with two extensions, so keep it out-of-line to not widen the table above even more. // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
AddRGBAFormat(&map, GL_RGB10_A2, true, 10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireESOrExtAndExt<3, 0, &Extensions::textureStorageEXT, &Extensions::textureType2101010REVEXT>, AlwaysSupported, RequireES<3, 0>, RequireES<3, 0>, RequireES<3, 0>);
// Floating point formats // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend // It's not possible to have two entries per sized format. // E.g. for GL_RG16F, one with GL_HALF_FLOAT type and the other with GL_HALF_FLOAT_OES type. // So, GL_HALF_FLOAT type formats conditions are merged with GL_HALF_FLOAT_OES type conditions.
AddRGBAFormat(&map, GL_R16F, true, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatRGSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGTextureAttachmentSupport, SizedHalfFloatRGRenderbufferSupport, SizedHalfFloatRGRenderbufferSupport);
AddRGBAFormat(&map, GL_RG16F, true, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatRGSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGTextureAttachmentSupport, SizedHalfFloatRGRenderbufferSupport, SizedHalfFloatRGRenderbufferSupport);
AddRGBAFormat(&map, GL_RGB16F, true, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGBTextureAttachmentSupport, SizedHalfFloatRGBRenderbufferSupport, SizedHalfFloatRGBRenderbufferSupport);
AddRGBAFormat(&map, GL_RGBA16F, true, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGBATextureAttachmentSupport, SizedHalfFloatRGBARenderbufferSupport, SizedHalfFloatRGBARenderbufferSupport);
AddRGBAFormat(&map, GL_R32F, true, 32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, SizedFloatRGSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>, Float32BlendableSupport);
AddRGBAFormat(&map, GL_RG32F, true, 32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, SizedFloatRGSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>, Float32BlendableSupport);
AddRGBAFormat(&map, GL_RGB32F, true, 32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, SizedFloatRGBSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatRgbCHROMIUM>, NeverSupported, NeverSupported);
AddRGBAFormat(&map, GL_RGBA32F, true, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, SizedFloatRGBASupport, RequireExt<&Extensions::textureFloatLinearOES>, SizedFloatRGBARenderableSupport, SizedFloatRGBARenderableSupport, Float32BlendableSupport);
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.