aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main/teximage.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main/teximage.c')
-rw-r--r--mesalib/src/mesa/main/teximage.c1023
1 files changed, 572 insertions, 451 deletions
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 27294ba80..59b38dee4 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -28,7 +28,7 @@
* Texture image-related functions.
*/
-
+#include <stdbool.h>
#include "glheader.h"
#include "bufferobj.h"
#include "context.h"
@@ -42,14 +42,20 @@
#include "mfeatures.h"
#include "state.h"
#include "texcompress.h"
+#include "texcompress_cpal.h"
#include "teximage.h"
#include "texobj.h"
#include "texstate.h"
-#include "texpal.h"
#include "mtypes.h"
#include "glformats.h"
+/* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT.
+ */
+#ifndef GL_HALF_FLOAT_OES
+#define GL_HALF_FLOAT_OES 0x8D61
+#endif
+
/**
* State changes which we care about for glCopyTex[Sub]Image() calls.
* In particular, we care about pixel transfer state and buffer state
@@ -833,8 +839,8 @@ _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
* \return pointer to texture image or NULL if invalid target, invalid
* level, or out of memory.
*/
-struct gl_texture_image *
-_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
+static struct gl_texture_image *
+get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
{
struct gl_texture_image *texImage;
GLuint texIndex;
@@ -1375,6 +1381,16 @@ compressedteximage_only_format(const struct gl_context *ctx, GLenum format)
{
switch (format) {
case GL_ETC1_RGB8_OES:
+ case GL_PALETTE4_RGB8_OES:
+ case GL_PALETTE4_RGBA8_OES:
+ case GL_PALETTE4_R5_G6_B5_OES:
+ case GL_PALETTE4_RGBA4_OES:
+ case GL_PALETTE4_RGB5_A1_OES:
+ case GL_PALETTE8_RGB8_OES:
+ case GL_PALETTE8_RGBA8_OES:
+ case GL_PALETTE8_R5_G6_B5_OES:
+ case GL_PALETTE8_RGBA4_OES:
+ case GL_PALETTE8_RGB5_A1_OES:
return GL_TRUE;
default:
return GL_FALSE;
@@ -1426,16 +1442,19 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
switch (target) {
case GL_TEXTURE_1D:
case GL_PROXY_TEXTURE_1D:
- return GL_TRUE;
+ return _mesa_is_desktop_gl(ctx);
default:
return GL_FALSE;
}
case 2:
switch (target) {
case GL_TEXTURE_2D:
- case GL_PROXY_TEXTURE_2D:
return GL_TRUE;
+ case GL_PROXY_TEXTURE_2D:
+ return _mesa_is_desktop_gl(ctx);
case GL_PROXY_TEXTURE_CUBE_MAP:
+ return _mesa_is_desktop_gl(ctx)
+ && ctx->Extensions.ARB_texture_cube_map;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
@@ -1445,23 +1464,31 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
return ctx->Extensions.ARB_texture_cube_map;
case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
- return ctx->Extensions.NV_texture_rectangle;
+ return _mesa_is_desktop_gl(ctx)
+ && ctx->Extensions.NV_texture_rectangle;
case GL_TEXTURE_1D_ARRAY_EXT:
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return _mesa_is_desktop_gl(ctx)
+ && (ctx->Extensions.MESA_texture_array ||
+ ctx->Extensions.EXT_texture_array);
default:
return GL_FALSE;
}
case 3:
switch (target) {
case GL_TEXTURE_3D:
- case GL_PROXY_TEXTURE_3D:
return GL_TRUE;
+ case GL_PROXY_TEXTURE_3D:
+ return _mesa_is_desktop_gl(ctx);
case GL_TEXTURE_2D_ARRAY_EXT:
+ return (_mesa_is_desktop_gl(ctx)
+ && (ctx->Extensions.MESA_texture_array ||
+ ctx->Extensions.EXT_texture_array))
+ || _mesa_is_gles3(ctx);
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return _mesa_is_desktop_gl(ctx)
+ && (ctx->Extensions.MESA_texture_array ||
+ ctx->Extensions.EXT_texture_array);
default:
return GL_FALSE;
}
@@ -1483,7 +1510,7 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
{
switch (dims) {
case 1:
- return target == GL_TEXTURE_1D;
+ return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D;
case 2:
switch (target) {
case GL_TEXTURE_2D:
@@ -1496,10 +1523,12 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
return ctx->Extensions.ARB_texture_cube_map;
case GL_TEXTURE_RECTANGLE_NV:
- return ctx->Extensions.NV_texture_rectangle;
+ return _mesa_is_desktop_gl(ctx)
+ && ctx->Extensions.NV_texture_rectangle;
case GL_TEXTURE_1D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return _mesa_is_desktop_gl(ctx)
+ && (ctx->Extensions.MESA_texture_array ||
+ ctx->Extensions.EXT_texture_array);
default:
return GL_FALSE;
}
@@ -1508,8 +1537,10 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
case GL_TEXTURE_3D:
return GL_TRUE;
case GL_TEXTURE_2D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return (_mesa_is_desktop_gl(ctx)
+ && (ctx->Extensions.MESA_texture_array ||
+ ctx->Extensions.EXT_texture_array))
+ || _mesa_is_gles3(ctx);
default:
return GL_FALSE;
}
@@ -1537,6 +1568,101 @@ mutable_tex_object(struct gl_context *ctx, GLenum target)
}
+GLenum
+_mesa_es_error_check_format_and_type(GLenum format, GLenum type,
+ unsigned dimensions)
+{
+ bool type_valid = true;
+
+ switch (format) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ type_valid = (type == GL_UNSIGNED_BYTE
+ || type == GL_FLOAT
+ || type == GL_HALF_FLOAT_OES);
+ break;
+
+ case GL_RGB:
+ type_valid = (type == GL_UNSIGNED_BYTE
+ || type == GL_UNSIGNED_SHORT_5_6_5
+ || type == GL_FLOAT
+ || type == GL_HALF_FLOAT_OES);
+ break;
+
+ case GL_RGBA:
+ type_valid = (type == GL_UNSIGNED_BYTE
+ || type == GL_UNSIGNED_SHORT_4_4_4_4
+ || type == GL_UNSIGNED_SHORT_5_5_5_1
+ || type == GL_FLOAT
+ || type == GL_HALF_FLOAT_OES
+ || type == GL_UNSIGNED_INT_2_10_10_10_REV);
+ break;
+
+ case GL_DEPTH_COMPONENT:
+ /* This format is filtered against invalid dimensionalities elsewhere.
+ */
+ type_valid = (type == GL_UNSIGNED_SHORT
+ || type == GL_UNSIGNED_INT);
+ break;
+
+ case GL_DEPTH_STENCIL:
+ /* This format is filtered against invalid dimensionalities elsewhere.
+ */
+ type_valid = (type == GL_UNSIGNED_INT_24_8);
+ break;
+
+ case GL_BGRA_EXT:
+ type_valid = (type == GL_UNSIGNED_BYTE);
+
+ /* This feels like a bug in the EXT_texture_format_BGRA8888 spec, but
+ * the format does not appear to be allowed for 3D textures in OpenGL
+ * ES.
+ */
+ if (dimensions != 2)
+ return GL_INVALID_VALUE;
+
+ break;
+
+ default:
+ return GL_INVALID_VALUE;
+ }
+
+ return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION;
+}
+
+
+
+/**
+ * Return expected size of a compressed texture.
+ */
+static GLuint
+compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
+ GLenum glformat)
+{
+ gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
+ return _mesa_format_image_size(mesaFormat, width, height, depth);
+}
+
+
+/*
+ * Return compressed texture block size, in pixels.
+ */
+static void
+get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
+{
+ gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
+ _mesa_get_format_block_size(mesaFormat, bw, bh);
+}
+
+
+/**
+ * Special value returned by error some texture error checking functions when
+ * an error is detected and the proxy texture image's width/height/depth/format
+ * fields should be zeroed-out.
+ */
+#define PROXY_ERROR 2
+
/**
* Test the glTexImage[123]D() parameters for errors.
@@ -1553,13 +1679,14 @@ mutable_tex_object(struct gl_context *ctx, GLenum target)
* \param depth image depth given by the user.
* \param border image border given by the user.
*
- * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ * \return PROXY_ERROR if there's an error that should zero-out the proxy image,
+ * GL_TRUE if a regular GL error is found, or GL_FALSE if no error,
*
* Verifies each of the parameters against the constants specified in
* __struct gl_contextRec::Const and the supported extensions, and according
* to the OpenGL specification.
*/
-static GLboolean
+static GLenum
texture_error_check( struct gl_context *ctx,
GLuint dimensions, GLenum target,
GLint level, GLint internalFormat,
@@ -1579,34 +1706,62 @@ texture_error_check( struct gl_context *ctx,
*/
const GLboolean indexFormat = (format == GL_COLOR_INDEX);
+ /* Note: for proxy textures, some error conditions immediately generate
+ * a GL error in the usual way. But others do not generate a GL error.
+ * Instead, they cause the width, height, depth, format fields of the
+ * texture image to be zeroed-out. The GL spec seems to indicate that the
+ * zero-out behaviour is only used in cases related to memory allocation.
+ */
+
/* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(level=%d)", dimensions, level);
- }
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
}
/* Check border */
if (border < 0 || border > 1 ||
- ((target == GL_TEXTURE_RECTANGLE_NV ||
+ ((ctx->API != API_OPENGL ||
+ target == GL_TEXTURE_RECTANGLE_NV ||
target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(border=%d)", dimensions, border);
- }
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(border=%d)", dimensions, border);
return GL_TRUE;
}
if (width < 0 || height < 0 || depth < 0) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(width, height or depth < 0)", dimensions);
- }
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(width, height or depth < 0)", dimensions);
return GL_TRUE;
}
+ /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
+ * combinations of format, internalFormat, and type that can be used.
+ * Formats and types that require additional extensions (e.g., GL_FLOAT
+ * requires GL_OES_texture_float) are filtered elsewhere.
+ */
+ if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
+ if (format != internalFormat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%dD(format = %s, internalFormat = %s)",
+ dimensions,
+ _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(internalFormat));
+ return GL_TRUE;
+ }
+
+ err = _mesa_es_error_check_format_and_type(format, type, dimensions);
+ if (err != GL_NO_ERROR) {
+ _mesa_error(ctx, err,
+ "glTexImage%dD(format = %s, type = %s)",
+ dimensions,
+ _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type));
+ return GL_TRUE;
+ }
+ }
+
/* Do this simple check before calling the TestProxyTexImage() function */
if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
sizeOK = (width == height);
@@ -1621,32 +1776,32 @@ texture_error_check( struct gl_context *ctx,
type, width, height,
depth, border);
if (!sizeOK) {
- if (!isProxy) {
+ if (isProxy) {
+ /* No GL error is recorded, but we need to zero-out the image dims */
+ return PROXY_ERROR;
+ }
+ else {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
dimensions, level, width, height, depth);
+ return GL_TRUE;
}
- return GL_TRUE;
}
/* Check internalFormat */
if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(internalFormat=%s)",
- dimensions, _mesa_lookup_enum_by_nr(internalFormat));
- }
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(internalFormat=%s)",
+ dimensions, _mesa_lookup_enum_by_nr(internalFormat));
return GL_TRUE;
}
/* Check incoming image format and type */
err = _mesa_error_check_format_and_type(ctx, format, type);
if (err != GL_NO_ERROR) {
- if (!isProxy) {
- _mesa_error(ctx, err,
- "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
- dimensions, format, type);
- }
+ _mesa_error(ctx, err,
+ "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
+ dimensions, format, type);
return GL_TRUE;
}
@@ -1657,10 +1812,9 @@ texture_error_check( struct gl_context *ctx,
(_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
(_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
(_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
- if (!isProxy)
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
- dimensions, internalFormat, format);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
+ dimensions, internalFormat, format);
return GL_TRUE;
}
@@ -1671,7 +1825,8 @@ texture_error_check( struct gl_context *ctx,
type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
char message[100];
_mesa_snprintf(message, sizeof(message),
- "glTexImage%dD(format/type YCBCR mismatch", dimensions);
+ "glTexImage%dD(format/type YCBCR mismatch)",
+ dimensions);
_mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
return GL_TRUE; /* error */
}
@@ -1679,18 +1834,17 @@ texture_error_check( struct gl_context *ctx,
target != GL_PROXY_TEXTURE_2D &&
target != GL_TEXTURE_RECTANGLE_NV &&
target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
- if (!isProxy)
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexImage%dD(bad target for YCbCr texture)",
+ dimensions);
return GL_TRUE;
}
if (border != 0) {
- if (!isProxy) {
- char message[100];
- _mesa_snprintf(message, sizeof(message),
- "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
- dimensions, border);
- _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
- }
+ char message[100];
+ _mesa_snprintf(message, sizeof(message),
+ "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
+ dimensions, border);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
return GL_TRUE;
}
}
@@ -1711,9 +1865,9 @@ texture_error_check( struct gl_context *ctx,
target != GL_PROXY_TEXTURE_RECTANGLE_ARB &&
!((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) &&
(ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))) {
- if (!isProxy)
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexImage(target/internalFormat)");
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexImage%dD(bad target for depth texture)",
+ dimensions);
return GL_TRUE;
}
}
@@ -1721,21 +1875,18 @@ texture_error_check( struct gl_context *ctx,
/* additional checks for compressed textures */
if (_mesa_is_compressed_format(ctx, internalFormat)) {
if (!target_can_be_compressed(ctx, target, internalFormat)) {
- if (!isProxy)
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexImage%dD(target)", dimensions);
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexImage%dD(target can't be compressed)", dimensions);
return GL_TRUE;
}
if (compressedteximage_only_format(ctx, internalFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%dD(no compression for format)", dimensions);
+ "glTexImage%dD(no compression for format)", dimensions);
return GL_TRUE;
}
if (border != 0) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%dD(border!=0)", dimensions);
- }
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%dD(border!=0)", dimensions);
return GL_TRUE;
}
}
@@ -1744,11 +1895,9 @@ texture_error_check( struct gl_context *ctx,
if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) &&
(_mesa_is_enum_format_integer(format) !=
_mesa_is_enum_format_integer(internalFormat))) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%dD(integer/non-integer format mismatch)",
- dimensions);
- }
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%dD(integer/non-integer format mismatch)",
+ dimensions);
return GL_TRUE;
}
@@ -1764,6 +1913,187 @@ texture_error_check( struct gl_context *ctx,
/**
+ * Error checking for glCompressedTexImage[123]D().
+ * \param reason returns reason for error, if any
+ * \return error code or GL_NO_ERROR or PROXY_ERROR.
+ */
+static GLenum
+compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
+ GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize)
+{
+ const GLenum proxyTarget = get_proxy_target(target);
+ const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
+ GLint expectedSize;
+ GLenum choose_format;
+ GLenum choose_type;
+ GLenum proxy_format;
+ GLenum error = GL_NO_ERROR;
+ char *reason = ""; /* no error */
+
+ if (!target_can_be_compressed(ctx, target, internalFormat)) {
+ reason = "target";
+ error = GL_INVALID_ENUM;
+ goto error;
+ }
+
+ /* This will detect any invalid internalFormat value */
+ if (!_mesa_is_compressed_format(ctx, internalFormat)) {
+ reason = "internalFormat";
+ error = GL_INVALID_ENUM;
+ goto error;
+ }
+
+ switch (internalFormat) {
+#if FEATURE_ES
+ case GL_PALETTE4_RGB8_OES:
+ case GL_PALETTE4_RGBA8_OES:
+ case GL_PALETTE4_R5_G6_B5_OES:
+ case GL_PALETTE4_RGBA4_OES:
+ case GL_PALETTE4_RGB5_A1_OES:
+ case GL_PALETTE8_RGB8_OES:
+ case GL_PALETTE8_RGBA8_OES:
+ case GL_PALETTE8_R5_G6_B5_OES:
+ case GL_PALETTE8_RGBA4_OES:
+ case GL_PALETTE8_RGB5_A1_OES:
+ _mesa_cpal_compressed_format_type(internalFormat, &choose_format,
+ &choose_type);
+ proxy_format = choose_format;
+
+ /* check level (note that level should be zero or less!) */
+ if (level > 0 || level < -maxLevels) {
+ reason = "level";
+ error = GL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (dimensions != 2) {
+ reason = "compressed paletted textures must be 2D";
+ error = GL_INVALID_OPERATION;
+ goto error;
+ }
+
+ /* Figure out the expected texture size (in bytes). This will be
+ * checked against the actual size later.
+ */
+ expectedSize = _mesa_cpal_compressed_size(level, internalFormat,
+ width, height);
+
+ /* This is for the benefit of the TestProxyTexImage below. It expects
+ * level to be non-negative. OES_compressed_paletted_texture uses a
+ * weird mechanism where the level specified to glCompressedTexImage2D
+ * is -(n-1) number of levels in the texture, and the data specifies the
+ * complete mipmap stack. This is done to ensure the palette is the
+ * same for all levels.
+ */
+ level = -level;
+ break;
+#endif
+
+ default:
+ choose_format = GL_NONE;
+ choose_type = GL_NONE;
+ proxy_format = internalFormat;
+
+ /* check level */
+ if (level < 0 || level >= maxLevels) {
+ reason = "level";
+ error = GL_INVALID_VALUE;
+ goto error;
+ }
+
+ /* Figure out the expected texture size (in bytes). This will be
+ * checked against the actual size later.
+ */
+ expectedSize = compressed_tex_size(width, height, depth, internalFormat);
+ break;
+ }
+
+ /* This should really never fail */
+ if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
+ reason = "internalFormat";
+ error = GL_INVALID_ENUM;
+ goto error;
+ }
+
+ /* No compressed formats support borders at this time */
+ if (border != 0) {
+ reason = "border != 0";
+ error = GL_INVALID_VALUE;
+ goto error;
+ }
+
+ /* For cube map, width must equal height */
+ if (_mesa_is_cube_face(target) && width != height) {
+ reason = "width != height";
+ error = GL_INVALID_VALUE;
+ goto error;
+ }
+
+ /* check image size against compression block size */
+ {
+ gl_format texFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, target, proxy_format,
+ choose_format, choose_type);
+ GLuint bw, bh;
+
+ _mesa_get_format_block_size(texFormat, &bw, &bh);
+ if ((width > bw && width % bw > 0) ||
+ (height > bh && height % bh > 0)) {
+ /*
+ * Per GL_ARB_texture_compression: GL_INVALID_OPERATION is
+ * generated [...] if any parameter combinations are not
+ * supported by the specific compressed internal format.
+ */
+ reason = "invalid width or height for compression format";
+ error = GL_INVALID_OPERATION;
+ goto error;
+ }
+ }
+
+ /* check image sizes */
+ if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
+ proxy_format, choose_format,
+ choose_type,
+ width, height, depth, border)) {
+ /* See error comment above */
+ if (target == proxyTarget) {
+ return PROXY_ERROR;
+ }
+ reason = "invalid width, height or format";
+ error = GL_INVALID_OPERATION;
+ goto error;
+ }
+
+ /* check image size in bytes */
+ if (expectedSize != imageSize) {
+ /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...]
+ * if <imageSize> is not consistent with the format, dimensions, and
+ * contents of the specified image.
+ */
+ reason = "imageSize inconsistant with width/height/format";
+ error = GL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (!mutable_tex_object(ctx, target)) {
+ reason = "immutable texture";
+ error = GL_INVALID_OPERATION;
+ goto error;
+ }
+
+ return GL_NO_ERROR;
+
+error:
+ _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason);
+ return error;
+}
+
+
+
+/**
* Test glTexSubImage[123]D() parameters for errors.
*
* \param ctx GL context.
@@ -1817,6 +2147,23 @@ subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
return GL_TRUE;
}
+ /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
+ * combinations of format and type that can be used. Formats and types
+ * that require additional extensions (e.g., GL_FLOAT requires
+ * GL_OES_texture_float) are filtered elsewhere.
+ */
+ if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
+ err = _mesa_es_error_check_format_and_type(format, type, dimensions);
+ if (err != GL_NO_ERROR) {
+ _mesa_error(ctx, err,
+ "glTexSubImage%dD(format = %s, type = %s)",
+ dimensions,
+ _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type));
+ return GL_TRUE;
+ }
+ }
+
err = _mesa_error_check_format_and_type(ctx, format, type);
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err,
@@ -1992,11 +2339,32 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
/* Check border */
if (border < 0 || border > 1 ||
- ((target == GL_TEXTURE_RECTANGLE_NV ||
+ ((ctx->API != API_OPENGL ||
+ target == GL_TEXTURE_RECTANGLE_NV ||
target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(border=%d)", dimensions, border);
return GL_TRUE;
}
+ /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
+ * internalFormat.
+ */
+ if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
+ switch (internalFormat) {
+ case GL_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(internalFormat)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
baseFormat = _mesa_base_tex_format(ctx, internalFormat);
if (baseFormat < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -2429,7 +2797,8 @@ _mesa_choose_texture_format(struct gl_context *ctx,
}
/* choose format from scratch */
- f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+ f = ctx->Driver.ChooseTextureFormat(ctx, texObj->Target, internalFormat,
+ format, type);
ASSERT(f != MESA_FORMAT_NONE);
return f;
}
@@ -2477,71 +2846,125 @@ strip_texture_border(GLenum target,
}
}
+
/**
- * Common code to implement all the glTexImage1D/2D/3D functions.
+ * Common code to implement all the glTexImage1D/2D/3D functions
+ * as well as glCompressedTexImage1D/2D/3D.
+ * \param compressed only GL_TRUE for glCompressedTexImage1D/2D/3D calls.
+ * \param format the user's image format (only used if !compressed)
+ * \param type the user's image type (only used if !compressed)
+ * \param imageSize only used for glCompressedTexImage1D/2D/3D calls.
*/
static void
-teximage(struct gl_context *ctx, GLuint dims,
+teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
- const GLvoid *pixels)
+ GLsizei imageSize, const GLvoid *pixels)
{
- GLboolean error;
+ const char *func = compressed ? "glCompressedTexImage" : "glTexImage";
+ GLenum error;
struct gl_pixelstore_attrib unpack_no_border;
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
- dims,
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat),
- width, height, depth, border,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type), pixels);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) {
+ if (compressed)
+ _mesa_debug(ctx,
+ "glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n",
+ dims,
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height, depth, border, pixels);
+ else
+ _mesa_debug(ctx,
+ "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
+ dims,
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height, depth, border,
+ _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type), pixels);
+ }
internalFormat = override_internal_format(internalFormat, width, height);
/* target error checking */
if (!legal_teximage_target(ctx, dims, target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
- dims, _mesa_lookup_enum_by_nr(target));
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
+ func, dims, _mesa_lookup_enum_by_nr(target));
return;
}
/* general error checking */
- error = texture_error_check(ctx, dims, target, level, internalFormat,
- format, type, width, height, depth, border);
+ if (compressed) {
+ error = compressed_texture_error_check(ctx, dims, target, level,
+ internalFormat,
+ width, height, depth,
+ border, imageSize);
+ }
+ else {
+ error = texture_error_check(ctx, dims, target, level, internalFormat,
+ format, type, width, height, depth, border);
+ }
+
+#if FEATURE_ES
+ /* Here we convert a cpal compressed image into a regular glTexImage2D
+ * call by decompressing the texture. If we really want to support cpal
+ * textures in any driver this would have to be changed.
+ */
+ if (compressed && !error && dims == 2) {
+ switch (internalFormat) {
+ case GL_PALETTE4_RGB8_OES:
+ case GL_PALETTE4_RGBA8_OES:
+ case GL_PALETTE4_R5_G6_B5_OES:
+ case GL_PALETTE4_RGBA4_OES:
+ case GL_PALETTE4_RGB5_A1_OES:
+ case GL_PALETTE8_RGB8_OES:
+ case GL_PALETTE8_RGBA8_OES:
+ case GL_PALETTE8_R5_G6_B5_OES:
+ case GL_PALETTE8_RGBA4_OES:
+ case GL_PALETTE8_RGB5_A1_OES:
+ _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
+ width, height, imageSize, pixels);
+ return;
+ }
+ }
+#endif
if (_mesa_is_proxy_texture(target)) {
/* Proxy texture: just clear or set state depending on error checking */
struct gl_texture_image *texImage =
- _mesa_get_proxy_tex_image(ctx, target, level);
+ get_proxy_tex_image(ctx, target, level);
+ gl_format texFormat = MESA_FORMAT_NONE;
- if (error) {
- /* when error, clear all proxy texture image parameters */
- if (texImage)
- clear_teximage_fields(texImage);
- }
- else {
- /* no error, set the tex image parameters */
+ if (!error) {
+ /* No parameter errors. Choose a texture format and see if we
+ * can really allocate the texture.
+ */
struct gl_texture_object *texObj =
_mesa_get_current_tex_object(ctx, target);
- gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
- target, level,
- internalFormat,
- format, type);
-
- if (legal_texture_size(ctx, texFormat, width, height, depth)) {
- _mesa_init_teximage_fields(ctx, texImage, width, height,
- depth, border, internalFormat,
- texFormat);
+ texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
+ internalFormat, format, type);
+ if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
+ error = PROXY_ERROR;
}
- else if (texImage) {
+ }
+
+ if (error == PROXY_ERROR) {
+ /* image too large, etc. Clear all proxy texture image parameters. */
+ if (texImage)
clear_teximage_fields(texImage);
- }
+ }
+ else if (error == GL_FALSE) {
+ /* no error: store the teximage parameters */
+ if (texImage)
+ _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
+ border, internalFormat, texFormat);
+ }
+ else {
+ /* other, regular error (was already recorded) */
}
}
else {
@@ -2575,7 +2998,7 @@ teximage(struct gl_context *ctx, GLuint dims,
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
}
else {
gl_format texFormat;
@@ -2592,8 +3015,14 @@ teximage(struct gl_context *ctx, GLuint dims,
border, internalFormat, texFormat);
/* Give the texture to the driver. <pixels> may be null. */
- ctx->Driver.TexImage(ctx, dims, texImage, format,
- type, pixels, unpack);
+ if (compressed) {
+ ctx->Driver.CompressedTexImage(ctx, dims, texImage,
+ imageSize, pixels);
+ }
+ else {
+ ctx->Driver.TexImage(ctx, dims, texImage, format,
+ type, pixels, unpack);
+ }
check_gen_mipmap(ctx, target, texObj, level);
@@ -2602,7 +3031,7 @@ teximage(struct gl_context *ctx, GLuint dims,
_mesa_dirty_texobj(ctx, texObj, GL_TRUE);
}
else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
}
}
}
@@ -2620,8 +3049,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
GLenum type, const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
- border, format, type, pixels);
+ teximage(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1,
+ border, format, type, 0, pixels);
}
@@ -2632,8 +3061,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, 2, target, level, internalFormat, width, height, 1,
- border, format, type, pixels);
+ teximage(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1,
+ border, format, type, 0, pixels);
}
@@ -2648,8 +3077,9 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, 3, target, level, internalFormat, width, height, depth,
- border, format, type, pixels);
+ teximage(ctx, GL_FALSE, 3, target, level, internalFormat,
+ width, height, depth,
+ border, format, type, 0, pixels);
}
@@ -2670,13 +3100,23 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ bool valid_target;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if ((target == GL_TEXTURE_2D &&
- !ctx->Extensions.OES_EGL_image) ||
- (target == GL_TEXTURE_EXTERNAL_OES &&
- !ctx->Extensions.OES_EGL_image_external)) {
+ switch (target) {
+ case GL_TEXTURE_2D:
+ valid_target = ctx->Extensions.OES_EGL_image;
+ break;
+ case GL_TEXTURE_EXTERNAL_OES:
+ valid_target = ctx->Extensions.OES_EGL_image_external;
+ break;
+ default:
+ valid_target = false;
+ break;
+ }
+
+ if (!valid_target) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glEGLImageTargetTexture2D(target=%d)", target);
return;
@@ -3084,190 +3524,6 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
/**
- * Return expected size of a compressed texture.
- */
-static GLuint
-compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
- GLenum glformat)
-{
- gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
- return _mesa_format_image_size(mesaFormat, width, height, depth);
-}
-
-
-/*
- * Return compressed texture block size, in pixels.
- */
-static void
-get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
-{
- gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
- _mesa_get_format_block_size(mesaFormat, bw, bh);
-}
-
-
-/**
- * Error checking for glCompressedTexImage[123]D().
- * \param reason returns reason for error, if any
- * \return error code or GL_NO_ERROR.
- */
-static GLenum
-compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
- GLenum target, GLint level,
- GLenum internalFormat, GLsizei width,
- GLsizei height, GLsizei depth, GLint border,
- GLsizei imageSize, char **reason)
-{
- const GLenum proxyTarget = get_proxy_target(target);
- const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
- GLint expectedSize;
- GLenum choose_format;
- GLenum choose_type;
- GLenum proxy_format;
-
- *reason = ""; /* no error */
-
- if (!target_can_be_compressed(ctx, target, internalFormat)) {
- *reason = "target";
- return GL_INVALID_ENUM;
- }
-
- /* This will detect any invalid internalFormat value */
- if (!_mesa_is_compressed_format(ctx, internalFormat)) {
- *reason = "internalFormat";
- return GL_INVALID_ENUM;
- }
-
- switch (internalFormat) {
-#if FEATURE_ES
- case GL_PALETTE4_RGB8_OES:
- case GL_PALETTE4_RGBA8_OES:
- case GL_PALETTE4_R5_G6_B5_OES:
- case GL_PALETTE4_RGBA4_OES:
- case GL_PALETTE4_RGB5_A1_OES:
- case GL_PALETTE8_RGB8_OES:
- case GL_PALETTE8_RGBA8_OES:
- case GL_PALETTE8_R5_G6_B5_OES:
- case GL_PALETTE8_RGBA4_OES:
- case GL_PALETTE8_RGB5_A1_OES:
- _mesa_cpal_compressed_format_type(internalFormat, &choose_format,
- &choose_type);
- proxy_format = choose_format;
-
- /* check level */
- if (level > 0 || level < -maxLevels) {
- *reason = "level";
- return GL_INVALID_VALUE;
- }
-
- if (dimensions != 2) {
- *reason = "compressed paletted textures must be 2D";
- return GL_INVALID_OPERATION;
- }
-
- /* Figure out the expected texture size (in bytes). This will be
- * checked against the actual size later.
- */
- expectedSize = _mesa_cpal_compressed_size(level, internalFormat,
- width, height);
-
- /* This is for the benefit of the TestProxyTexImage below. It expects
- * level to be non-negative. OES_compressed_paletted_texture uses a
- * weird mechanism where the level specified to glCompressedTexImage2D
- * is -(n-1) number of levels in the texture, and the data specifies the
- * complete mipmap stack. This is done to ensure the palette is the
- * same for all levels.
- */
- level = -level;
- break;
-#endif
-
- default:
- choose_format = GL_NONE;
- choose_type = GL_NONE;
- proxy_format = internalFormat;
-
- /* check level */
- if (level < 0 || level >= maxLevels) {
- *reason = "level";
- return GL_INVALID_VALUE;
- }
-
- /* Figure out the expected texture size (in bytes). This will be
- * checked against the actual size later.
- */
- expectedSize = compressed_tex_size(width, height, depth, internalFormat);
- break;
- }
-
- /* This should really never fail */
- if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
- *reason = "internalFormat";
- return GL_INVALID_ENUM;
- }
-
- /* No compressed formats support borders at this time */
- if (border != 0) {
- *reason = "border != 0";
- return GL_INVALID_VALUE;
- }
-
- /* For cube map, width must equal height */
- if (_mesa_is_cube_face(target) && width != height) {
- *reason = "width != height";
- return GL_INVALID_VALUE;
- }
-
- /* check image size against compression block size */
- {
- gl_format texFormat =
- ctx->Driver.ChooseTextureFormat(ctx, proxy_format,
- choose_format, choose_type);
- GLuint bw, bh;
-
- _mesa_get_format_block_size(texFormat, &bw, &bh);
- if ((width > bw && width % bw > 0) ||
- (height > bh && height % bh > 0)) {
- /*
- * Per GL_ARB_texture_compression: GL_INVALID_OPERATION is
- * generated [...] if any parameter combinations are not
- * supported by the specific compressed internal format.
- */
- *reason = "invalid width or height for compression format";
- return GL_INVALID_OPERATION;
- }
- }
-
- /* check image sizes */
- if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
- proxy_format, choose_format,
- choose_type,
- width, height, depth, border)) {
- /* See error comment above */
- *reason = "invalid width, height or format";
- return GL_INVALID_OPERATION;
- }
-
- /* check image size in bytes */
- if (expectedSize != imageSize) {
- /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...]
- * if <imageSize> is not consistent with the format, dimensions, and
- * contents of the specified image.
- */
- *reason = "imageSize inconsistant with width/height/format";
- return GL_INVALID_VALUE;
- }
-
- if (!mutable_tex_object(ctx, target)) {
- *reason = "immutable texture";
- return GL_INVALID_OPERATION;
- }
-
- return GL_NO_ERROR;
-}
-
-
-/**
* Error checking for glCompressedTexSubImage[123]D().
* \warning There are some bad assumptions here about the size of compressed
* texture tiles (multiple of 4) used to test the validity of the
@@ -3409,141 +3665,6 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
}
-/**
- * Implementation of the glCompressedTexImage1/2/3D() functions.
- */
-static void
-compressedteximage(struct gl_context *ctx, GLuint dims,
- GLenum target, GLint level,
- GLenum internalFormat, GLsizei width,
- GLsizei height, GLsizei depth, GLint border,
- GLsizei imageSize, const GLvoid *data)
-{
- GLenum error;
- char *reason = "";
-
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx,
- "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n",
- dims,
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat),
- width, height, depth, border, imageSize, data);
-
- /* check target */
- if (!legal_teximage_target(ctx, dims, target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)",
- dims, _mesa_lookup_enum_by_nr(target));
- return;
- }
-
- error = compressed_texture_error_check(ctx, dims, target, level,
- internalFormat, width, height, depth,
- border, imageSize, &reason);
-
-#if FEATURE_ES
- /* XXX this is kind of a hack */
- if (!error && dims == 2) {
- switch (internalFormat) {
- case GL_PALETTE4_RGB8_OES:
- case GL_PALETTE4_RGBA8_OES:
- case GL_PALETTE4_R5_G6_B5_OES:
- case GL_PALETTE4_RGBA4_OES:
- case GL_PALETTE4_RGB5_A1_OES:
- case GL_PALETTE8_RGB8_OES:
- case GL_PALETTE8_RGBA8_OES:
- case GL_PALETTE8_R5_G6_B5_OES:
- case GL_PALETTE8_RGBA4_OES:
- case GL_PALETTE8_RGB5_A1_OES:
- _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
- width, height, imageSize, data);
- return;
- }
- }
-#endif
-
- if (_mesa_is_proxy_texture(target)) {
- /* Proxy texture: just check for errors and update proxy state */
- struct gl_texture_image *texImage;
-
- if (!error) {
- struct gl_texture_object *texObj =
- _mesa_get_current_tex_object(ctx, target);
- gl_format texFormat =
- _mesa_choose_texture_format(ctx, texObj, target, level,
- internalFormat, GL_NONE, GL_NONE);
- if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
- error = GL_OUT_OF_MEMORY;
- }
- }
-
- texImage = _mesa_get_proxy_tex_image(ctx, target, level);
- if (texImage) {
- if (error) {
- /* if error, clear all proxy texture image parameters */
- clear_teximage_fields(texImage);
- }
- else {
- /* no error: store the teximage parameters */
- _mesa_init_teximage_fields(ctx, texImage, width, height,
- depth, border, internalFormat,
- MESA_FORMAT_NONE);
- }
- }
- }
- else {
- /* non-proxy target */
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- if (error) {
- _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason);
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_get_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY,
- "glCompressedTexImage%uD", dims);
- }
- else {
- gl_format texFormat;
-
- ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
-
- texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
- internalFormat, GL_NONE,
- GL_NONE);
-
- if (legal_texture_size(ctx, texFormat, width, height, depth)) {
- _mesa_init_teximage_fields(ctx, texImage,
- width, height, depth,
- border, internalFormat, texFormat);
-
- ctx->Driver.CompressedTexImage(ctx, dims, texImage, imageSize,
- data);
-
- check_gen_mipmap(ctx, target, texObj, level);
-
- _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
- }
- else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY,
- "glCompressedTexImage%uD", dims);
- }
- }
- }
- _mesa_unlock_texture(ctx, texObj);
- }
-}
-
-
void GLAPIENTRY
_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
GLenum internalFormat, GLsizei width,
@@ -3551,8 +3672,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
const GLvoid *data)
{
GET_CURRENT_CONTEXT(ctx);
- compressedteximage(ctx, 1, target, level, internalFormat,
- width, 1, 1, border, imageSize, data);
+ teximage(ctx, GL_TRUE, 1, target, level, internalFormat,
+ width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data);
}
@@ -3563,8 +3684,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
const GLvoid *data)
{
GET_CURRENT_CONTEXT(ctx);
- compressedteximage(ctx, 2, target, level, internalFormat,
- width, height, 1, border, imageSize, data);
+ teximage(ctx, GL_TRUE, 2, target, level, internalFormat,
+ width, height, 1, border, GL_NONE, GL_NONE, imageSize, data);
}
@@ -3575,8 +3696,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
GLsizei imageSize, const GLvoid *data)
{
GET_CURRENT_CONTEXT(ctx);
- compressedteximage(ctx, 3, target, level, internalFormat,
- width, height, depth, border, imageSize, data);
+ teximage(ctx, GL_TRUE, 3, target, level, internalFormat,
+ width, height, depth, border, GL_NONE, GL_NONE, imageSize, data);
}