| @@ -667,6 +667,47 @@ struct dd_function_table { | |||
| * 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 ); | |||
| @@ -1,4 +1,4 @@ | |||
| /* $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 | |||
| @@ -245,6 +245,13 @@ typedef enum { | |||
| /* 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 */ | |||
| @@ -420,6 +427,30 @@ void gl_destroy_list( GLcontext *ctx, GLuint list ) | |||
| 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 ); | |||
| @@ -628,7 +659,14 @@ void gl_init_lists( void ) | |||
| 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; | |||
| @@ -3611,28 +3649,136 @@ static void save_PixelTexGenSGIX(GLenum mode) | |||
| /* 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); | |||
| } | |||
| } | |||
| } | |||
| @@ -3641,6 +3787,36 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, | |||
| 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); | |||
| } | |||
| } | |||
| @@ -3650,6 +3826,38 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, | |||
| 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); | |||
| } | |||
| } | |||
| @@ -3659,6 +3867,40 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, | |||
| 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); | |||
| } | |||
| } | |||
| @@ -4433,6 +4675,31 @@ static void execute_list( GLcontext *ctx, GLuint list ) | |||
| 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; | |||
| @@ -1125,11 +1125,13 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, | |||
| } | |||
| } | |||
| 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; | |||
| @@ -1810,19 +1812,45 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, | |||
| 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; | |||
| @@ -2581,7 +2609,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, | |||
| 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; | |||
| @@ -2678,7 +2709,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, | |||
| 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; | |||
| @@ -2771,6 +2802,35 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, | |||
| 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; | |||
| } | |||
| } | |||
| @@ -2780,6 +2840,35 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, | |||
| 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; | |||
| } | |||
| } | |||
| @@ -2789,10 +2878,113 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, | |||
| 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"); | |||
| } | |||
| } | |||