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.c1137
1 files changed, 585 insertions, 552 deletions
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index a8160c273..b946f3c69 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -33,9 +33,7 @@
#include "glheader.h"
#include "bufferobj.h"
#include "context.h"
-#if FEATURE_convolve
#include "convolve.h"
-#endif
#include "enums.h"
#include "fbobject.h"
#include "framebuffer.h"
@@ -45,7 +43,7 @@
#include "macros.h"
#include "state.h"
#include "texcompress.h"
-#include "texformat.h"
+#include "texfetch.h"
#include "teximage.h"
#include "texstate.h"
#include "texstore.h"
@@ -84,63 +82,6 @@ _mesa_free_texmemory(void *m)
}
-
-
-#if 0
-static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img)
-{
-#if CHAN_TYPE != GL_UNSIGNED_BYTE
- _mesa_problem(NULL, "PrintTexture not supported");
-#else
- GLuint i, j, c;
- const GLubyte *data = (const GLubyte *) img->Data;
-
- if (!data) {
- _mesa_printf("No texture data\n");
- return;
- }
-
- switch (img->Format) {
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_INTENSITY:
- case GL_COLOR_INDEX:
- c = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- c = 2;
- break;
- case GL_RGB:
- c = 3;
- break;
- case GL_RGBA:
- c = 4;
- break;
- default:
- _mesa_problem(NULL, "error in PrintTexture\n");
- return;
- }
-
- for (i = 0; i < img->Height; i++) {
- for (j = 0; j < img->Width; j++) {
- if (c==1)
- _mesa_printf("%02x ", data[0]);
- else if (c==2)
- _mesa_printf("%02x%02x ", data[0], data[1]);
- else if (c==3)
- _mesa_printf("%02x%02x%02x ", data[0], data[1], data[2]);
- else if (c==4)
- _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
-}
-#endif
-
-
/*
* Compute floor(log_base_2(n)).
* If n < 0 return -1.
@@ -642,6 +583,17 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
/**
+ * Return pointer to texture object for given target on current texture unit.
+ */
+struct gl_texture_object *
+_mesa_get_current_tex_object(GLcontext *ctx, GLenum target)
+{
+ struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
+ return _mesa_select_tex_object(ctx, texUnit, target);
+}
+
+
+/**
* Get a texture image pointer from a texture object, given a texture
* target and mipmap level. The target and level parameters should
* have already been error-checked.
@@ -902,11 +854,9 @@ clear_teximage_fields(struct gl_texture_image *img)
img->HeightLog2 = 0;
img->DepthLog2 = 0;
img->Data = NULL;
- img->TexFormat = &_mesa_null_texformat;
+ img->TexFormat = MESA_FORMAT_NONE;
img->FetchTexelc = NULL;
img->FetchTexelf = NULL;
- img->IsCompressed = 0;
- img->CompressedSize = 0;
}
@@ -969,9 +919,6 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
- img->IsCompressed = GL_FALSE;
- img->CompressedSize = 0;
-
if ((width == 1 || _mesa_is_pow_two(img->Width2)) &&
(height == 1 || _mesa_is_pow_two(img->Height2)) &&
(depth == 1 || _mesa_is_pow_two(img->Depth2)))
@@ -1004,6 +951,9 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
img->HeightScale = (GLfloat) img->Height;
img->DepthScale = (GLfloat) img->Depth;
}
+
+ img->FetchTexelc = NULL;
+ img->FetchTexelf = NULL;
}
@@ -1317,8 +1267,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
if (!isProxy) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(internalFormat=0x%x)",
- dimensions, internalFormat);
+ "glTexImage%dD(internalFormat=%s)",
+ dimensions, _mesa_lookup_enum_by_nr(internalFormat));
}
return GL_TRUE;
}
@@ -1530,6 +1480,11 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_FALSE;
}
+
+/**
+ * Do second part of glTexSubImage which depends on the destination texture.
+ * \return GL_TRUE if error recorded, GL_FALSE otherwise
+ */
static GLboolean
subtexture_error_check2( GLcontext *ctx, GLuint dimensions,
GLenum target, GLint level,
@@ -1577,41 +1532,35 @@ subtexture_error_check2( GLcontext *ctx, GLuint dimensions,
}
}
-#if FEATURE_EXT_texture_sRGB
- if (destTex->InternalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT ||
- destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ||
- destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ||
- destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) {
- if ((width & 0x3) || (height & 0x3) ||
- (xoffset & 0x3) || (yoffset & 0x3))
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexSubImage%dD(size or offset not multiple of 4)",
- dimensions);
- return GL_TRUE;
- }
-#endif
+ if (_mesa_is_format_compressed(destTex->TexFormat)) {
+ GLuint bw, bh;
- if (destTex->IsCompressed) {
if (!target_can_be_compressed(ctx, target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glTexSubImage%D(target)", dimensions);
+ "glTexSubImage%D(target=%s)", dimensions,
+ _mesa_lookup_enum_by_nr(target));
return GL_TRUE;
}
- /* offset must be multiple of 4 */
- if ((xoffset & 3) || (yoffset & 3)) {
+
+ /* do tests which depend on compression block size */
+ _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh);
+
+ /* offset must be multiple of block size */
+ if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexSubImage%D(xoffset or yoffset)", dimensions);
+ "glTexSubImage%D(xoffset = %d, yoffset = %d)",
+ dimensions, xoffset, yoffset);
return GL_TRUE;
}
- /* size must be multiple of 4 or equal to whole texture size */
- if ((width & 3) && (GLuint) width != destTex->Width) {
+ /* size must be multiple of bw by bh or equal to whole texture size */
+ if ((width % bw != 0) && (GLuint) width != destTex->Width) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexSubImage%D(width)", dimensions);
+ "glTexSubImage%D(width = %d)", dimensions, width);
return GL_TRUE;
}
- if ((height & 3) && (GLuint) height != destTex->Height) {
+ if ((height % bh != 0) && (GLuint) height != destTex->Height) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexSubImage%D(width)", dimensions);
+ "glTexSubImage%D(height = %d)", dimensions, height);
return GL_TRUE;
}
}
@@ -1953,7 +1902,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
}
}
- if (teximage->IsCompressed) {
+ if (_mesa_is_format_compressed(teximage->TexFormat)) {
if (!target_can_be_compressed(ctx, target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexSubImage%d(target)", dimensions);
@@ -2076,6 +2025,25 @@ update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj,
}
+/**
+ * If the texture object's GenerateMipmap flag is set and we've
+ * changed the texture base level image, regenerate the rest of the
+ * mipmap levels now.
+ */
+static INLINE void
+check_gen_mipmap(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj, GLint level)
+{
+ ASSERT(target != GL_TEXTURE_CUBE_MAP);
+ if (texObj->GenerateMipmap &&
+ level == texObj->BaseLevel &&
+ level < texObj->MaxLevel) {
+ ASSERT(ctx->Driver.GenerateMipmap);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+}
+
+
/** Debug helper: override the user-requested internal format */
static GLenum
override_internal_format(GLenum internalFormat, GLint width, GLint height)
@@ -2149,7 +2117,6 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
if (target == GL_TEXTURE_1D) {
/* non-proxy target */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
const GLuint face = _mesa_tex_target_to_face(target);
@@ -2162,43 +2129,50 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ 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, "glTexImage1D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+
+ ASSERT(texImage->Data == NULL);
+
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, 1, 1,
+ border, internalFormat);
+
+ /* Choose actual texture format */
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ format, type);
+ ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+
+ /* Give the texture to the driver. <pixels> may be null. */
+ ASSERT(ctx->Driver.TexImage1D);
+ ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
+ width, border, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
+
+ ASSERT(texImage->TexFormat);
+
+ _mesa_set_fetch_functions(texImage, 1);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ update_fbo_texture(ctx, texObj, face, level);
- ASSERT(texImage->Data == NULL);
-
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- postConvWidth, 1, 1,
- border, internalFormat);
-
- ASSERT(ctx->Driver.TexImage1D);
-
- /* Give the texture to the driver! <pixels> may be null! */
- (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
- width, border, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- ASSERT(texImage->TexFormat);
-
- update_fbo_texture(ctx, texObj, face, level);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_1D) {
@@ -2217,8 +2191,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
_mesa_init_teximage_fields(ctx, target, texImage,
postConvWidth, 1, 1,
border, internalFormat);
- texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
- internalFormat, format, type);
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
}
}
else {
@@ -2263,7 +2237,6 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
(ctx->Extensions.MESA_texture_array &&
target == GL_TEXTURE_1D_ARRAY_EXT)) {
/* non-proxy target */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
const GLuint face = _mesa_tex_target_to_face(target);
@@ -2277,42 +2250,49 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ 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, "glTexImage2D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
-
- ASSERT(texImage->Data == NULL);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- postConvWidth, postConvHeight, 1,
- border, internalFormat);
-
- ASSERT(ctx->Driver.TexImage2D);
-
- /* Give the texture to the driver! <pixels> may be null! */
- (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
- width, height, border, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- ASSERT(texImage->TexFormat);
-
- update_fbo_texture(ctx, texObj, face, level);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+
+ ASSERT(texImage->Data == NULL);
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+
+ /* Choose actual texture format */
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ format, type);
+ ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+
+ /* Give the texture to the driver. <pixels> may be null. */
+ ASSERT(ctx->Driver.TexImage2D);
+ ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+ width, height, border, format, type,
+ pixels, &ctx->Unpack, texObj, texImage);
+
+ ASSERT(texImage->TexFormat);
+
+ _mesa_set_fetch_functions(texImage, 2);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_2D ||
@@ -2337,8 +2317,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
_mesa_init_teximage_fields(ctx, target, texImage,
postConvWidth, postConvHeight, 1,
border, internalFormat);
- texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
- internalFormat, format, type);
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
}
}
else {
@@ -2374,7 +2354,6 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
(ctx->Extensions.MESA_texture_array &&
target == GL_TEXTURE_2D_ARRAY_EXT)) {
/* non-proxy target */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
const GLuint face = _mesa_tex_target_to_face(target);
@@ -2387,42 +2366,49 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ 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, "glTexImage3D");
- goto out;
}
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
-
- ASSERT(texImage->Data == NULL);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, depth,
- border, internalFormat);
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+
+ ASSERT(texImage->Data == NULL);
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ width, height, depth,
+ border, internalFormat);
+
+ /* Choose actual texture format */
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ format, type);
+ ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
- ASSERT(ctx->Driver.TexImage3D);
+ /* Give the texture to the driver. <pixels> may be null. */
+ ASSERT(ctx->Driver.TexImage3D);
+ ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
+ width, height, depth, border, format, type,
+ pixels, &ctx->Unpack, texObj, texImage);
- /* Give the texture to the driver! <pixels> may be null! */
- (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
- width, height, depth, border, format, type,
- pixels, &ctx->Unpack, texObj, texImage);
+ ASSERT(texImage->TexFormat);
- ASSERT(texImage->TexFormat);
+ _mesa_set_fetch_functions(texImage, 3);
- update_fbo_texture(ctx, texObj, face, level);
+ check_gen_mipmap(ctx, target, texObj, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_3D ||
@@ -2441,8 +2427,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
/* no error, set the tex image parameters */
_mesa_init_teximage_fields(ctx, target, texImage, width, height,
depth, border, internalFormat);
- texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
- internalFormat, format, type);
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
}
}
else {
@@ -2471,9 +2457,8 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
const GLvoid *pixels )
{
GLsizei postConvWidth = width;
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
- struct gl_texture_image *texImage = NULL;
+ struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -2499,8 +2484,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
}
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
assert(texObj);
_mesa_lock_texture(ctx, texObj);
@@ -2508,23 +2492,24 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0,
- postConvWidth, 1, 1, format, type, texImage)) {
- goto out; /* error was detected */
+ postConvWidth, 1, 1,
+ format, type, texImage)) {
+ /* error was recorded */
}
+ else if (width > 0) {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
- if (width == 0)
- goto out; /* no-op, not an error */
+ ASSERT(ctx->Driver.TexSubImage1D);
+ ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width,
+ format, type, pixels, &ctx->Unpack,
+ texObj, texImage);
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
+ check_gen_mipmap(ctx, target, texObj, level);
- ASSERT(ctx->Driver.TexSubImage1D);
- (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
- format, type, pixels, &ctx->Unpack,
- texObj, texImage);
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2537,7 +2522,6 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
const GLvoid *pixels )
{
GLsizei postConvWidth = width, postConvHeight = height;
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
@@ -2566,32 +2550,32 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
return; /* error was detected */
}
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
- postConvWidth, postConvHeight, 1, format, type,
- texImage)) {
- goto out; /* error was detected */
+ postConvWidth, postConvHeight, 1,
+ format, type, texImage)) {
+ /* error was recorded */
}
+ else if (width > 0 && height >= 0) {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
- if (width == 0 || height == 0)
- goto out; /* no-op, not an error */
+ ASSERT(ctx->Driver.TexSubImage2D);
+ ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
+ width, height, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
-
- ASSERT(ctx->Driver.TexSubImage2D);
- (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset,
- width, height, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
- ctx->NewState |= _NEW_TEXTURE;
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2604,7 +2588,6 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
GLenum format, GLenum type,
const GLvoid *pixels )
{
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
@@ -2625,35 +2608,36 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
return; /* error was detected */
}
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (subtexture_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset,
- width, height, depth, format, type, texImage)) {
- goto out; /* error was detected */
+ if (subtexture_error_check2(ctx, 3, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, texImage)) {
+ /* error was recorded */
}
+ else if (width > 0 && height > 0 && height > 0) {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+ zoffset += texImage->Border;
- if (width == 0 || height == 0 || height == 0)
- goto out; /* no-op, not an error */
+ ASSERT(ctx->Driver.TexSubImage3D);
+ ctx->Driver.TexSubImage3D(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, pixels,
+ &ctx->Unpack, texObj, texImage );
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
- zoffset += texImage->Border;
+ check_gen_mipmap(ctx, target, texObj, level);
- ASSERT(ctx->Driver.TexSubImage3D);
- (*ctx->Driver.TexSubImage3D)(ctx, target, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels,
- &ctx->Unpack, texObj, texImage );
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2665,7 +2649,6 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
GLint x, GLint y,
GLsizei width, GLint border )
{
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width;
@@ -2692,40 +2675,48 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
postConvWidth, 1, border))
return;
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ 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, "glCopyTexImage1D");
- goto out;
}
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
-
- ASSERT(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,
+ border, internalFormat);
+
+ /* Choose actual texture format */
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ GL_NONE, GL_NONE);
+ ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
- border, internalFormat);
+ ASSERT(ctx->Driver.CopyTexImage1D);
+ ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
+ x, y, width, border);
+ ASSERT(texImage->TexFormat);
- ASSERT(ctx->Driver.CopyTexImage1D);
- (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat,
- x, y, width, border);
+ _mesa_set_fetch_functions(texImage, 1);
- ASSERT(texImage->TexFormat);
+ check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ update_fbo_texture(ctx, texObj, face, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2736,7 +2727,6 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border )
{
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width, postConvHeight = height;
@@ -2764,8 +2754,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
postConvWidth, postConvHeight, border))
return;
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2773,33 +2762,42 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
-
- ASSERT(texImage->Data == NULL);
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+
+ ASSERT(texImage->Data == NULL);
+
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+
+ /* Choose actual texture format */
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ GL_NONE, GL_NONE);
+ ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+
+ ASSERT(ctx->Driver.CopyTexImage2D);
+ ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
+ x, y, width, height, border);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- postConvWidth, postConvHeight, 1,
- border, internalFormat);
-
- ASSERT(ctx->Driver.CopyTexImage2D);
- (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat,
- x, y, width, height, border);
-
- ASSERT(texImage->TexFormat);
+ ASSERT(texImage->TexFormat);
- update_fbo_texture(ctx, texObj, face, level);
+ _mesa_set_fetch_functions(texImage, 2);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2808,7 +2806,6 @@ void GLAPIENTRY
_mesa_CopyTexSubImage1D( GLenum target, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width )
{
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width;
@@ -2829,8 +2826,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 1, target, level))
return;
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2844,23 +2840,25 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
if (copytexsubimage_error_check2(ctx, 1, target, level,
xoffset, 0, 0, postConvWidth, 1,
- texImage))
- goto out;
-
+ texImage)) {
+ /* error was recorded */
+ }
+ else {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage1D);
+ ctx->Driver.CopyTexSubImage1D(ctx, target, level,
+ xoffset, x, y, width);
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage1D);
- ctx->Driver.CopyTexSubImage1D(ctx, target, level,
- xoffset, x, y, width);
- }
+ check_gen_mipmap(ctx, target, texObj, level);
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2871,7 +2869,6 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height )
{
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width, postConvHeight = height;
@@ -2889,8 +2886,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 2, target, level))
return;
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2903,24 +2899,29 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
}
#endif
- if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
- postConvWidth, postConvHeight, texImage))
- goto out;
+ if (copytexsubimage_error_check2(ctx, 2, target, level,
+ xoffset, yoffset, 0,
+ postConvWidth, postConvHeight,
+ texImage)) {
+ /* error was recorded */
+ }
+ else {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage2D);
+ ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset,
+ x, y, width, height);
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage2D);
- ctx->Driver.CopyTexSubImage2D(ctx, target, level,
- xoffset, yoffset, x, y, width, height);
- }
+ check_gen_mipmap(ctx, target, texObj, level);
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2931,7 +2932,6 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height )
{
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width, postConvHeight = height;
@@ -2949,8 +2949,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 3, target, level))
return;
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2965,25 +2964,28 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset,
zoffset, postConvWidth, postConvHeight,
- texImage))
- goto out;
-
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
- zoffset += texImage->Border;
-
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage3D);
- ctx->Driver.CopyTexSubImage3D(ctx, target, level,
- xoffset, yoffset, zoffset,
- x, y, width, height);
+ texImage)) {
+ /* error was recored */
}
+ else {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+ zoffset += texImage->Border;
+
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage3D);
+ ctx->Driver.CopyTexSubImage3D(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ x, y, width, height);
+
+ check_gen_mipmap(ctx, target, texObj, level);
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2996,6 +2998,29 @@ _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().
* \return error code or GL_NO_ERROR.
*/
@@ -3077,8 +3102,7 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
if (level < 0 || level >= maxLevels)
return GL_INVALID_VALUE;
- expectedSize = _mesa_compressed_texture_size_glenum(ctx, width, height,
- depth, internalFormat);
+ expectedSize = compressed_tex_size(width, height, depth, internalFormat);
if (expectedSize != imageSize)
return GL_INVALID_VALUE;
@@ -3111,6 +3135,7 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
GLenum format, GLsizei imageSize)
{
GLint expectedSize, maxLevels = 0, maxTextureSize;
+ GLuint bw, bh;
(void) zoffset;
if (dimensions == 1) {
@@ -3160,20 +3185,21 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
if (level < 0 || level >= maxLevels)
return GL_INVALID_VALUE;
- /* XXX these tests are specific to the compressed format.
- * this code should be generalized in some way.
+ /*
+ * do checks which depend on compression block size
*/
- if ((xoffset & 3) != 0 || (yoffset & 3) != 0)
+ get_compressed_block_size(format, &bw, &bh);
+
+ if ((xoffset % bw != 0) || (yoffset % bh != 0))
return GL_INVALID_VALUE;
- if ((width & 3) != 0 && width != 2 && width != 1)
+ if ((width % bw != 0) && width != 2 && width != 1)
return GL_INVALID_VALUE;
- if ((height & 3) != 0 && height != 2 && height != 1)
+ if ((height % bh != 0) && height != 2 && height != 1)
return GL_INVALID_VALUE;
- expectedSize = _mesa_compressed_texture_size_glenum(ctx, width, height,
- depth, format);
+ expectedSize = compressed_tex_size(width, height, depth, format);
if (expectedSize != imageSize)
return GL_INVALID_VALUE;
@@ -3181,6 +3207,55 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
}
+/**
+ * Do second part of glCompressedTexSubImage error checking.
+ * \return GL_TRUE if error found, GL_FALSE otherwise.
+ */
+static GLboolean
+compressed_subtexture_error_check2(GLcontext *ctx, GLuint dims,
+ GLsizei width, GLsizei height,
+ GLsizei depth, GLenum format,
+ struct gl_texture_image *texImage)
+{
+
+ if ((GLint) format != texImage->InternalFormat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTexSubImage%uD(format=0x%x)", dims, format);
+ return GL_TRUE;
+ }
+
+ if (((width == 1 || width == 2) &&
+ (GLuint) width != texImage->Width) ||
+ (width > texImage->Width)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCompressedTexSubImage%uD(width=%d)", dims, width);
+ return GL_TRUE;
+ }
+
+ if (dims >= 2) {
+ if (((height == 1 || height == 2) &&
+ (GLuint) height != texImage->Height) ||
+ (height > texImage->Height)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCompressedTexSubImage%uD(height=%d)", dims, height);
+ return GL_TRUE;
+ }
+ }
+
+ if (dims >= 3) {
+ if (((depth == 1 || depth == 2) &&
+ (GLuint) depth != texImage->Depth) ||
+ (depth > texImage->Depth)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCompressedTexSubImage%uD(depth=%d)", dims, depth);
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+
void GLAPIENTRY
_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
@@ -3199,7 +3274,6 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
if (target == GL_TEXTURE_1D) {
/* non-proxy target */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLenum error = compressed_texture_error_check(ctx, 1, target, level,
@@ -3209,36 +3283,44 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
return;
}
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ 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, "glCompressedTexImage1D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
- ASSERT(texImage->Data == NULL);
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
+ border, internalFormat);
+
+ /* Choose actual texture format */
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ GL_NONE, GL_NONE);
+ ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
- _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
- border, internalFormat);
+ ASSERT(ctx->Driver.CompressedTexImage1D);
+ ctx->Driver.CompressedTexImage1D(ctx, target, level,
+ internalFormat, width, border,
+ imageSize, data,
+ texObj, texImage);
- ASSERT(ctx->Driver.CompressedTexImage1D);
- (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
- internalFormat, width, border,
- imageSize, data,
- texObj, texImage);
+ _mesa_set_fetch_functions(texImage, 1);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_1D) {
@@ -3260,11 +3342,10 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
}
else {
/* store the teximage parameters */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3302,9 +3383,9 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
/* non-proxy target */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+
GLenum error = compressed_texture_error_check(ctx, 2, target, level,
internalFormat, width, height, 1, border, imageSize);
if (error) {
@@ -3312,36 +3393,44 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
return;
}
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ 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, "glCompressedTexImage2D");
- goto out;
}
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
- ASSERT(texImage->Data == NULL);
-
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
- border, internalFormat);
-
- ASSERT(ctx->Driver.CompressedTexImage2D);
- (*ctx->Driver.CompressedTexImage2D)(ctx, target, level,
- internalFormat, width, height,
- border, imageSize, data,
- texObj, texImage);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+ border, internalFormat);
+
+ /* Choose actual texture format */
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ GL_NONE, GL_NONE);
+ ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+
+ ASSERT(ctx->Driver.CompressedTexImage2D);
+ ctx->Driver.CompressedTexImage2D(ctx, target, level,
+ internalFormat, width, height,
+ border, imageSize, data,
+ texObj, texImage);
+
+ _mesa_set_fetch_functions(texImage, 2);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_2D ||
@@ -3365,11 +3454,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
}
else {
/* store the teximage parameters */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3404,7 +3492,6 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
if (target == GL_TEXTURE_3D) {
/* non-proxy target */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLenum error = compressed_texture_error_check(ctx, 3, target, level,
@@ -3414,36 +3501,46 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
return;
}
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ 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, "glCompressedTexImage3D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
- ASSERT(texImage->Data == NULL);
-
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
- border, internalFormat);
-
- ASSERT(ctx->Driver.CompressedTexImage3D);
- (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
- internalFormat,
- width, height, depth,
- border, imageSize, data,
- texObj, texImage);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ width, height, depth,
+ border, internalFormat);
+
+ /* Choose actual texture format */
+ texImage->TexFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ GL_NONE, GL_NONE);
+ ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+
+ ASSERT(ctx->Driver.CompressedTexImage3D);
+ ctx->Driver.CompressedTexImage3D(ctx, target, level,
+ internalFormat,
+ width, height, depth,
+ border, imageSize, data,
+ texObj, texImage);
+
+ _mesa_set_fetch_functions(texImage, 3);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_3D) {
@@ -3465,11 +3562,11 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
}
else {
/* store the teximage parameters */
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -3486,116 +3583,100 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
}
-void GLAPIENTRY
-_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
- GLsizei width, GLenum format,
- GLsizei imageSize, const GLvoid *data)
+/**
+ * Common helper for glCompressedTexSubImage1/2/3D().
+ */
+static void
+compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const GLvoid *data)
{
- struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLenum error;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- error = compressed_subtexture_error_check(ctx, 1, target, level,
+ error = compressed_subtexture_error_check(ctx, dims, target, level,
xoffset, 0, 0, /* pos */
- width, 1, 1, /* size */
+ width, height, depth, /* size */
format, imageSize);
if (error) {
- _mesa_error(ctx, error, "glCompressedTexSubImage1D");
+ _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims);
return;
}
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
assert(texImage);
- if ((GLint) format != texImage->InternalFormat) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTexSubImage1D(format)");
- goto out;
- }
+ if (compressed_subtexture_error_check2(ctx, dims, width, height, depth,
+ format, texImage)) {
+ /* error was recorded */
+ }
+ else if (width > 0 && height > 0 && depth > 0) {
+ switch (dims) {
+ case 1:
+ if (ctx->Driver.CompressedTexSubImage1D) {
+ ctx->Driver.CompressedTexSubImage1D(ctx, target, level,
+ xoffset, width,
+ format, imageSize, data,
+ texObj, texImage);
+ }
+ break;
+ case 2:
+ if (ctx->Driver.CompressedTexSubImage2D) {
+ ctx->Driver.CompressedTexSubImage2D(ctx, target, level,
+ xoffset, yoffset,
+ width, height,
+ format, imageSize, data,
+ texObj, texImage);
+ }
+ break;
+ case 3:
+ if (ctx->Driver.CompressedTexSubImage3D) {
+ ctx->Driver.CompressedTexSubImage3D(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, imageSize, data,
+ texObj, texImage);
+ }
+ break;
+ default:
+ ;
+ }
- if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)");
- goto out;
- }
-
- if (width == 0)
- goto out; /* no-op, not an error */
+ check_gen_mipmap(ctx, target, texObj, level);
- if (ctx->Driver.CompressedTexSubImage1D) {
- (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
- xoffset, width,
- format, imageSize, data,
- texObj, texImage);
+ ctx->NewState |= _NEW_TEXTURE;
}
- ctx->NewState |= _NEW_TEXTURE;
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
void GLAPIENTRY
+_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data)
+{
+ compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1,
+ format, imageSize, data);
+}
+
+
+void GLAPIENTRY
_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLsizei width, GLsizei height,
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLenum error;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- error = compressed_subtexture_error_check(ctx, 2, target, level,
- xoffset, yoffset, 0, /* pos */
- width, height, 1, /* size */
- format, imageSize);
- if (error) {
- /* XXX proxy target? */
- _mesa_error(ctx, error, "glCompressedTexSubImage2D");
- return;
- }
-
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- assert(texImage);
-
- if ((GLint) format != texImage->InternalFormat) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTexSubImage2D(format)");
- goto out;
- }
-
- if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
- ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)");
- goto out;
- }
-
- if (width == 0 || height == 0)
- goto out; /* no-op, not an error */
-
- if (ctx->Driver.CompressedTexSubImage2D) {
- (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
- xoffset, yoffset, width, height,
- format, imageSize, data,
- texObj, texImage);
- }
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
- _mesa_unlock_texture(ctx, texObj);
+ compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0,
+ width, height, 1, format, imageSize, data);
}
@@ -3605,56 +3686,8 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid *data)
{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLenum error;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- error = compressed_subtexture_error_check(ctx, 3, target, level,
- xoffset, yoffset, zoffset,/*pos*/
- width, height, depth, /*size*/
- format, imageSize);
- if (error) {
- _mesa_error(ctx, error, "glCompressedTexSubImage3D");
- return;
- }
-
- texUnit = _mesa_get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- assert(texImage);
-
- if ((GLint) format != texImage->InternalFormat) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTexSubImage3D(format)");
- goto out;
- }
-
- if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
- ((height == 1 || height == 2) && (GLuint) height != texImage->Height) ||
- ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)");
- goto out;
- }
-
- if (width == 0 || height == 0 || depth == 0)
- goto out; /* no-op, not an error */
-
- if (ctx->Driver.CompressedTexSubImage3D) {
- (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, imageSize, data,
- texObj, texImage);
- }
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
- _mesa_unlock_texture(ctx, texObj);
+ compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, imageSize, data);
}