* should do the job.
*/
+ GLboolean (*CompressedTexSubImage1D)( GLcontext *ctx, GLenum target,
+ GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+ GLboolean (*CompressedTexSubImage2D)( GLcontext *ctx, GLenum target,
+ GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width,
+ GLint height, GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+ GLboolean (*CompressedTexSubImage3D)( GLcontext *ctx, GLenum target,
+ GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset,
+ GLsizei width, GLint height,
+ GLint depth, GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+ /* Called by glCompressedTexSubImage1/2/3D.
+ * Arguments:
+ * <target>, <level>, <x/z/zoffset>, <width>, <height>, <depth>,
+ * <imageSize>, and <data> are user specified.
+ * <texObj> is the target texture object.
+ * <texImage> is the target texture image. It will have the texture
+ * width, height, depth, border and internalFormat information.
+ * Return GL_TRUE if operation completed, return GL_FALSE if core Mesa
+ * should do the job.
+ */
+
+ void (*GetCompressedTexImage)( GLcontext *ctx, GLenum target,
+ GLint lod, void *image,
+ const struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+ /* Called by glGetCompressedTexImageARB.
+ * <target>, <lod>, <image> are specified by user.
+ * <texObj> is the source texture object.
+ * <texImage> is the source texture image.
+ */
void (*TexEnv)( GLcontext *ctx, GLenum target, GLenum pname,
const GLfloat *param );
-/* $Id: dlist.c,v 1.41 2000/05/24 15:04:45 brianp Exp $ */
+/* $Id: dlist.c,v 1.42 2000/06/06 17:03:38 brianp Exp $ */
/*
* Mesa 3-D graphics library
/* GL_SGIX/SGIS_pixel_texture */
OPCODE_PIXEL_TEXGEN_SGIX,
OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS,
+ /* GL_ARB_texture_compression */
+ OPCODE_COMPRESSED_TEX_IMAGE_1D,
+ OPCODE_COMPRESSED_TEX_IMAGE_2D,
+ OPCODE_COMPRESSED_TEX_IMAGE_3D,
+ OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D,
+ OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D,
+ OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D,
/* The following three are meta instructions */
OPCODE_ERROR, /* raise compiled-in error */
OPCODE_VERTEX_CASSETTE, /* render prebuilt vertex buffer */
FREE(n[11].data);
n += InstSize[n[0].opcode];
break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_1D:
+ FREE(n[7].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_2D:
+ FREE(n[8].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_3D:
+ FREE(n[9].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:
+ FREE(n[7].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:
+ FREE(n[9].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:
+ FREE(n[11].data);
+ n += InstSize[n[0].opcode];
+ break;
case OPCODE_CONTINUE:
n = (Node *) n[1].next;
FREE( block );
InstSize[OPCODE_END_OF_LIST] = 1;
/* GL_SGIX/SGIS_pixel_texture */
InstSize[OPCODE_PIXEL_TEXGEN_SGIX] = 2;
- InstSize[OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS] = 3,
+ InstSize[OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS] = 3;
+ /* GL_ARB_texture_compression */
+ InstSize[OPCODE_COMPRESSED_TEX_IMAGE_1D] = 8;
+ InstSize[OPCODE_COMPRESSED_TEX_IMAGE_2D] = 9;
+ InstSize[OPCODE_COMPRESSED_TEX_IMAGE_3D] = 10;
+ InstSize[OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D] = 8;
+ InstSize[OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D] = 10;
+ InstSize[OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D] = 12;
/* GL_ARB_multitexture */
InstSize[OPCODE_ACTIVE_TEXTURE] = 2;
InstSize[OPCODE_CLIENT_ACTIVE_TEXTURE] = 2;
/* GL_ARB_texture_compression */
static void
save_CompressedTexImage1DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
+ GLenum internalFormat, GLsizei width,
GLint border, GLsizei imageSize,
const GLvoid *data)
{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_1D) {
+ /* don't compile, execute immediately */
+ (*ctx->Exec->CompressedTexImage1DARB)(target, level, internalFormat,
+ width, border, imageSize, data);
+ }
+ else {
+ Node *n;
+ GLvoid *image;
+ FLUSH_VB(ctx, "dlist");
+ /* make copy of image */
+ image = MALLOC(imageSize);
+ if (!image) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 8 );
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].e = internalFormat;
+ n[4].i = (GLint) width;
+ n[5].i = border;
+ n[6].i = imageSize;
+ n[7].data = image;
+ }
+ else if (image) {
+ FREE(image);
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->CompressedTexImage1DARB)(target, level, internalFormat,
+ width, border, imageSize, data);
+ }
+ }
}
static void
save_CompressedTexImage2DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
+ GLenum internalFormat, GLsizei width,
GLsizei height, GLint border, GLsizei imageSize,
const GLvoid *data)
{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_2D) {
+ /* don't compile, execute immediately */
+ (*ctx->Exec->CompressedTexImage2DARB)(target, level, internalFormat,
+ width, height, border, imageSize, data);
+ }
+ else {
+ Node *n;
+ GLvoid *image;
+ FLUSH_VB(ctx, "dlist");
+ /* make copy of image */
+ image = MALLOC(imageSize);
+ if (!image) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 9 );
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].e = internalFormat;
+ n[4].i = (GLint) width;
+ n[5].i = (GLint) height;
+ n[6].i = border;
+ n[7].i = imageSize;
+ n[8].data = image;
+ }
+ else if (image) {
+ FREE(image);
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->CompressedTexImage2DARB)(target, level, internalFormat,
+ width, height, border, imageSize, data);
+ }
+ }
}
static void
save_CompressedTexImage3DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
+ GLenum internalFormat, GLsizei width,
GLsizei height, GLsizei depth, GLint border,
GLsizei imageSize, const GLvoid *data)
{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_3D) {
+ /* don't compile, execute immediately */
+ (*ctx->Exec->CompressedTexImage3DARB)(target, level, internalFormat,
+ width, height, depth, border, imageSize, data);
+ }
+ else {
+ Node *n;
+ GLvoid *image;
+ FLUSH_VB(ctx, "dlist");
+ /* make copy of image */
+ image = MALLOC(imageSize);
+ if (!image) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 10 );
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].e = internalFormat;
+ n[4].i = (GLint) width;
+ n[5].i = (GLint) height;
+ n[6].i = (GLint) depth;
+ n[7].i = border;
+ n[8].i = imageSize;
+ n[9].data = image;
+ }
+ else if (image) {
+ FREE(image);
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->CompressedTexImage3DARB)(target, level, internalFormat,
+ width, height, depth, border, imageSize, data);
+ }
+ }
}
GLsizei width, GLenum format,
GLsizei imageSize, const GLvoid *data)
{
+ Node *n;
+ GLvoid *image;
+
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VB(ctx, "dlist");
+
+ /* make copy of image */
+ image = MALLOC(imageSize);
+ if (!image) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage1DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 8 );
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = (GLint) width;
+ n[5].e = format;
+ n[6].i = imageSize;
+ n[7].data = image;
+ }
+ else if (image) {
+ FREE(image);
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->CompressedTexSubImage1DARB)(target, level, xoffset,
+ width, format, imageSize, data);
+ }
}
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
+ Node *n;
+ GLvoid *image;
+
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VB(ctx, "dlist");
+
+ /* make copy of image */
+ image = MALLOC(imageSize);
+ if (!image) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 10 );
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = yoffset;
+ n[5].i = (GLint) width;
+ n[6].i = (GLint) height;
+ n[7].e = format;
+ n[8].i = imageSize;
+ n[9].data = image;
+ }
+ else if (image) {
+ FREE(image);
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->CompressedTexSubImage2DARB)(target, level, xoffset, yoffset,
+ width, height, format, imageSize, data);
+ }
}
GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid *data)
{
+ Node *n;
+ GLvoid *image;
+
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VB(ctx, "dlist");
+
+ /* make copy of image */
+ image = MALLOC(imageSize);
+ if (!image) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage3DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 12 );
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = yoffset;
+ n[5].i = zoffset;
+ n[6].i = (GLint) width;
+ n[7].i = (GLint) height;
+ n[8].i = (GLint) depth;
+ n[9].e = format;
+ n[10].i = imageSize;
+ n[11].data = image;
+ }
+ else if (image) {
+ FREE(image);
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->CompressedTexSubImage3DARB)(target, level, xoffset, yoffset,
+ zoffset, width, height, depth, format, imageSize, data);
+ }
}
case OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS: /* GL_SGIS_pixel_texture */
(*ctx->Exec->PixelTexGenParameteriSGIS)( n[1].e, n[2].i );
break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_1D: /* GL_ARB_texture_compression */
+ (*ctx->Exec->CompressedTexImage1DARB)(n[1].e, n[2].i, n[3].e,
+ n[4].i, n[5].i, n[6].i, n[7].data);
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_2D: /* GL_ARB_texture_compression */
+ (*ctx->Exec->CompressedTexImage2DARB)(n[1].e, n[2].i, n[3].e,
+ n[4].i, n[5].i, n[6].i, n[7].i, n[8].data);
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_3D: /* GL_ARB_texture_compression */
+ (*ctx->Exec->CompressedTexImage3DARB)(n[1].e, n[2].i, n[3].e,
+ n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].data);
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: /* GL_ARB_texture_compress */
+ (*ctx->Exec->CompressedTexSubImage1DARB)(n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].e, n[6].i, n[7].data);
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: /* GL_ARB_texture_compress */
+ (*ctx->Exec->CompressedTexSubImage2DARB)(n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].i, n[6].i, n[7].e, n[8].i, n[9].data);
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: /* GL_ARB_texture_compress */
+ (*ctx->Exec->CompressedTexSubImage3DARB)(n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].i, n[6].i, n[7].i, n[8].i,
+ n[9].e, n[10].i, n[11].data);
+ break;
case OPCODE_CONTINUE:
n = (Node *) n[1].next;
break;
}
}
- if (!_mesa_is_legal_format_and_type(format, type)) {
- char message[100];
- sprintf(message, "glTexSubImage%dD(format or type)", dimensions);
- gl_error(ctx, GL_INVALID_ENUM, message);
- return GL_TRUE;
+ if (!is_compressed_format(destTex->IntFormat)) {
+ if (!_mesa_is_legal_format_and_type(format, type)) {
+ char message[100];
+ sprintf(message, "glTexSubImage%dD(format or type)", dimensions);
+ gl_error(ctx, GL_INVALID_ENUM, message);
+ return GL_TRUE;
+ }
}
return GL_FALSE;
switch (target) {
case GL_TEXTURE_1D:
texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[1];
+ texImage = texObj->Image[level];
break;
case GL_TEXTURE_2D:
texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[2];
+ texImage = texObj->Image[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->Image[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->NegX[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->PosY[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->NegY[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->PosZ[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->NegZ[level];
break;
case GL_TEXTURE_3D:
texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[3];
+ texImage = texObj->Image[level];
break;
default:
gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(target)" );
return;
}
- texImage = texObj->Image[level];
if (!texImage) {
/* invalid mipmap level */
return;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCompressedTexImage2DARB");
- if (target == GL_TEXTURE_2D) {
+ if (target==GL_TEXTURE_2D ||
+ (ctx->Extensions.HaveTextureCubeMap &&
+ target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCompressedTexImage3DARB");
- if (target == GL_TEXTURE_1D) {
+ if (target == GL_TEXTURE_3D) {
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei width, GLenum format,
GLsizei imageSize, const GLvoid *data)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean success = GL_FALSE;
+
+ if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
+ width, 1, 1, format, GL_NONE)) {
+ return; /* error was detected */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = texObj->Image[level];
+ assert(texImage);
+
+ if (width == 0 || !data)
+ return; /* no-op, not an error */
+
+ if (ctx->Driver.CompressedTexSubImage1D) {
+ success = (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
+ xoffset, width, format, imageSize, data, texObj, texImage);
+ }
+ if (!success) {
+ /* XXX what else can we do? */
+ gl_problem(ctx, "glCompressedTexSubImage1DARB failed!");
+ return;
+ }
+
}
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean success = GL_FALSE;
+
+ if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
+ width, height, 1, format, GL_NONE)) {
+ return; /* error was detected */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = texObj->Image[level];
+ assert(texImage);
+
+ if (width == 0 || height == 0 || !data)
+ return; /* no-op, not an error */
+
+ if (ctx->Driver.CompressedTexSubImage2D) {
+ success = (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
+ xoffset, yoffset, width, height, format,
+ imageSize, data, texObj, texImage);
+ }
+ if (!success) {
+ /* XXX what else can we do? */
+ gl_problem(ctx, "glCompressedTexSubImage2DARB failed!");
+ return;
+ }
}
GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid *data)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean success = GL_FALSE;
+
+ if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, GL_NONE)) {
+ return; /* error was detected */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = texObj->Image[level];
+ assert(texImage);
+
+ if (width == 0 || height == 0 || depth == 0 || !data)
+ return; /* no-op, not an error */
+
+ if (ctx->Driver.CompressedTexSubImage3D) {
+ success = (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
+ xoffset, yoffset, zoffset, width, height, depth,
+ format, imageSize, data, texObj, texImage);
+ }
+ if (!success) {
+ /* XXX what else can we do? */
+ gl_problem(ctx, "glCompressedTexSubImage3DARB failed!");
+ return;
+ }
}
void
-_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img)
+_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
{
+ GET_CURRENT_CONTEXT(ctx);
+ const struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetCompressedTexImageARB");
+
+ if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
+ gl_error( ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)" );
+ return;
+ }
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[1];
+ texImage = texObj->Image[level];
+ break;
+ case GL_TEXTURE_2D:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[2];
+ texImage = texObj->Image[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->Image[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->NegX[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->PosY[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->NegY[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->PosZ[level];
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
+ texImage = texObj->NegZ[level];
+ break;
+ case GL_TEXTURE_3D:
+ texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[3];
+ texImage = texObj->Image[level];
+ break;
+ default:
+ gl_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
+ return;
+ }
+
+ if (!texImage) {
+ /* invalid mipmap level */
+ gl_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
+ return;
+ }
+
+ if (!texImage->IsCompressed) {
+ gl_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB");
+ return;
+ }
+
+ if (!img)
+ return;
+
+ if (ctx->Driver.GetCompressedTexImage) {
+ (*ctx->Driver.GetCompressedTexImage)(ctx, target, level, img, texObj,
+ texImage);
+ }
+ else {
+ gl_problem(ctx, "Driver doesn't implement GetCompressedTexImage");
+ }
}