static bool copy_format_compatible(const struct gl_context *ctx, GLenum srcFormat, GLenum dstFormat) { /* * From ARB_copy_image spec: * For the purposes of CopyImageSubData, two internal formats * are considered compatible if any of the following conditions are * met: * * the formats are the same, * * the formats are considered compatible according to the * compatibility rules used for texture views as defined in * section 3.9.X. In particular, if both internal formats are listed * in the same entry of Table 3.X.2, they are considered compatible, or * * one format is compressed and the other is uncompressed and * Table 4.X.1 lists the two formats in the same row. */ if (_mesa_texture_view_compatible_format(ctx, srcFormat, dstFormat)) { /* Also checks if formats are equal. */ return true; } else if (_mesa_is_compressed_format(ctx, srcFormat)) { return compressed_format_compatible(ctx, srcFormat, dstFormat); } else if (_mesa_is_compressed_format(ctx, dstFormat)) { return compressed_format_compatible(ctx, dstFormat, srcFormat); } return false; }
/** * Do error checking for calls to glTexStorage1/2/3D(). * If an error is found, record it with _mesa_error(), unless the target * is a proxy texture. * \return GL_TRUE if any error, GL_FALSE otherwise. */ static GLboolean tex_storage_error_check(struct gl_context *ctx, struct gl_texture_object *texObj, GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool dsa) { const char* suffix = dsa ? "ture" : ""; /* Legal format checking has been moved to texstorage and texturestorage in * order to allow meta functions to use legacy formats. */ /* size check */ if (!_mesa_valid_tex_storage_dim(width, height, depth)) { _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(width, height or depth < 1)", suffix, dims); return GL_TRUE; } if (_mesa_is_compressed_format(ctx, internalformat)) { GLenum err; if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) { _mesa_error(ctx, err, "glTex%sStorage%dD(internalformat = %s)", suffix, dims, _mesa_enum_to_string(internalformat)); return GL_TRUE; } } /* levels check */ if (levels < 1) { _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)", suffix, dims); return GL_TRUE; } /* check levels against maximum (note different error than above) */ if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(levels too large)", suffix, dims); return GL_TRUE; } /* check levels against width/height/depth */ if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(too many levels" " for max texture dimension)", suffix, dims); return GL_TRUE; } /* non-default texture object check */ if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(texture object 0)", suffix, dims); return GL_TRUE; } /* Check if texObj->Immutable is set */ if (!_mesa_is_proxy_texture(target) && texObj->Immutable) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)", suffix, dims); return GL_TRUE; } /* additional checks for depth textures */ if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(bad target for texture)", suffix, dims); return GL_TRUE; } return GL_FALSE; }
static bool compressed_format_compatible(const struct gl_context *ctx, GLenum compressedFormat, GLenum otherFormat) { enum mesa_block_class compressedClass, otherClass; /* Two view-incompatible compressed formats are never compatible. */ if (_mesa_is_compressed_format(ctx, otherFormat)) { return false; } /* * From ARB_copy_image spec: * Table 4.X.1 (Compatible internal formats for copying between * compressed and uncompressed internal formats) * --------------------------------------------------------------------- * | Texel / | Uncompressed | | * | Block | internal format | Compressed internal format | * | size | | | * --------------------------------------------------------------------- * | 128-bit | RGBA32UI, | COMPRESSED_RGBA_S3TC_DXT3_EXT, | * | | RGBA32I, | COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,| * | | RGBA32F | COMPRESSED_RGBA_S3TC_DXT5_EXT, | * | | | COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,| * | | | COMPRESSED_RG_RGTC2, | * | | | COMPRESSED_SIGNED_RG_RGTC2, | * | | | COMPRESSED_RGBA_BPTC_UNORM, | * | | | COMPRESSED_SRGB_ALPHA_BPTC_UNORM, | * | | | COMPRESSED_RGB_BPTC_SIGNED_FLOAT, | * | | | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT | * --------------------------------------------------------------------- * | 64-bit | RGBA16F, RG32F, | COMPRESSED_RGB_S3TC_DXT1_EXT, | * | | RGBA16UI, RG32UI, | COMPRESSED_SRGB_S3TC_DXT1_EXT, | * | | RGBA16I, RG32I, | COMPRESSED_RGBA_S3TC_DXT1_EXT, | * | | RGBA16, | COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,| * | | RGBA16_SNORM | COMPRESSED_RED_RGTC1, | * | | | COMPRESSED_SIGNED_RED_RGTC1 | * --------------------------------------------------------------------- */ switch (compressedFormat) { case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 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: compressedClass = BLOCK_CLASS_128_BITS; break; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_SIGNED_RED_RGTC1: compressedClass = BLOCK_CLASS_64_BITS; break; default: return false; } switch (otherFormat) { case GL_RGBA32UI: case GL_RGBA32I: case GL_RGBA32F: otherClass = BLOCK_CLASS_128_BITS; break; case GL_RGBA16F: case GL_RG32F: case GL_RGBA16UI: case GL_RG32UI: case GL_RGBA16I: case GL_RG32I: case GL_RGBA16: case GL_RGBA16_SNORM: otherClass = BLOCK_CLASS_64_BITS; break; default: return false; } return compressedClass == otherClass; }
/** * Choose an appropriate texture format given the format, type and * internalFormat parameters passed to glTexImage(). * * \param ctx the GL context. * \param target a texture target (GL_TEXTURE_x) * \param internalFormat user's prefered internal texture format. * \param format incoming image pixel format. * \param type incoming image data type. * * \return the closest mesa_format for the given format/type arguments * * This is called via dd_function_table::ChooseTextureFormat. Hardware * drivers may override this function with a specialized version. */ mesa_format _mesa_choose_tex_format(struct gl_context *ctx, GLenum target, GLint internalFormat, GLenum format, GLenum type) { (void) format; switch (internalFormat) { /* shallow RGBA formats */ case 4: case GL_RGBA: if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { RETURN_IF_SUPPORTED(MESA_FORMAT_B4G4R4A4_UNORM); } else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { RETURN_IF_SUPPORTED(MESA_FORMAT_B5G5R5A1_UNORM); } else if (type == GL_UNSIGNED_SHORT_5_5_5_1) { RETURN_IF_SUPPORTED(MESA_FORMAT_B5G5R5A1_UNORM); } else if (type == GL_UNSIGNED_INT_2_10_10_10_REV) { RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UNORM); } /* fallthrough */ case GL_RGBA8: RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; case GL_RGB5_A1: RETURN_IF_SUPPORTED(MESA_FORMAT_B5G5R5A1_UNORM); break; case GL_RGBA2: RETURN_IF_SUPPORTED(MESA_FORMAT_A4R4G4B4_UNORM); /* just to test another format*/ RETURN_IF_SUPPORTED(MESA_FORMAT_B4G4R4A4_UNORM); break; case GL_RGBA4: RETURN_IF_SUPPORTED(MESA_FORMAT_B4G4R4A4_UNORM); break; /* deep RGBA formats */ case GL_RGB10_A2: RETURN_IF_SUPPORTED(MESA_FORMAT_R10G10B10A2_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; case GL_RGBA12: case GL_RGBA16: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; /* shallow RGB formats */ case 3: case GL_RGB: if (type == GL_UNSIGNED_INT_2_10_10_10_REV) { RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UNORM); } /* fallthrough */ case GL_RGB8: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8X8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_UNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; case GL_R3_G3_B2: RETURN_IF_SUPPORTED(MESA_FORMAT_B2G3R3_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R5G6B5_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_UNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; case GL_RGB4: RETURN_IF_SUPPORTED(MESA_FORMAT_R5G6B5_UNORM); /* just to test another format */ RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); break; case GL_RGB5: RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); break; /* deep RGB formats */ case GL_RGB10: case GL_RGB12: case GL_RGB16: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_UNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; /* Alpha formats */ case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8: RETURN_IF_SUPPORTED(MESA_FORMAT_A_UNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_UNORM); break; case GL_ALPHA12: case GL_ALPHA16: RETURN_IF_SUPPORTED(MESA_FORMAT_A_UNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_A_UNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_UNORM); break; /* Luminance formats */ case 1: case GL_LUMINANCE: case GL_LUMINANCE4: case GL_LUMINANCE8: RETURN_IF_SUPPORTED(MESA_FORMAT_L_UNORM8); break; case GL_LUMINANCE12: case GL_LUMINANCE16: RETURN_IF_SUPPORTED(MESA_FORMAT_L_UNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_L_UNORM8); break; /* Luminance/Alpha formats */ case GL_LUMINANCE4_ALPHA4: RETURN_IF_SUPPORTED(MESA_FORMAT_L4A4_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_UNORM); break; case 2: case GL_LUMINANCE_ALPHA: case GL_LUMINANCE6_ALPHA2: case GL_LUMINANCE8_ALPHA8: RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_UNORM); break; case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: RETURN_IF_SUPPORTED(MESA_FORMAT_L16A16_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_UNORM); break; case GL_INTENSITY: case GL_INTENSITY4: case GL_INTENSITY8: RETURN_IF_SUPPORTED(MESA_FORMAT_I_UNORM8); break; case GL_INTENSITY12: case GL_INTENSITY16: RETURN_IF_SUPPORTED(MESA_FORMAT_I_UNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_I_UNORM8); break; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32: RETURN_IF_SUPPORTED(MESA_FORMAT_Z_UNORM32); RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_X8_UINT); RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT); break; case GL_DEPTH_COMPONENT16: RETURN_IF_SUPPORTED(MESA_FORMAT_Z_UNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_X8_UINT); RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT); break; case GL_COMPRESSED_ALPHA_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_A_UNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_UNORM); break; case GL_COMPRESSED_LUMINANCE_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_L_UNORM8); break; case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_UNORM); break; case GL_COMPRESSED_INTENSITY_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_I_UNORM8); break; case GL_COMPRESSED_RGB_ARB: /* We don't use texture compression for 1D and 1D array textures. * For 1D textures, compressions doesn't buy us much. * For 1D ARRAY textures, there's complicated issues with updating * sub-regions on non-block boundaries with glCopyTexSubImage, among * other issues. FWIW, the GL_EXT_texture_array extension prohibits * 1D ARRAY textures in S3TC format. */ if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) { if (ctx->Mesa_DXTn) RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1); RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FXT1); } RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_UNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; case GL_COMPRESSED_RGBA_ARB: /* We don't use texture compression for 1D and 1D array textures. */ if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) { if (ctx->Mesa_DXTn) RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3); /* Not rgba_dxt1, see spec */ RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FXT1); } RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; case GL_RGB565: RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); break; case GL_YCBCR_MESA: if (type == GL_UNSIGNED_SHORT_8_8_MESA) RETURN_IF_SUPPORTED(MESA_FORMAT_YCBCR); else RETURN_IF_SUPPORTED(MESA_FORMAT_YCBCR_REV); break; case GL_ALPHA16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_A_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_A_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_ALPHA32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_A_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_A_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_LUMINANCE16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_L_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_L_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_LUMINANCE32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_L_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_L_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_LUMINANCE_ALPHA16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_LA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_LUMINANCE_ALPHA32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_LA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_INTENSITY16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_I_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_I_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_INTENSITY32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_I_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_I_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_RGB16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_RGB32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_RGBA16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_RGBA32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_RGB9_E5: /* GL_EXT_texture_shared_exponent -- just one format to support */ assert(ctx->TextureFormatSupported[MESA_FORMAT_R9G9B9E5_FLOAT]); return MESA_FORMAT_R9G9B9E5_FLOAT; case GL_R11F_G11F_B10F: /* GL_EXT_texture_packed_float -- just one format to support */ assert(ctx->TextureFormatSupported[MESA_FORMAT_R11G11B10_FLOAT]); return MESA_FORMAT_R11G11B10_FLOAT; case GL_DEPTH_STENCIL_EXT: case GL_DEPTH24_STENCIL8_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_S8_UINT_Z24_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT); break; case GL_DEPTH_COMPONENT32F: assert(ctx->TextureFormatSupported[MESA_FORMAT_Z_FLOAT32]); return MESA_FORMAT_Z_FLOAT32; case GL_DEPTH32F_STENCIL8: assert(ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT_S8X24_UINT]); return MESA_FORMAT_Z32_FLOAT_S8X24_UINT; case GL_RED_SNORM: case GL_R8_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_R_SNORM8); break; case GL_RG_SNORM: case GL_RG8_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8_SNORM); break; case GL_RGB_SNORM: case GL_RGB8_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8X8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_X8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); break; case GL_RGBA_SNORM: case GL_RGBA8_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_ALPHA_SNORM: case GL_ALPHA8_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_A_SNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_LUMINANCE_SNORM: case GL_LUMINANCE8_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_L_SNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_X8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_LUMINANCE_ALPHA_SNORM: case GL_LUMINANCE8_ALPHA8_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_A8L8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_INTENSITY_SNORM: case GL_INTENSITY8_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_I_SNORM8); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_R16_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_R_SNORM16); break; case GL_RG16_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_R16G16_SNORM); break; case GL_RGB16_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_SNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_SNORM16); /* FALLTHROUGH */ case GL_RGBA16_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_ALPHA16_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_A_SNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_LUMINANCE16_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_L_SNORM16); /* FALLTHROUGH */ case GL_LUMINANCE16_ALPHA16_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_INTENSITY16_SNORM: RETURN_IF_SUPPORTED(MESA_FORMAT_I_SNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SNORM16); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); break; case GL_SRGB_EXT: case GL_SRGB8_EXT: /* there is no MESA_FORMAT_RGB_SRGB8 */ RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8X8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_SRGB8); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_X8B8G8R8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); break; case GL_SRGB_ALPHA_EXT: case GL_SRGB8_ALPHA8_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); break; case GL_SLUMINANCE_EXT: case GL_SLUMINANCE8_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L_SRGB8); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); break; case GL_SLUMINANCE_ALPHA_EXT: case GL_SLUMINANCE8_ALPHA8_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8L8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); break; case GL_COMPRESSED_SLUMINANCE_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L_SRGB8); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); break; case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8L8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); break; case GL_COMPRESSED_SRGB_EXT: if (ctx->Mesa_DXTn) RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1); RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_SRGB8); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); break; case GL_COMPRESSED_SRGB_ALPHA_EXT: if (ctx->Mesa_DXTn) RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3); /* Not srgba_dxt1, see spec */ RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); break; case GL_ALPHA8UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_A_UINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); break; case GL_ALPHA16UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_A_UINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); break; case GL_ALPHA32UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_A_UINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); break; case GL_ALPHA8I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_A_SINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); break; case GL_ALPHA16I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_A_SINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); break; case GL_ALPHA32I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_A_SINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); break; case GL_LUMINANCE8UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L_UINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); break; case GL_LUMINANCE16UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L_UINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); break; case GL_LUMINANCE32UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L_UINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); break; case GL_LUMINANCE8I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L_SINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); break; case GL_LUMINANCE16I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L_SINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); break; case GL_LUMINANCE32I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_L_SINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); break; case GL_LUMINANCE_ALPHA8UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); break; case GL_LUMINANCE_ALPHA16UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); break; case GL_LUMINANCE_ALPHA32UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); break; case GL_LUMINANCE_ALPHA8I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); break; case GL_LUMINANCE_ALPHA16I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); break; case GL_LUMINANCE_ALPHA32I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); break; case GL_INTENSITY8UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_I_UINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); break; case GL_INTENSITY16UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_I_UINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); break; case GL_INTENSITY32UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_I_UINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); break; case GL_INTENSITY8I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_I_SINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); break; case GL_INTENSITY16I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_I_SINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); break; case GL_INTENSITY32I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_I_SINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); break; case GL_RGB8UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_UINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); break; case GL_RGB16UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_UINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); break; case GL_RGB32UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_UINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); break; case GL_RGB8I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_SINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_SINT8); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); break; case GL_RGB16I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_SINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_SINT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); break; case GL_RGB32I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_SINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_SINT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); break; case GL_RGBA8UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); break; case GL_RGBA16UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); break; case GL_RGBA32UI_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); break; case GL_RGBA8I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); break; case GL_RGBA16I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); break; case GL_RGBA32I_EXT: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); break; case GL_R8: case GL_RED: RETURN_IF_SUPPORTED(MESA_FORMAT_R_UNORM8); break; case GL_COMPRESSED_RED: if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) RETURN_IF_SUPPORTED(MESA_FORMAT_R_RGTC1_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R_UNORM8); break; case GL_R16: RETURN_IF_SUPPORTED(MESA_FORMAT_R_UNORM16); break; case GL_RG: case GL_RG8: RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8_UNORM); break; case GL_COMPRESSED_RG: if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) RETURN_IF_SUPPORTED(MESA_FORMAT_RG_RGTC2_UNORM); RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8_UNORM); break; case GL_RG16: RETURN_IF_SUPPORTED(MESA_FORMAT_R16G16_UNORM); break; case GL_R16F: RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_R32F: RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_RG16F: RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_RG32F: RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_R8UI: RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT8); break; case GL_RG8UI: RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT8); break; case GL_R16UI: RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT16); break; case GL_RG16UI: RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT16); break; case GL_R32UI: RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT32); break; case GL_RG32UI: RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT32); break; case GL_R8I: RETURN_IF_SUPPORTED(MESA_FORMAT_R_SINT8); break; case GL_RG8I: RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SINT8); break; case GL_R16I: RETURN_IF_SUPPORTED(MESA_FORMAT_R_SINT16); break; case GL_RG16I: RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SINT16); break; case GL_R32I: RETURN_IF_SUPPORTED(MESA_FORMAT_R_SINT32); break; case GL_RG32I: RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SINT32); break; case GL_RGB10_A2UI: RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UINT); RETURN_IF_SUPPORTED(MESA_FORMAT_R10G10B10A2_UINT); break; case GL_BGRA: RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); break; case GL_STENCIL_INDEX: case GL_STENCIL_INDEX8: RETURN_IF_SUPPORTED(MESA_FORMAT_S_UINT8); break; default: /* For non-generic compressed format we assert two things: * * 1. The format has already been validated against the set of available * extensions. * * 2. The driver only enables the extension if it supports all of the * formats that are part of that extension. */ if (_mesa_is_compressed_format(ctx, internalFormat)) return _mesa_glenum_to_compressed_format(internalFormat); } _mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()", _mesa_enum_to_string(internalFormat)); return MESA_FORMAT_NONE; }
void GLAPIENTRY _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) { GLint buffer[16]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); /* ARB_internalformat_query is also mandatory for ARB_internalformat_query2 */ if (!(_mesa_has_ARB_internalformat_query(ctx) || _mesa_is_gles3(ctx))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ"); return; } assert(ctx->Driver.QueryInternalFormat != NULL); if (!_legal_parameters(ctx, target, internalformat, pname, bufSize, params)) return; /* initialize the contents of the temporary buffer */ memcpy(buffer, params, MIN2(bufSize, 16) * sizeof(GLint)); /* Use the 'unsupported' response defined by the spec for every pname * as the default answer. */ _set_default_response(pname, buffer); if (!_is_target_supported(ctx, target) || !_is_internalformat_supported(ctx, target, internalformat) || !_is_resource_supported(ctx, target, internalformat, pname)) goto end; switch (pname) { case GL_SAMPLES: /* fall-through */ case GL_NUM_SAMPLE_COUNTS: /* The ARB_internalformat_query2 sets the response as 'unsupported' for * SAMPLES and NUM_SAMPLE_COUNTS: * * "If <internalformat> is not color-renderable, depth-renderable, or * stencil-renderable (as defined in section 4.4.4), or if <target> * does not support multiple samples (ie other than * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY, * or RENDERBUFFER)." */ if ((target != GL_RENDERBUFFER && target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) || !_is_renderable(ctx, internalformat)) goto end; /* The GL ES 3.0 specification, section 6.1.15 page 236 says: * * "Since multisampling is not supported for signed and unsigned * integer internal formats, the value of NUM_SAMPLE_COUNTS will be * zero for such formats. * * Since OpenGL ES 3.1 adds support for multisampled integer formats, we * have to check the version for 30 exactly. */ if (pname == GL_NUM_SAMPLE_COUNTS && ctx->API == API_OPENGLES2 && ctx->Version == 30 && _mesa_is_enum_format_integer(internalformat)) { goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_INTERNALFORMAT_SUPPORTED: /* Having a supported <internalformat> is implemented as a prerequisite * for all the <pnames>. Thus, if we reach this point, the internalformat is * supported. */ buffer[0] = GL_TRUE; break; case GL_INTERNALFORMAT_PREFERRED: /* The ARB_internalformat_query2 spec says: * * "- INTERNALFORMAT_PREFERRED: The implementation-preferred internal * format for representing resources of the specified <internalformat> is * returned in <params>. * * Therefore, we let the driver answer. Note that if we reach this * point, it means that the internalformat is supported, so the driver * is called just to try to get a preferred format. If not supported, * GL_NONE was already returned and the driver is not called. */ ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_INTERNALFORMAT_RED_SIZE: case GL_INTERNALFORMAT_GREEN_SIZE: case GL_INTERNALFORMAT_BLUE_SIZE: case GL_INTERNALFORMAT_ALPHA_SIZE: case GL_INTERNALFORMAT_DEPTH_SIZE: case GL_INTERNALFORMAT_STENCIL_SIZE: case GL_INTERNALFORMAT_SHARED_SIZE: case GL_INTERNALFORMAT_RED_TYPE: case GL_INTERNALFORMAT_GREEN_TYPE: case GL_INTERNALFORMAT_BLUE_TYPE: case GL_INTERNALFORMAT_ALPHA_TYPE: case GL_INTERNALFORMAT_DEPTH_TYPE: case GL_INTERNALFORMAT_STENCIL_TYPE: { GLint baseformat; mesa_format texformat; if (target != GL_RENDERBUFFER) { if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true)) goto end; baseformat = _mesa_base_tex_format(ctx, internalformat); } else { baseformat = _mesa_base_fbo_format(ctx, internalformat); } /* Let the driver choose the texture format. * * Disclaimer: I am considering that drivers use for renderbuffers the * same format-choice logic as for textures. */ texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat, GL_NONE /*format */, GL_NONE /* type */); if (texformat == MESA_FORMAT_NONE || baseformat <= 0) goto end; /* Implementation based on what Mesa does for glGetTexLevelParameteriv * and glGetRenderbufferParameteriv functions. */ if (pname == GL_INTERNALFORMAT_SHARED_SIZE) { if (_mesa_has_EXT_texture_shared_exponent(ctx) && target != GL_TEXTURE_BUFFER && target != GL_RENDERBUFFER && texformat == MESA_FORMAT_R9G9B9E5_FLOAT) { buffer[0] = 5; } goto end; } if (!_mesa_base_format_has_channel(baseformat, pname)) goto end; switch (pname) { case GL_INTERNALFORMAT_DEPTH_SIZE: if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_depth_texture(ctx) && target != GL_RENDERBUFFER && target != GL_TEXTURE_BUFFER) goto end; /* fallthrough */ case GL_INTERNALFORMAT_RED_SIZE: case GL_INTERNALFORMAT_GREEN_SIZE: case GL_INTERNALFORMAT_BLUE_SIZE: case GL_INTERNALFORMAT_ALPHA_SIZE: case GL_INTERNALFORMAT_STENCIL_SIZE: buffer[0] = _mesa_get_format_bits(texformat, pname); break; case GL_INTERNALFORMAT_DEPTH_TYPE: if (!_mesa_has_ARB_texture_float(ctx)) goto end; /* fallthrough */ case GL_INTERNALFORMAT_RED_TYPE: case GL_INTERNALFORMAT_GREEN_TYPE: case GL_INTERNALFORMAT_BLUE_TYPE: case GL_INTERNALFORMAT_ALPHA_TYPE: case GL_INTERNALFORMAT_STENCIL_TYPE: buffer[0] = _mesa_get_format_datatype(texformat); break; default: break; } break; } /* For WIDTH/HEIGHT/DEPTH/LAYERS there is no reason to think that the * returned values should be different to the values returned by * GetInteger with MAX_TEXTURE_SIZE, MAX_3D_TEXTURE_SIZE, etc.*/ case GL_MAX_WIDTH: case GL_MAX_HEIGHT: case GL_MAX_DEPTH: { GLenum get_pname; GLint dimensions; GLint min_dimensions; /* From query2:MAX_HEIGHT spec (as example): * * "If the resource does not have at least two dimensions, or if the * resource is unsupported, zero is returned." */ dimensions = _get_target_dimensions(target); min_dimensions = _get_min_dimensions(pname); if (dimensions < min_dimensions) goto end; get_pname = _equivalent_size_pname(target, pname); if (get_pname == 0) goto end; _mesa_GetIntegerv(get_pname, buffer); break; } case GL_MAX_LAYERS: if (!_mesa_has_EXT_texture_array(ctx)) goto end; if (!_mesa_is_array_texture(target)) goto end; _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer); break; case GL_MAX_COMBINED_DIMENSIONS:{ GLint64 combined_value = 1; GLenum max_dimensions_pnames[] = { GL_MAX_WIDTH, GL_MAX_HEIGHT, GL_MAX_DEPTH, GL_SAMPLES }; unsigned i; GLint current_value; /* Combining the dimensions. Note that for array targets, this would * automatically include the value of MAX_LAYERS, as that value is * returned as MAX_HEIGHT or MAX_DEPTH */ for (i = 0; i < 4; i++) { if (max_dimensions_pnames[i] == GL_SAMPLES && !_is_multisample_target(target)) continue; _mesa_GetInternalformativ(target, internalformat, max_dimensions_pnames[i], 1, ¤t_value); if (current_value != 0) combined_value *= current_value; } if (_mesa_is_cube_map_texture(target)) combined_value *= 6; /* We pack the 64-bit value on two 32-bit values. Calling the 32-bit * query, this would work as far as the value can be hold on a 32-bit * signed integer. For the 64-bit query, the wrapper around the 32-bit * query will unpack the value */ memcpy(buffer, &combined_value, sizeof(GLint64)); break; } case GL_COLOR_COMPONENTS: /* The ARB_internalformat_query2 spec says: * * "- COLOR_COMPONENTS: If the internal format contains any color * components (R, G, B, or A), TRUE is returned in <params>. * If the internal format is unsupported or contains no color * components, FALSE is returned." */ if (_mesa_is_color_format(internalformat)) buffer[0] = GL_TRUE; break; case GL_DEPTH_COMPONENTS: /* The ARB_internalformat_query2 spec says: * * "- DEPTH_COMPONENTS: If the internal format contains a depth * component (D), TRUE is returned in <params>. If the internal format * is unsupported or contains no depth component, FALSE is returned." */ if (_mesa_is_depth_format(internalformat) || _mesa_is_depthstencil_format(internalformat)) buffer[0] = GL_TRUE; break; case GL_STENCIL_COMPONENTS: /* The ARB_internalformat_query2 spec says: * * "- STENCIL_COMPONENTS: If the internal format contains a stencil * component (S), TRUE is returned in <params>. If the internal format * is unsupported or contains no stencil component, FALSE is returned. */ if (_mesa_is_stencil_format(internalformat) || _mesa_is_depthstencil_format(internalformat)) buffer[0] = GL_TRUE; break; case GL_COLOR_RENDERABLE: case GL_DEPTH_RENDERABLE: case GL_STENCIL_RENDERABLE: if (!_is_renderable(ctx, internalformat)) goto end; if (pname == GL_COLOR_RENDERABLE) { if (!_mesa_is_color_format(internalformat)) goto end; } else { GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat); if (baseFormat != GL_DEPTH_STENCIL && ((pname == GL_DEPTH_RENDERABLE && baseFormat != GL_DEPTH_COMPONENT) || (pname == GL_STENCIL_RENDERABLE && baseFormat != GL_STENCIL_INDEX))) goto end; } buffer[0] = GL_TRUE; break; case GL_FRAMEBUFFER_RENDERABLE_LAYERED: if (!_mesa_has_EXT_texture_array(ctx) || _legal_target_for_framebuffer_texture_layer(ctx, target)) goto end; /* fallthrough */ case GL_FRAMEBUFFER_RENDERABLE: case GL_FRAMEBUFFER_BLEND: if (!_mesa_has_ARB_framebuffer_object(ctx)) goto end; if (target == GL_TEXTURE_BUFFER || !_is_renderable(ctx, internalformat)) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_READ_PIXELS: case GL_READ_PIXELS_FORMAT: case GL_READ_PIXELS_TYPE: ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_TEXTURE_IMAGE_FORMAT: case GL_GET_TEXTURE_IMAGE_FORMAT: case GL_TEXTURE_IMAGE_TYPE: case GL_GET_TEXTURE_IMAGE_TYPE: ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_MIPMAP: case GL_MANUAL_GENERATE_MIPMAP: case GL_AUTO_GENERATE_MIPMAP: if (!_mesa_is_valid_generate_texture_mipmap_target(ctx, target) || !_mesa_is_valid_generate_texture_mipmap_internalformat(ctx, internalformat)) { goto end; } if (pname == GL_MIPMAP) { buffer[0] = GL_TRUE; goto end; } else if (pname == GL_MANUAL_GENERATE_MIPMAP) { if (!_mesa_has_ARB_framebuffer_object(ctx)) goto end; } else { /* From ARB_internalformat_query2: * "Dependencies on OpenGL 3.2 (Core Profile) * In core profiles for OpenGL 3.2 and later versions, queries * for the AUTO_GENERATE_MIPMAP <pname> return the appropriate * unsupported response." */ if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 32) goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_COLOR_ENCODING: if (!_mesa_is_color_format(internalformat)) goto end; if (_mesa_is_srgb_format(internalformat)) buffer[0] = GL_SRGB; else buffer[0] = GL_LINEAR; break; case GL_SRGB_READ: if (!_mesa_has_EXT_texture_sRGB(ctx) || !_mesa_is_srgb_format(internalformat)) { goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_SRGB_WRITE: if (!_mesa_has_EXT_framebuffer_sRGB(ctx) || !_mesa_is_color_format(internalformat)) { goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_SRGB_DECODE_ARB: /* Presence of EXT_texture_sRGB_decode was already verified */ if (!_mesa_has_EXT_texture_sRGB(ctx) || target == GL_RENDERBUFFER || !_mesa_is_srgb_format(internalformat)) { goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_FILTER: /* If it doesn't allow to set sampler parameters then it would not allow * to set a filter different to GL_NEAREST. In practice, this method * only filters out MULTISAMPLE/MULTISAMPLE_ARRAY */ if (!_mesa_target_allows_setting_sampler_parameters(target)) goto end; if (_mesa_is_enum_format_integer(internalformat)) goto end; if (target == GL_TEXTURE_BUFFER) goto end; /* At this point we know that multi-texel filtering is supported. We * need to call the driver to know if it is CAVEAT_SUPPORT or * FULL_SUPPORT. */ ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_VERTEX_TEXTURE: case GL_TESS_CONTROL_TEXTURE: case GL_TESS_EVALUATION_TEXTURE: case GL_GEOMETRY_TEXTURE: case GL_FRAGMENT_TEXTURE: case GL_COMPUTE_TEXTURE: if (target == GL_RENDERBUFFER) goto end; if ((pname == GL_TESS_CONTROL_TEXTURE || pname == GL_TESS_EVALUATION_TEXTURE) && !_mesa_has_tessellation(ctx)) goto end; if (pname == GL_GEOMETRY_TEXTURE && !_mesa_has_geometry_shaders(ctx)) goto end; if (pname == GL_COMPUTE_TEXTURE && !_mesa_has_compute_shaders(ctx)) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_TEXTURE_GATHER: case GL_TEXTURE_GATHER_SHADOW: if (!_mesa_has_ARB_texture_gather(ctx)) goto end; /* fallthrough */ case GL_TEXTURE_SHADOW: /* Only depth or depth-stencil image formats make sense in shadow samplers */ if (pname != GL_TEXTURE_GATHER && !_mesa_is_depth_format(internalformat) && !_mesa_is_depthstencil_format(internalformat)) goto end; /* Validate the target for shadow and gather operations */ switch (target) { case GL_TEXTURE_2D: case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_RECTANGLE: break; case GL_TEXTURE_1D: case GL_TEXTURE_1D_ARRAY: /* 1D and 1DArray textures are not admitted in gather operations */ if (pname != GL_TEXTURE_SHADOW) goto end; break; default: goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_SHADER_IMAGE_LOAD: case GL_SHADER_IMAGE_STORE: if (!_mesa_has_ARB_shader_image_load_store(ctx)) goto end; /* We call to _mesa_is_shader_image_format_supported * using "internalformat" as parameter, because the * the ARB_internalformat_query2 spec says: * "In this case the <internalformat> is the value of the <format> * parameter that is passed to BindImageTexture." */ if (target == GL_RENDERBUFFER || !_mesa_is_shader_image_format_supported(ctx, internalformat)) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_SHADER_IMAGE_ATOMIC: if (!_mesa_has_ARB_shader_image_load_store(ctx)) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_IMAGE_TEXEL_SIZE: { mesa_format image_format; if (!_mesa_has_ARB_shader_image_load_store(ctx) || target == GL_RENDERBUFFER) goto end; image_format = _mesa_get_shader_image_format(internalformat); if (image_format == MESA_FORMAT_NONE) goto end; /* We return bits */ buffer[0] = (_mesa_get_format_bytes(image_format) * 8); break; } case GL_IMAGE_COMPATIBILITY_CLASS: if (!_mesa_has_ARB_shader_image_load_store(ctx) || target == GL_RENDERBUFFER) goto end; buffer[0] = _mesa_get_image_format_class(internalformat); break; case GL_IMAGE_PIXEL_FORMAT: { GLint base_format; if (!_mesa_has_ARB_shader_image_load_store(ctx) || target == GL_RENDERBUFFER || !_mesa_is_shader_image_format_supported(ctx, internalformat)) goto end; base_format = _mesa_base_tex_format(ctx, internalformat); if (base_format == -1) goto end; if (_mesa_is_enum_format_integer(internalformat)) buffer[0] = _mesa_base_format_to_integer_format(base_format); else buffer[0] = base_format; break; } case GL_IMAGE_PIXEL_TYPE: { mesa_format image_format; GLenum datatype; GLuint comps; if (!_mesa_has_ARB_shader_image_load_store(ctx) || target == GL_RENDERBUFFER) goto end; image_format = _mesa_get_shader_image_format(internalformat); if (image_format == MESA_FORMAT_NONE) goto end; _mesa_uncompressed_format_to_type_and_comps(image_format, &datatype, &comps); if (!datatype) goto end; buffer[0] = datatype; break; } case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: { if (!_mesa_has_ARB_shader_image_load_store(ctx)) goto end; if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true)) goto end; /* From spec: "Equivalent to calling GetTexParameter with <value> set * to IMAGE_FORMAT_COMPATIBILITY_TYPE." * * GetTexParameter just returns * tex_obj->ImageFormatCompatibilityType. We create a fake tex_obj * just with the purpose of getting the value. */ struct gl_texture_object *tex_obj = _mesa_new_texture_object(ctx, 0, target); buffer[0] = tex_obj->ImageFormatCompatibilityType; _mesa_delete_texture_object(ctx, tex_obj); break; } case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: if (target == GL_RENDERBUFFER) goto end; if (!_mesa_is_depthstencil_format(internalformat)) { if (((pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST || pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE) && !_mesa_is_depth_format(internalformat)) || ((pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST || pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE) && !_mesa_is_stencil_format(internalformat))) goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_TEXTURE_COMPRESSED: buffer[0] = _mesa_is_compressed_format(ctx, internalformat); break; case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: { mesa_format mesaformat; GLint block_size; mesaformat = _mesa_glenum_to_compressed_format(internalformat); if (mesaformat == MESA_FORMAT_NONE) goto end; block_size = _mesa_get_format_bytes(mesaformat); assert(block_size > 0); if (pname == GL_TEXTURE_COMPRESSED_BLOCK_SIZE) { buffer[0] = block_size; } else { GLuint bwidth, bheight; /* Returns the width and height in pixels. We return bytes */ _mesa_get_format_block_size(mesaformat, &bwidth, &bheight); assert(bwidth > 0 && bheight > 0); if (pname == GL_TEXTURE_COMPRESSED_BLOCK_WIDTH) buffer[0] = block_size / bheight; else buffer[0] = block_size / bwidth; } break; } case GL_CLEAR_BUFFER: if (target != GL_TEXTURE_BUFFER) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_TEXTURE_VIEW: case GL_VIEW_COMPATIBILITY_CLASS: if (!_mesa_has_ARB_texture_view(ctx) || target == GL_TEXTURE_BUFFER || target == GL_RENDERBUFFER) goto end; if (pname == GL_TEXTURE_VIEW) { ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); } else { GLenum view_class = _mesa_texture_view_lookup_view_class(ctx, internalformat); if (view_class == GL_FALSE) goto end; buffer[0] = view_class; } break; default: unreachable("bad param"); } end: if (bufSize != 0 && params == NULL) { /* Emit a warning to aid application debugging, but go ahead and do the * memcpy (and probably crash) anyway. */ _mesa_warning(ctx, "glGetInternalformativ(bufSize = %d, but params = NULL)", bufSize); } /* Copy the data from the temporary buffer to the buffer supplied by the * application. Clamp the size of the copy to the size supplied by the * application. */ memcpy(params, buffer, MIN2(bufSize, 16) * sizeof(GLint)); return; }
static bool _is_resource_supported(struct gl_context *ctx, GLenum target, GLenum internalformat, GLenum pname) { /* From the ARB_internalformat_query2 spec: * * In the following descriptions, the term /resource/ is used to generically * refer to an object of the appropriate type that has been created with * <internalformat> and <target>. If the particular <target> and * <internalformat> combination do not make sense, ... the "unsupported" * answer should be given. This is not an error. */ /* In the ARB_internalformat_query2 spec wording, some <pnames> do not care * about the /resource/ being supported or not, we return 'true' for those. */ switch (pname) { case GL_INTERNALFORMAT_SUPPORTED: case GL_INTERNALFORMAT_PREFERRED: case GL_COLOR_COMPONENTS: case GL_DEPTH_COMPONENTS: case GL_STENCIL_COMPONENTS: case GL_COLOR_RENDERABLE: case GL_DEPTH_RENDERABLE: case GL_STENCIL_RENDERABLE: return true; default: break; } switch(target){ case GL_TEXTURE_1D: case GL_TEXTURE_1D_ARRAY: case GL_TEXTURE_2D: case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_3D: case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_RECTANGLE: /* Based on what Mesa does for glTexImage1D/2D/3D and * glCompressedTexImage1D/2D/3D functions. */ if (_mesa_base_tex_format(ctx, internalformat) < 0) return false; /* additional checks for depth textures */ if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) return false; /* additional checks for compressed textures */ if (_mesa_is_compressed_format(ctx, internalformat) && (!_mesa_target_can_be_compressed(ctx, target, internalformat, NULL) || _mesa_format_no_online_compression(ctx, internalformat))) return false; break; case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: /* Based on what Mesa does for glTexImage2D/3DMultisample, * glTexStorage2D/3DMultisample and * glTextureStorage2D/3DMultisample functions. */ if (!_mesa_is_renderable_texture_format(ctx, internalformat)) return false; break; case GL_TEXTURE_BUFFER: /* Based on what Mesa does for the glTexBuffer function. */ if (_mesa_validate_texbuffer_format(ctx, internalformat) == MESA_FORMAT_NONE) return false; break; case GL_RENDERBUFFER: /* Based on what Mesa does for glRenderbufferStorage(Multisample) and * glNamedRenderbufferStorage functions. */ if (!_mesa_base_fbo_format(ctx, internalformat)) return false; break; default: unreachable("bad target"); } return true; }
/** * Do error checking for calls to glTexStorage1/2/3D(). * If an error is found, record it with _mesa_error(), unless the target * is a proxy texture. * \return GL_TRUE if any error, GL_FALSE otherwise. */ static GLboolean tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { struct gl_texture_object *texObj; if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexStorage%uD(internalformat = %s)", dims, _mesa_lookup_enum_by_nr(internalformat)); return GL_TRUE; } /* size check */ if (width < 1 || height < 1 || depth < 1) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(width, height or depth < 1)", dims); return GL_TRUE; } /* target check */ if (!legal_texobj_target(ctx, dims, target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexStorage%uD(illegal target=%s)", dims, _mesa_lookup_enum_by_nr(target)); return GL_TRUE; } /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec: * * "The ETC2/EAC texture compression algorithm supports only * two-dimensional images. If internalformat is an ETC2/EAC format, * CompressedTexImage3D will generate an INVALID_OPERATION error if * target is not TEXTURE_2D_ARRAY." * * This should also be applicable for glTexStorage3D(). */ if (_mesa_is_compressed_format(ctx, internalformat) && !_mesa_target_can_be_compressed(ctx, target, internalformat)) { _mesa_error(ctx, _mesa_is_desktop_gl(ctx)? GL_INVALID_ENUM : GL_INVALID_OPERATION, "glTexStorage3D(internalformat = %s)", _mesa_lookup_enum_by_nr(internalformat)); } /* levels check */ if (levels < 1) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)", dims); return GL_TRUE; } /* check levels against maximum (note different error than above) */ if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(levels too large)", dims); return GL_TRUE; } /* check levels against width/height/depth */ if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(too many levels for max texture dimension)", dims); return GL_TRUE; } /* non-default texture object check */ texObj = _mesa_get_current_tex_object(ctx, target); if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(texture object 0)", dims); return GL_TRUE; } /* Check if texObj->Immutable is set */ if (!_mesa_is_proxy_texture(target) && texObj->Immutable) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(immutable)", dims); return GL_TRUE; } /* additional checks for depth textures */ if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat, dims, "glTexStorage")) return GL_TRUE; return GL_FALSE; }