X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fteximage.c;h=4b9b1b8728d27a3e7dd5debd941b1d4f0a51c251;hb=5999c5b620236fb6a996cf56759aec31f01c126b;hp=f0b3ac1f13dff4e18907731ea9d0c01d9e53b367;hpb=8c3ddf4270ff075ee783a67e5d5d04fa16a9cb45;p=mesa.git diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index f0b3ac1f13d..4b9b1b8728d 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.3 + * Version: 6.5 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -25,13 +25,7 @@ /** * \file teximage.c - * Texture images manipulation functions. - * - * \note Mesa's native texture data type is GLchan. Native formats are - * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA, and - * GL_COLOR_INDEX. - * - * \note Device drivers are free to implement any internal format they want. + * Texture image-related functions. */ @@ -39,6 +33,8 @@ #include "bufferobj.h" #include "context.h" #include "convolve.h" +#include "fbobject.h" +#include "framebuffer.h" #include "image.h" #include "imports.h" #include "macros.h" @@ -51,6 +47,29 @@ #include "mtypes.h" +/** + * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE + * elsewhere. + */ +void * +_mesa_alloc_texmemory(GLsizei bytes) +{ + return _mesa_align_malloc(bytes, 512); +} + + +/** + * Free texture memory allocated with _mesa_alloc_texmemory() + */ +void +_mesa_free_texmemory(void *m) +{ + _mesa_align_free(m); +} + + + + #if 0 static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img) { @@ -98,6 +117,7 @@ static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img) _mesa_printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]); data += (img->RowStride - img->Width) * c; } + /* XXX use img->ImageStride here */ _mesa_printf("\n"); } #endif @@ -219,7 +239,8 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat ) } } - if (ctx->Extensions.SGIX_depth_texture) { + if (ctx->Extensions.SGIX_depth_texture || + ctx->Extensions.ARB_depth_texture) { switch (internalFormat) { case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16_SGIX: @@ -317,6 +338,16 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat ) } } + if (ctx->Extensions.EXT_packed_depth_stencil) { + switch (internalFormat) { + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + return GL_DEPTH_STENCIL_EXT; + default: + ; /* fallthrough */ + } + } + return -1; /* error */ } @@ -471,6 +502,23 @@ is_ycbcr_format(GLenum format) } +/** + * Test if the given image format is a Depth/Stencil format. + */ +static GLboolean +is_depthstencil_format(GLenum format) +{ + switch (format) { + case GL_DEPTH24_STENCIL8_EXT: + case GL_DEPTH_STENCIL_EXT: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + + /** * Test if it is a supported compressed format. * @@ -504,6 +552,18 @@ is_compressed_format(GLcontext *ctx, GLenum internalFormat) } +static GLuint +texture_face(GLenum target) +{ + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) + return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + else + return 0; +} + + + /** * Store a gl_texture_image pointer in a gl_texture_object structure * according to the target and level parameters. @@ -533,12 +593,13 @@ _mesa_set_tex_image(struct gl_texture_object *tObj, case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: { - GLuint face = ((GLuint) target - - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); - tObj->Image[face][level] = texImage; - break; - } + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + { + GLuint face = ((GLuint) target - + (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); + tObj->Image[face][level] = texImage; + } + break; case GL_TEXTURE_RECTANGLE_NV: ASSERT(level == 0); tObj->Image[0][level] = texImage; @@ -569,22 +630,42 @@ _mesa_new_texture_image( GLcontext *ctx ) } +/** + * Free texture image data. + * This function is a fallback called via ctx->Driver.FreeTexImageData(). + * + * \param teximage texture image. + * + * Free the texture image data if it's not marked as client data. + */ +void +_mesa_free_texture_image_data(GLcontext *ctx, + struct gl_texture_image *texImage) +{ + if (texImage->Data && !texImage->IsClientData) { + /* free the old texture data */ + _mesa_free_texmemory(texImage->Data); + } + + texImage->Data = NULL; +} + + /** * Free texture image. * * \param teximage texture image. * - * Free the texture image structure and the associated image data if it's not - * marked as client data. + * Free the texture image structure and the associated image data. */ void -_mesa_delete_texture_image( struct gl_texture_image *teximage ) +_mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage ) { - if (teximage->Data && !teximage->IsClientData) { - MESA_PBUFFER_FREE( teximage->Data ); - teximage->Data = NULL; + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - FREE( teximage ); + ASSERT(texImage->Data == NULL); + FREE( texImage ); } @@ -595,8 +676,8 @@ _mesa_delete_texture_image( struct gl_texture_image *teximage ) * * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise. */ -static GLboolean -is_proxy_target(GLenum target) +GLboolean +_mesa_is_proxy_texture(GLenum target) { return (target == GL_PROXY_TEXTURE_1D || target == GL_PROXY_TEXTURE_2D || @@ -965,13 +1046,14 @@ static void clear_teximage_fields(struct gl_texture_image *img) { ASSERT(img); - img->Format = 0; - img->IntFormat = 0; + img->_BaseFormat = 0; + img->InternalFormat = 0; img->Border = 0; img->Width = 0; img->Height = 0; img->Depth = 0; img->RowStride = 0; + img->ImageStride = 0; img->Width2 = 0; img->Height2 = 0; img->Depth2 = 0; @@ -1009,37 +1091,34 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target, GLint border, GLenum internalFormat) { ASSERT(img); - img->Format = _mesa_base_tex_format( ctx, internalFormat ); - ASSERT(img->Format > 0); - img->IntFormat = internalFormat; + img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); + ASSERT(img->_BaseFormat > 0); + img->InternalFormat = internalFormat; img->Border = border; img->Width = width; img->Height = height; img->Depth = depth; img->RowStride = width; - img->WidthLog2 = logbase2(width - 2 * border); + img->ImageStride = width * height; + img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ + img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ + img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ + img->WidthLog2 = logbase2(img->Width2); if (height == 1) /* 1-D texture */ img->HeightLog2 = 0; else - img->HeightLog2 = logbase2(height - 2 * border); + img->HeightLog2 = logbase2(img->Height2); if (depth == 1) /* 2-D texture */ img->DepthLog2 = 0; else - img->DepthLog2 = logbase2(depth - 2 * border); - img->Width2 = width - 2 * border; /*1 << img->WidthLog2;*/ - img->Height2 = height - 2 * border; /*1 << img->HeightLog2;*/ - img->Depth2 = depth - 2 * border; /*1 << img->DepthLog2;*/ + img->DepthLog2 = logbase2(img->Depth2); img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); - img->IsCompressed = is_compressed_format(ctx, internalFormat); - if (img->IsCompressed) - img->CompressedSize = ctx->Driver.CompressedTextureSize(ctx, width, - height, depth, internalFormat); - else - img->CompressedSize = 0; + img->IsCompressed = GL_FALSE; + img->CompressedSize = 0; - if ((width == 1 || _mesa_bitcount(width - 2 * border) == 1) && - (height == 1 || _mesa_bitcount(height - 2 * border) == 1) && - (depth == 1 || _mesa_bitcount(depth - 2 * border) == 1)) + if ((width == 1 || _mesa_bitcount(img->Width2) == 1) && + (height == 1 || _mesa_bitcount(img->Height2) == 1) && + (depth == 1 || _mesa_bitcount(img->Depth2) == 1)) img->_IsPowerOfTwo = GL_TRUE; else img->_IsPowerOfTwo = GL_FALSE; @@ -1187,7 +1266,7 @@ texture_error_check( GLcontext *ctx, GLenum target, GLint width, GLint height, GLint depth, GLint border ) { - const GLboolean isProxy = is_proxy_target(target); + const GLboolean isProxy = _mesa_is_proxy_texture(target); GLboolean sizeOK; GLboolean colorFormat, indexFormat; @@ -1324,7 +1403,8 @@ texture_error_check( GLcontext *ctx, GLenum target, if ((is_color_format(internalFormat) && !colorFormat && !indexFormat) || (is_index_format(internalFormat) && !indexFormat) || (is_depth_format(internalFormat) != is_depth_format(format)) || - (is_ycbcr_format(internalFormat) != is_ycbcr_format(format))) { + (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) || + (is_depthstencil_format(internalFormat) != is_depthstencil_format(format))) { if (!isProxy) _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage(internalFormat/format)"); @@ -1614,11 +1694,22 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border ) { - GLenum format, type; + GLenum type; GLboolean sizeOK; + GLint format; /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { + /* Check that the source buffer is complete */ + if (ctx->ReadBuffer->Name) { + _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); + if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, + "glCopyTexImage%dD(invalid readbuffer)", dimensions); + return GL_TRUE; + } + } + _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage%dD(level=%d)", dimensions, level); return GL_TRUE; @@ -1631,10 +1722,22 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - /* The format and type aren't really significant here, but we need to pass - * something to TestProxyTexImage(). - */ format = _mesa_base_tex_format(ctx, internalFormat); + if (format < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexImage%dD(internalFormat)", dimensions); + return GL_TRUE; + } + + /* NOTE: the format and type aren't really significant for + * TestProxyTexImage(). Only the internalformat really matters. + if (!_mesa_source_buffer_exists(ctx, format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%dD(missing readbuffer)", dimensions); + return GL_TRUE; + } + + */ type = GL_FLOAT; /* Check target and call ctx->Driver.TestProxyTexImage() to check the @@ -1704,12 +1807,6 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - if (_mesa_base_tex_format(ctx, internalFormat) < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexImage%dD(internalFormat)", dimensions); - return GL_TRUE; - } - if (is_compressed_format(ctx, internalFormat)) { if (target != GL_TEXTURE_2D) { _mesa_error(ctx, GL_INVALID_ENUM, @@ -1722,6 +1819,22 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } } + else if (is_depth_format(internalFormat)) { + /* make sure we have depth/stencil buffers */ + if (!ctx->ReadBuffer->_DepthBuffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%D(no depth)", dimensions); + return GL_TRUE; + } + } + else if (is_depthstencil_format(internalFormat)) { + /* make sure we have depth/stencil buffers */ + if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%D(no depth/stencil buffer)", dimensions); + return GL_TRUE; + } + } /* if we get here, the parameters are OK */ return GL_FALSE; @@ -1729,7 +1842,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, /** - * Test glCopyTexImage[12]D() parameters for errors. + * Test glCopyTexSubImage[12]D() parameters for errors. * * \param ctx GL context. * \param dimensions texture image dimensions (must be 1, 2 or 3). @@ -1757,6 +1870,16 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, struct gl_texture_image *teximage; /* Check target */ + /* Check that the source buffer is complete */ + if (ctx->ReadBuffer->Name) { + _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); + if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, + "glCopyTexImage%dD(invalid readbuffer)", dimensions); + return GL_TRUE; + } + } + if (dimensions == 1) { if (target != GL_TEXTURE_1D) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); @@ -1854,6 +1977,12 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, } if (teximage->IsCompressed) { + if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexSubImage%dD(missing readbuffer)", dimensions); + return GL_TRUE; + } + if (target != GL_TEXTURE_2D) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%d(target)", dimensions); @@ -1878,11 +2007,28 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, } } - if (teximage->IntFormat == GL_YCBCR_MESA) { + if (teximage->InternalFormat == GL_YCBCR_MESA) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); return GL_TRUE; } + if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) { + if (!ctx->ReadBuffer->_DepthBuffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexSubImage%D(no depth buffer)", + dimensions); + return GL_TRUE; + } + } + else if (teximage->_BaseFormat == GL_DEPTH_STENCIL_EXT) { + if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexSubImage%D(no depth/stencil buffer)", + dimensions); + return GL_TRUE; + } + } + /* if we get here, the parameters are OK */ return GL_FALSE; } @@ -1902,15 +2048,15 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels ) { const struct gl_texture_unit *texUnit; - const struct gl_texture_object *texObj; - const struct gl_texture_image *texImage; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; GLint maxLevels = 0; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]); texObj = _mesa_select_tex_object(ctx, texUnit, target); - if (!texObj || is_proxy_target(target)) { + if (!texObj || _mesa_is_proxy_texture(target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); return; } @@ -1938,7 +2084,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); } - if (!ctx->Extensions.SGIX_depth_texture && is_depth_format(format)) { + if (!ctx->Extensions.SGIX_depth_texture && + !ctx->Extensions.ARB_depth_texture && is_depth_format(format)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); } @@ -1946,6 +2093,11 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); } + if (!ctx->Extensions.EXT_packed_depth_stencil + && is_depthstencil_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); + } + if (!pixels) return; @@ -1956,8 +2108,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, } /* Make sure the requested image format is compatible with the - * texture's format. We let the colorformat-indexformat go through, - * because the texelfetcher will dequantize to full rgba. + * texture's format. Note that a color index texture can be converted + * to RGBA so that combo is allowed. */ if (is_color_format(format) && !is_color_format(texImage->TexFormat->BaseFormat) @@ -1971,7 +2123,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, return; } else if (is_depth_format(format) - && !is_depth_format(texImage->TexFormat->BaseFormat)) { + && !is_depth_format(texImage->TexFormat->BaseFormat) + && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); return; } @@ -1980,6 +2133,11 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); return; } + else if (is_depthstencil_format(format) + && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + return; + } /* typically, this will call _mesa_get_teximage() */ ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels, @@ -1988,6 +2146,36 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, +/** + * Check if the given texture image is bound to any framebuffer objects + * and update/invalidate them. + * XXX We're only checking the currently bound framebuffer object for now. + * In the future, perhaps struct gl_texture_image should have a pointer (or + * list of pointers (yikes)) to the gl_framebuffer(s) which it's bound to. + */ +static void +update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj, + GLuint face, GLuint level) +{ + if (ctx->DrawBuffer->Name) { + GLuint i; + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = + ctx->DrawBuffer->Attachment + i; + if (att->Type == GL_TEXTURE && + att->Texture == texObj && + att->TextureLevel == level && + att->CubeMapFace == face) { + ASSERT(att->Texture->Image[att->CubeMapFace][att->TextureLevel]); + /* Tell driver about the new renderbuffer texture */ + ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att); + } + } + } +} + + + /* * Called from the API. Note that width includes the border. */ @@ -2009,6 +2197,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + const GLuint face = texture_face(target); if (texture_error_check(ctx, target, level, internalFormat, format, type, 1, postConvWidth, 1, 1, border)) { @@ -2023,11 +2212,10 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); return; } - else if (texImage->Data && !texImage->IsClientData) { - /* free the old texture data */ - MESA_PBUFFER_FREE(texImage->Data); + else if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - texImage->Data = NULL; + ASSERT(texImage->Data == NULL); clear_teximage_fields(texImage); /* not really needed, but helpful */ _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, @@ -2045,13 +2233,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, ASSERT(texImage->TexFormat); - /* If driver didn't explicitly set this, use the defaults */ - if (!texImage->FetchTexelc) - texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D; - if (!texImage->FetchTexelf) - texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df; - ASSERT(texImage->FetchTexelc); - ASSERT(texImage->FetchTexelf); + update_fbo_texture(ctx, texObj, face, level); /* state update */ texObj->Complete = GL_FALSE; @@ -2109,6 +2291,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + const GLuint face = texture_face(target); if (texture_error_check(ctx, target, level, internalFormat, format, type, 2, postConvWidth, postConvHeight, @@ -2123,11 +2306,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } - else if (texImage->Data && !texImage->IsClientData) { - /* free the old texture data */ - MESA_PBUFFER_FREE(texImage->Data); + else if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - texImage->Data = NULL; + ASSERT(texImage->Data == NULL); clear_teximage_fields(texImage); /* not really needed, but helpful */ _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, postConvHeight, 1, @@ -2145,13 +2327,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, ASSERT(texImage->TexFormat); - /* If driver didn't explicitly set these, use the defaults */ - if (!texImage->FetchTexelc) - texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D; - if (!texImage->FetchTexelf) - texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df; - ASSERT(texImage->FetchTexelc); - ASSERT(texImage->FetchTexelf); + update_fbo_texture(ctx, texObj, face, level); /* state update */ texObj->Complete = GL_FALSE; @@ -2202,10 +2378,11 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (target == GL_TEXTURE_3D) { + /* non-proxy target */ struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; - /* non-proxy target */ + const GLuint face = texture_face(target); if (texture_error_check(ctx, target, level, (GLint) internalFormat, format, type, 3, width, height, depth, border)) { @@ -2219,10 +2396,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); return; } - else if (texImage->Data && !texImage->IsClientData) { - MESA_PBUFFER_FREE(texImage->Data); + else if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - texImage->Data = NULL; + ASSERT(texImage->Data == NULL); clear_teximage_fields(texImage); /* not really needed, but helpful */ _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, @@ -2240,13 +2417,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, ASSERT(texImage->TexFormat); - /* If driver didn't explicitly set these, use the defaults */ - if (!texImage->FetchTexelc) - texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D; - if (!texImage->FetchTexelf) - texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df; - ASSERT(texImage->FetchTexelc); - ASSERT(texImage->FetchTexelf); + update_fbo_texture(ctx, texObj, face, level); /* state update */ texObj->Complete = GL_FALSE; @@ -2438,6 +2609,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width; + const GLuint face = texture_face(target); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -2459,11 +2631,10 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); return; } - else if (texImage->Data && !texImage->IsClientData) { - /* free the old texture data */ - MESA_PBUFFER_FREE(texImage->Data); + else if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - texImage->Data = NULL; + ASSERT(texImage->Data == NULL); clear_teximage_fields(texImage); /* not really needed, but helpful */ _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, @@ -2476,13 +2647,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, ASSERT(texImage->TexFormat); - /* If driver didn't explicitly set these, use the defaults */ - if (!texImage->FetchTexelc) - texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D; - if (!texImage->FetchTexelf) - texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df; - ASSERT(texImage->FetchTexelc); - ASSERT(texImage->FetchTexelf); + update_fbo_texture(ctx, texObj, face, level); /* state update */ texObj->Complete = GL_FALSE; @@ -2500,6 +2665,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width, postConvHeight = height; + const GLuint face = texture_face(target); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -2522,11 +2688,10 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); return; } - else if (texImage->Data && !texImage->IsClientData) { - /* free the old texture data */ - MESA_PBUFFER_FREE(texImage->Data); + else if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - texImage->Data = NULL; + ASSERT(texImage->Data == NULL); clear_teximage_fields(texImage); /* not really needed, but helpful */ _mesa_init_teximage_fields(ctx, target, texImage, @@ -2539,13 +2704,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, ASSERT(texImage->TexFormat); - /* If driver didn't explicitly set these, use the defaults */ - if (!texImage->FetchTexelc) - texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D; - if (!texImage->FetchTexelf) - texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df; - ASSERT(texImage->FetchTexelc); - ASSERT(texImage->FetchTexelf); + update_fbo_texture(ctx, texObj, face, level); /* state update */ texObj->Complete = GL_FALSE; @@ -2681,7 +2840,7 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize) { - GLint expectedSize, maxLevels = 0, maxTextureSize; + GLint /**expectedSize,**/ maxLevels = 0, maxTextureSize; if (dimensions == 1) { /* 1D compressed textures not allowed */ @@ -2750,10 +2909,13 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions, if (level < 0 || level >= maxLevels) return GL_INVALID_VALUE; +#if 0 + /* XXX need to renable this code someday! */ expectedSize = ctx->Driver.CompressedTextureSize(ctx, width, height, depth, internalFormat); if (expectedSize != imageSize) return GL_INVALID_VALUE; +#endif return GL_NO_ERROR; } @@ -2872,10 +3034,10 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); return; } - else if (texImage->Data && !texImage->IsClientData) { - MESA_PBUFFER_FREE(texImage->Data); + else if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - texImage->Data = NULL; + ASSERT(texImage->Data == NULL); _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, border, internalFormat); @@ -2955,10 +3117,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); return; } - else if (texImage->Data && !texImage->IsClientData) { - MESA_PBUFFER_FREE(texImage->Data); + else if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - texImage->Data = NULL; + ASSERT(texImage->Data == NULL); _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, border, internalFormat); @@ -3037,10 +3199,10 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); return; } - else if (texImage->Data && !texImage->IsClientData) { - MESA_PBUFFER_FREE(texImage->Data); + else if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); } - texImage->Data = NULL; + ASSERT(texImage->Data == NULL); _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, border, internalFormat); @@ -3114,7 +3276,7 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, texImage = _mesa_select_tex_image(ctx, texUnit, target, level); assert(texImage); - if ((GLint) format != texImage->IntFormat) { + if ((GLint) format != texImage->InternalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCompressedTexSubImage1D(format)"); return; @@ -3164,7 +3326,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, texImage = _mesa_select_tex_image(ctx, texUnit, target, level); assert(texImage); - if ((GLint) format != texImage->IntFormat) { + if ((GLint) format != texImage->InternalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCompressedTexSubImage2D(format)"); return; @@ -3214,7 +3376,7 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, texImage = _mesa_select_tex_image(ctx, texUnit, target, level); assert(texImage); - if ((GLint) format != texImage->IntFormat) { + if ((GLint) format != texImage->InternalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCompressedTexSubImage3D(format)"); return; @@ -3266,7 +3428,7 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) return; } - if (is_proxy_target(target)) { + if (_mesa_is_proxy_texture(target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)"); return; }