X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fglformats.c;h=77cf26337e10a175dee2f1e878bdfe91e14f4ecb;hb=55cf320ed87f902d817dfea363e6612be0c3b675;hp=04029c07c495d9524f89b0ec1e0408be8576f218;hpb=3ba9dbbabf591cfeb388cafbd9fa40cb784d32d9;p=mesa.git diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c index 04029c07c49..77cf26337e1 100644 --- a/src/mesa/main/glformats.c +++ b/src/mesa/main/glformats.c @@ -18,9 +18,10 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ @@ -271,7 +272,8 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type) case GL_UNSIGNED_INT_10_10_10_2: case GL_UNSIGNED_INT_2_10_10_10_REV: if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || - format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) + format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT || + format == GL_RGB) return sizeof(GLuint); else return -1; @@ -307,25 +309,60 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type) } +/** + * Get the number of bytes for a vertex attrib with the given number of + * components and type. + * + * \param comps number of components. + * \param type data type. + * + * \return bytes per attribute, or -1 if a bad comps/type combination was given. + */ +GLint +_mesa_bytes_per_vertex_attrib(GLint comps, GLenum type) +{ + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + return comps * sizeof(GLubyte); + case GL_SHORT: + case GL_UNSIGNED_SHORT: + return comps * sizeof(GLshort); + case GL_INT: + case GL_UNSIGNED_INT: + return comps * sizeof(GLint); + case GL_FLOAT: + return comps * sizeof(GLfloat); + case GL_HALF_FLOAT_ARB: + return comps * sizeof(GLhalfARB); + case GL_DOUBLE: + return comps * sizeof(GLdouble); + case GL_FIXED: + return comps * sizeof(GLfixed); + case GL_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (comps == 4) + return sizeof(GLuint); + else + return -1; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (comps == 3) + return sizeof(GLuint); + else + return -1; + default: + return -1; + } +} + + /** * Test if the given format is an integer (non-normalized) format. */ GLboolean -_mesa_is_enum_format_integer(GLenum format) +_mesa_is_enum_format_unsigned_int(GLenum format) { switch (format) { - /* generic integer formats */ - case GL_RED_INTEGER_EXT: - case GL_GREEN_INTEGER_EXT: - case GL_BLUE_INTEGER_EXT: - case GL_ALPHA_INTEGER_EXT: - case GL_RGB_INTEGER_EXT: - case GL_RGBA_INTEGER_EXT: - case GL_BGR_INTEGER_EXT: - case GL_BGRA_INTEGER_EXT: - case GL_LUMINANCE_INTEGER_EXT: - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - case GL_RG_INTEGER: /* specific integer formats */ case GL_RGBA32UI_EXT: case GL_RGB32UI_EXT: @@ -351,6 +388,34 @@ _mesa_is_enum_format_integer(GLenum format) case GL_INTENSITY8UI_EXT: case GL_LUMINANCE8UI_EXT: case GL_LUMINANCE_ALPHA8UI_EXT: + case GL_RGB10_A2UI: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * Test if the given format is an integer (non-normalized) format. + */ +GLboolean +_mesa_is_enum_format_signed_int(GLenum format) +{ + switch (format) { + /* generic integer formats */ + case GL_RED_INTEGER_EXT: + case GL_GREEN_INTEGER_EXT: + case GL_BLUE_INTEGER_EXT: + case GL_ALPHA_INTEGER_EXT: + case GL_RGB_INTEGER_EXT: + case GL_RGBA_INTEGER_EXT: + case GL_BGR_INTEGER_EXT: + case GL_BGRA_INTEGER_EXT: + case GL_LUMINANCE_INTEGER_EXT: + case GL_LUMINANCE_ALPHA_INTEGER_EXT: + case GL_RG_INTEGER: + /* specific integer formats */ case GL_RGBA32I_EXT: case GL_RGB32I_EXT: case GL_RG32I: @@ -375,7 +440,6 @@ _mesa_is_enum_format_integer(GLenum format) case GL_INTENSITY8I_EXT: case GL_LUMINANCE8I_EXT: case GL_LUMINANCE_ALPHA8I_EXT: - case GL_RGB10_A2UI: return GL_TRUE; default: return GL_FALSE; @@ -383,6 +447,17 @@ _mesa_is_enum_format_integer(GLenum format) } +/** + * Test if the given format is an integer (non-normalized) format. + */ +GLboolean +_mesa_is_enum_format_integer(GLenum format) +{ + return _mesa_is_enum_format_unsigned_int(format) || + _mesa_is_enum_format_signed_int(format); +} + + /** * Test if the given type is an integer (non-normalized) format. */ @@ -570,6 +645,16 @@ _mesa_is_color_format(GLenum format) case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI: case GL_ETC1_RGB8_OES: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: /* generic integer formats */ case GL_RED_INTEGER_EXT: case GL_GREEN_INTEGER_EXT: @@ -788,16 +873,17 @@ _mesa_is_compressed_format(struct gl_context *ctx, GLenum format) switch (format) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return ctx->Extensions.EXT_texture_compression_s3tc; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return _mesa_is_desktop_gl(ctx) - && ctx->Extensions.EXT_texture_compression_s3tc; + /* Assume that the ANGLE flag will always be set if the EXT flag is set. + */ + return ctx->Extensions.ANGLE_texture_compression_dxt; case GL_RGB_S3TC: case GL_RGB4_S3TC: case GL_RGBA_S3TC: case GL_RGBA4_S3TC: - return _mesa_is_desktop_gl(ctx) && ctx->Extensions.S3_s3tc; + return _mesa_is_desktop_gl(ctx) && + ctx->Extensions.ANGLE_texture_compression_dxt; case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: @@ -819,15 +905,25 @@ _mesa_is_compressed_format(struct gl_context *ctx, GLenum format) case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT: case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: - return ctx->API == API_OPENGL + return ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_texture_compression_latc; case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI: - return ctx->API == API_OPENGL + return ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ATI_texture_compression_3dc; case GL_ETC1_RGB8_OES: return _mesa_is_gles(ctx) && ctx->Extensions.OES_compressed_ETC1_RGB8_texture; -#if FEATURE_ES + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + return _mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility; case GL_PALETTE4_RGB8_OES: case GL_PALETTE4_RGBA8_OES: case GL_PALETTE4_R5_G6_B5_OES: @@ -839,7 +935,6 @@ _mesa_is_compressed_format(struct gl_context *ctx, GLenum format) case GL_PALETTE8_RGBA4_OES: case GL_PALETTE8_RGB5_A1_OES: return ctx->API == API_OPENGLES; -#endif default: return GL_FALSE; } @@ -968,6 +1063,32 @@ _mesa_base_format_has_channel(GLenum base_format, GLenum pname) } +/** + * Returns the number of channels/components for a base format. + */ +GLint +_mesa_base_format_component_count(GLenum base_format) +{ + switch (base_format) { + case GL_RED: + case GL_ALPHA: + case GL_INTENSITY: + case GL_DEPTH_COMPONENT: + return 1; + case GL_RG: + case GL_LUMINANCE_ALPHA: + case GL_DEPTH_STENCIL: + return 2; + case GL_RGB: + return 3; + case GL_RGBA: + return 4; + default: + return -1; + } +} + + /** * If format is a generic compressed format, return the corresponding * non-compressed format. For other formats, return the format as-is. @@ -1007,6 +1128,101 @@ _mesa_generic_compressed_format_to_uncompressed_format(GLenum format) } +/** + * Return the equivalent non-generic internal format. + * This is useful for comparing whether two internal formats are equivalent. + */ +GLenum +_mesa_get_nongeneric_internalformat(GLenum format) +{ + switch (format) { + /* GL 1.1 formats. */ + case 4: + case GL_RGBA: + return GL_RGBA8; + case 3: + case GL_RGB: + return GL_RGB8; + case 2: + case GL_LUMINANCE_ALPHA: + return GL_LUMINANCE8_ALPHA8; + case 1: + case GL_LUMINANCE: + return GL_LUMINANCE8; + case GL_ALPHA: + return GL_ALPHA8; + case GL_INTENSITY: + return GL_INTENSITY8; + + /* GL_ARB_texture_rg */ + case GL_RED: + return GL_R8; + case GL_RG: + return GL_RG8; + + /* GL_EXT_texture_sRGB */ + case GL_SRGB: + return GL_SRGB8; + case GL_SRGB_ALPHA: + return GL_SRGB8_ALPHA8; + case GL_SLUMINANCE: + return GL_SLUMINANCE8; + case GL_SLUMINANCE_ALPHA: + return GL_SLUMINANCE8_ALPHA8; + + /* GL_EXT_texture_snorm */ + case GL_RGBA_SNORM: + return GL_RGBA8_SNORM; + case GL_RGB_SNORM: + return GL_RGB8_SNORM; + case GL_RG_SNORM: + return GL_RG8_SNORM; + case GL_RED_SNORM: + return GL_R8_SNORM; + case GL_LUMINANCE_ALPHA_SNORM: + return GL_LUMINANCE8_ALPHA8_SNORM; + case GL_LUMINANCE_SNORM: + return GL_LUMINANCE8_SNORM; + case GL_ALPHA_SNORM: + return GL_ALPHA8_SNORM; + case GL_INTENSITY_SNORM: + return GL_INTENSITY8_SNORM; + + default: + return format; + } +} + + +/** + * Convert an sRGB internal format to linear. + */ +GLenum +_mesa_get_linear_internalformat(GLenum format) +{ + switch (format) { + case GL_SRGB: + return GL_RGB; + case GL_SRGB_ALPHA: + return GL_RGBA; + case GL_SRGB8: + return GL_RGB8; + case GL_SRGB8_ALPHA8: + return GL_RGBA8; + case GL_SLUMINANCE8: + return GL_LUMINANCE8; + case GL_SLUMINANCE: + return GL_LUMINANCE; + case GL_SLUMINANCE_ALPHA: + return GL_LUMINANCE_ALPHA; + case GL_SLUMINANCE8_ALPHA8: + return GL_LUMINANCE8_ALPHA8; + default: + return format; + } +} + + /** * Do error checking of format/type combinations for glReadPixels, * glDrawPixels and glTex[Sub]Image. Note that depending on the format @@ -1060,12 +1276,13 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, ctx->Extensions.ARB_texture_rgb10_a2ui) { break; /* OK */ } + if (type == GL_UNSIGNED_INT_2_10_10_10_REV && format == GL_RGB && + ctx->API == API_OPENGLES2) { + break; /* OK by GL_EXT_texture_type_2_10_10_10_REV */ + } return GL_INVALID_OPERATION; case GL_UNSIGNED_INT_24_8: - if (!ctx->Extensions.EXT_packed_depth_stencil) { - return GL_INVALID_ENUM; - } if (format != GL_DEPTH_STENCIL) { return GL_INVALID_OPERATION; } @@ -1106,10 +1323,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: - return GL_NO_ERROR; case GL_HALF_FLOAT: - return ctx->Extensions.ARB_half_float_pixel - ? GL_NO_ERROR : GL_INVALID_ENUM; + return GL_NO_ERROR; default: return GL_INVALID_ENUM; } @@ -1132,10 +1347,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: - return GL_NO_ERROR; case GL_HALF_FLOAT: - return ctx->Extensions.ARB_half_float_pixel - ? GL_NO_ERROR : GL_INVALID_ENUM; + return GL_NO_ERROR; default: return GL_INVALID_ENUM; } @@ -1151,10 +1364,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: - return GL_NO_ERROR; case GL_HALF_FLOAT: - return ctx->Extensions.ARB_half_float_pixel - ? GL_NO_ERROR : GL_INVALID_ENUM; + return GL_NO_ERROR; default: return GL_INVALID_ENUM; } @@ -1172,9 +1383,11 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_UNSIGNED_BYTE_2_3_3_REV: case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5_REV: - return GL_NO_ERROR; case GL_HALF_FLOAT: - return ctx->Extensions.ARB_half_float_pixel + return GL_NO_ERROR; + case GL_UNSIGNED_INT_2_10_10_10_REV: + /* OK by GL_EXT_texture_type_2_10_10_10_REV */ + return (ctx->API == API_OPENGLES2) ? GL_NO_ERROR : GL_INVALID_ENUM; case GL_UNSIGNED_INT_5_9_9_9_REV: return ctx->Extensions.EXT_texture_shared_exponent @@ -1198,10 +1411,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: - return GL_NO_ERROR; case GL_HALF_FLOAT: - return ctx->Extensions.ARB_half_float_pixel - ? GL_NO_ERROR : GL_INVALID_ENUM; + return GL_NO_ERROR; default: return GL_INVALID_ENUM; } @@ -1225,10 +1436,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_UNSIGNED_INT_8_8_8_8_REV: case GL_UNSIGNED_INT_10_10_10_2: case GL_UNSIGNED_INT_2_10_10_10_REV: - return GL_NO_ERROR; case GL_HALF_FLOAT: - return ctx->Extensions.ARB_half_float_pixel - ? GL_NO_ERROR : GL_INVALID_ENUM; + return GL_NO_ERROR; default: return GL_INVALID_ENUM; } @@ -1242,9 +1451,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, else return GL_INVALID_OPERATION; - case GL_DEPTH_STENCIL_EXT: - if (ctx->Extensions.EXT_packed_depth_stencil && - type == GL_UNSIGNED_INT_24_8) + case GL_DEPTH_STENCIL: + if (type == GL_UNSIGNED_INT_24_8) return GL_NO_ERROR; else if (ctx->Extensions.ARB_depth_buffer_float && type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) @@ -1441,3 +1649,436 @@ _mesa_es_error_check_format_and_type(GLenum format, GLenum type, return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION; } + + +/** + * Do error checking of format/type combinations for OpenGL ES 3 + * glTex[Sub]Image. + * \return error code, or GL_NO_ERROR. + */ +GLenum +_mesa_es3_error_check_format_and_type(GLenum format, GLenum type, + GLenum internalFormat) +{ + switch (format) { + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_BYTE: + switch (internalFormat) { + case GL_RGBA: + case GL_RGBA8: + case GL_RGB5_A1: + case GL_RGBA4: + case GL_SRGB8_ALPHA8_EXT: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_BYTE: + if (internalFormat != GL_RGBA8_SNORM) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_SHORT_4_4_4_4: + switch (internalFormat) { + case GL_RGBA: + case GL_RGBA4: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_UNSIGNED_SHORT_5_5_5_1: + switch (internalFormat) { + case GL_RGBA: + case GL_RGB5_A1: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_UNSIGNED_INT_2_10_10_10_REV: + switch (internalFormat) { + case GL_RGBA: /* GL_EXT_texture_type_2_10_10_10_REV */ + case GL_RGB10_A2: + case GL_RGB5_A1: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_HALF_FLOAT: + if (internalFormat != GL_RGBA16F) + return GL_INVALID_OPERATION; + break; + + case GL_FLOAT: + switch (internalFormat) { + case GL_RGBA16F: + case GL_RGBA32F: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_RGBA_INTEGER: + switch (type) { + case GL_UNSIGNED_BYTE: + if (internalFormat != GL_RGBA8UI) + return GL_INVALID_OPERATION; + break; + + case GL_BYTE: + if (internalFormat != GL_RGBA8I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_SHORT: + if (internalFormat != GL_RGBA16UI) + return GL_INVALID_OPERATION; + break; + + case GL_SHORT: + if (internalFormat != GL_RGBA16I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_INT: + if (internalFormat != GL_RGBA32UI) + return GL_INVALID_OPERATION; + break; + + case GL_INT: + if (internalFormat != GL_RGBA32I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (internalFormat != GL_RGB10_A2UI) + return GL_INVALID_OPERATION; + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_RGB: + switch (type) { + case GL_UNSIGNED_BYTE: + switch (internalFormat) { + case GL_RGB: + case GL_RGB8: + case GL_RGB565: + case GL_SRGB8: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_BYTE: + if (internalFormat != GL_RGB8_SNORM) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_SHORT_5_6_5: + switch (internalFormat) { + case GL_RGB: + case GL_RGB565: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (internalFormat != GL_R11F_G11F_B10F) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_INT_5_9_9_9_REV: + if (internalFormat != GL_RGB9_E5) + return GL_INVALID_OPERATION; + break; + + case GL_HALF_FLOAT: + switch (internalFormat) { + case GL_RGB16F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_FLOAT: + switch (internalFormat) { + case GL_RGB16F: + case GL_RGB32F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_UNSIGNED_INT_2_10_10_10_REV: + switch (internalFormat) { + case GL_RGB: /* GL_EXT_texture_type_2_10_10_10_REV */ + break; + default: + return GL_INVALID_OPERATION; + } + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_RGB_INTEGER: + switch (type) { + case GL_UNSIGNED_BYTE: + if (internalFormat != GL_RGB8UI) + return GL_INVALID_OPERATION; + break; + + case GL_BYTE: + if (internalFormat != GL_RGB8I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_SHORT: + if (internalFormat != GL_RGB16UI) + return GL_INVALID_OPERATION; + break; + + case GL_SHORT: + if (internalFormat != GL_RGB16I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_INT: + if (internalFormat != GL_RGB32UI) + return GL_INVALID_OPERATION; + break; + + case GL_INT: + if (internalFormat != GL_RGB32I) + return GL_INVALID_OPERATION; + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_RG: + switch (type) { + case GL_UNSIGNED_BYTE: + if (internalFormat != GL_RG8) + return GL_INVALID_OPERATION; + break; + + case GL_BYTE: + if (internalFormat != GL_RG8_SNORM) + return GL_INVALID_OPERATION; + break; + + case GL_HALF_FLOAT: + if (internalFormat != GL_RG16F) + return GL_INVALID_OPERATION; + break; + + case GL_FLOAT: + switch (internalFormat) { + case GL_RG16F: + case GL_RG32F: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_RG_INTEGER: + switch (type) { + case GL_UNSIGNED_BYTE: + if (internalFormat != GL_RG8UI) + return GL_INVALID_OPERATION; + break; + + case GL_BYTE: + if (internalFormat != GL_RG8I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_SHORT: + if (internalFormat != GL_RG16UI) + return GL_INVALID_OPERATION; + break; + + case GL_SHORT: + if (internalFormat != GL_RG16I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_INT: + if (internalFormat != GL_RG32UI) + return GL_INVALID_OPERATION; + break; + + case GL_INT: + if (internalFormat != GL_RG32I) + return GL_INVALID_OPERATION; + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_RED: + switch (type) { + case GL_UNSIGNED_BYTE: + if (internalFormat != GL_R8) + return GL_INVALID_OPERATION; + break; + + case GL_BYTE: + if (internalFormat != GL_R8_SNORM) + return GL_INVALID_OPERATION; + break; + + case GL_HALF_FLOAT: + if (internalFormat != GL_R16F) + return GL_INVALID_OPERATION; + break; + + case GL_FLOAT: + switch (internalFormat) { + case GL_R16F: + case GL_R32F: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_RED_INTEGER: + switch (type) { + case GL_UNSIGNED_BYTE: + if (internalFormat != GL_R8UI) + return GL_INVALID_OPERATION; + break; + + case GL_BYTE: + if (internalFormat != GL_R8I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_SHORT: + if (internalFormat != GL_R16UI) + return GL_INVALID_OPERATION; + break; + + case GL_SHORT: + if (internalFormat != GL_R16I) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_INT: + if (internalFormat != GL_R32UI) + return GL_INVALID_OPERATION; + break; + + case GL_INT: + if (internalFormat != GL_R32I) + return GL_INVALID_OPERATION; + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_DEPTH_COMPONENT: + switch (type) { + case GL_UNSIGNED_SHORT: + if (internalFormat != GL_DEPTH_COMPONENT + && internalFormat != GL_DEPTH_COMPONENT16) + return GL_INVALID_OPERATION; + break; + + case GL_UNSIGNED_INT: + switch (internalFormat) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + break; + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_FLOAT: + if (internalFormat != GL_DEPTH_COMPONENT32F) + return GL_INVALID_OPERATION; + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_DEPTH_STENCIL: + switch (type) { + case GL_UNSIGNED_INT_24_8: + if (internalFormat != GL_DEPTH_STENCIL + && internalFormat != GL_DEPTH24_STENCIL8) + return GL_INVALID_OPERATION; + break; + + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + if (internalFormat != GL_DEPTH32F_STENCIL8) + return GL_INVALID_OPERATION; + break; + + default: + return GL_INVALID_OPERATION; + } + break; + + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + if (type != GL_UNSIGNED_BYTE || format != internalFormat) + return GL_INVALID_OPERATION; + break; + } + + return GL_NO_ERROR; +}