-/* $Id: teximage.c,v 1.92 2001/04/19 22:39:50 brianp Exp $ */
+/* $Id: teximage.c,v 1.106 2001/11/18 22:48:13 brianp Exp $ */
/*
* Mesa 3-D graphics library
#include "texformat.h"
#include "teximage.h"
#include "texstate.h"
+#include "texstore.h"
#include "mtypes.h"
#include "swrast/s_span.h" /* XXX SWRAST hack */
#endif
#ifdef DEBUG
static void PrintTexture(const struct gl_texture_image *img)
{
+#if CHAN_TYPE == GL_FLOAT
+ _mesa_problem(NULL, "PrintTexture doesn't support float channels");
+#else
GLuint i, j, c;
const GLchan *data = (const GLchan *) img->Data;
}
printf("\n");
}
+#endif
}
#endif
static GLboolean
is_compressed_format(GLcontext *ctx, GLenum internalFormat)
{
- if (ctx->Driver.IsCompressedFormat) {
- return (*ctx->Driver.IsCompressedFormat)(ctx, internalFormat);
- }
- return GL_FALSE;
+ if (ctx->Driver.BaseCompressedTexFormat) {
+ GLint b = (*ctx->Driver.BaseCompressedTexFormat)(ctx, internalFormat);
+ if (b > 0)
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ }
+ return GL_FALSE;
}
* according to the target and level parameters.
* This was basically prompted by the introduction of cube maps.
*/
-static void
-set_tex_image(struct gl_texture_object *tObj,
- GLenum target, GLint level,
- struct gl_texture_image *texImage)
+void
+_mesa_set_tex_image(struct gl_texture_object *tObj,
+ GLenum target, GLint level,
+ struct gl_texture_image *texImage)
{
ASSERT(tObj);
ASSERT(texImage);
switch (target) {
+ case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
tObj->Image[level] = texImage;
return;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
tObj->NegZ[level] = texImage;
return;
default:
- _mesa_problem(NULL, "bad target in set_tex_image()");
+ _mesa_problem(NULL, "bad target in _mesa_set_tex_image()");
return;
}
}
GLenum target, GLint level)
{
ASSERT(texUnit);
+ ASSERT(level < MAX_TEXTURE_LEVELS);
switch (target) {
case GL_TEXTURE_1D:
return texUnit->Current1D->Image[level];
+#if 000 /* not used anymore */
/*
* glTexImage[123]D can accept a NULL image pointer. In this case we
* create a texture image with unspecified image contents per the OpenGL
const GLint numPixels = width * height * depth;
GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
+#ifdef DEBUG
/*
* Let's see if anyone finds this. If glTexImage2D() is called with
* a NULL image pointer then load the texture image with something
}
}
}
+#endif
return data;
}
+#endif
/*
* Initialize basic fields of the gl_texture_image struct.
*/
-static void
-init_teximage_fields(GLcontext *ctx,
- struct gl_texture_image *img,
- GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum internalFormat)
+void
+_mesa_init_teximage_fields(GLcontext *ctx,
+ struct gl_texture_image *img,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum internalFormat)
{
ASSERT(img);
img->Format = _mesa_base_tex_format( ctx, internalFormat );
+ ASSERT(img->Format > 0);
img->IntFormat = internalFormat;
img->Border = border;
img->Width = width;
{
GLboolean isProxy;
GLint iformat;
+ GLint maxLevels = 0, maxTextureSize;
if (dimensions == 1) {
isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_1D);
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
return GL_TRUE;
}
+ maxLevels = ctx->Const.MaxTextureLevels;
}
else if (dimensions == 2) {
isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_2D ||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
return GL_TRUE;
}
+ if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D)
+ maxLevels = ctx->Const.MaxTextureLevels;
+ else
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
}
else if (dimensions == 3) {
isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_3D);
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
return GL_TRUE;
}
+ maxLevels = ctx->Const.Max3DTextureLevels;
}
else {
_mesa_problem( ctx, "bad dims in texture_error_check" );
return GL_TRUE;
}
+ ASSERT(maxLevels > 0);
+ maxTextureSize = 1 << (maxLevels - 1);
+
/* Border */
if (border != 0 && border != 1) {
if (!isProxy) {
}
/* Width */
- if (width < 2 * border || width > 2 + ctx->Const.MaxTextureSize
+ if (width < 2 * border || width > 2 + maxTextureSize
|| logbase2( width - 2 * border ) < 0) {
if (!isProxy) {
char message[100];
/* Height */
if (dimensions >= 2) {
- if (height < 2 * border || height > 2 + ctx->Const.MaxTextureSize
+ if (height < 2 * border || height > 2 + maxTextureSize
|| logbase2( height - 2 * border ) < 0) {
if (!isProxy) {
char message[100];
/* Depth */
if (dimensions >= 3) {
- if (depth < 2 * border || depth > 2 + ctx->Const.MaxTextureSize
+ if (depth < 2 * border || depth > 2 + maxTextureSize
|| logbase2( depth - 2 * border ) < 0) {
if (!isProxy) {
char message[100];
}
/* Level */
- if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
+ if (level < 0 || level >= maxLevels) {
if (!isProxy) {
char message[100];
sprintf(message, "glTexImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
}
+ ASSERT(iformat > 0);
+
if (!is_compressed_format( ctx, internalFormat ) &&
!_mesa_is_legal_format_and_type( format, type )) {
/* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
{
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
struct gl_texture_image *destTex;
+ GLint maxLevels = 0;
+ GLboolean compressed;
if (dimensions == 1) {
if (target != GL_TEXTURE_1D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
return GL_TRUE;
}
+ maxLevels = ctx->Const.MaxTextureLevels;
}
else if (dimensions == 2) {
if (ctx->Extensions.ARB_texture_cube_map) {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
return GL_TRUE;
}
+ if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D)
+ maxLevels = ctx->Const.MaxTextureLevels;
+ else
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
}
else if (dimensions == 3) {
if (target != GL_TEXTURE_3D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
return GL_TRUE;
}
+ maxLevels = ctx->Const.Max3DTextureLevels;
}
else {
_mesa_problem( ctx, "bad dims in texture_error_check" );
return GL_TRUE;
}
- if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
+ ASSERT(maxLevels > 0);
+
+ if (level < 0 || level >= maxLevels) {
char message[100];
sprintf(message, "glTexSubImage2D(level=%d)", level);
_mesa_error(ctx, GL_INVALID_ENUM, message);
}
}
- if (!is_compressed_format(ctx, destTex->IntFormat) &&
- !_mesa_is_legal_format_and_type(format, type)) {
+ compressed = is_compressed_format(ctx, destTex->IntFormat);
+
+ if (!compressed && !_mesa_is_legal_format_and_type(format, type)) {
char message[100];
sprintf(message, "glTexSubImage%dD(format or type)", dimensions);
_mesa_error(ctx, GL_INVALID_ENUM, message);
return GL_TRUE;
}
+ if (compressed) {
+ if (xoffset != -((GLint)destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage1/2/3D(xoffset != -border");
+ return GL_TRUE;
+ }
+ if (dimensions > 1 && yoffset != -((GLint)destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage2/3D(yoffset != -border");
+ return GL_TRUE;
+ }
+ if (dimensions > 2 && zoffset != -((GLint)destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage3D(zoffset != -border");
+ return GL_TRUE;
+ }
+ }
+
return GL_FALSE;
}
GLint width, GLint height, GLint border )
{
GLint iformat;
+ GLint maxLevels = 0, maxTextureSize;
if (dimensions == 1) {
if (target != GL_TEXTURE_1D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
return GL_TRUE;
}
+ maxLevels = ctx->Const.MaxTextureLevels;
}
else if (dimensions == 2) {
if (ctx->Extensions.ARB_texture_cube_map) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
return GL_TRUE;
}
+ if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D)
+ maxLevels = ctx->Const.MaxTextureLevels;
+ else
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
}
+ ASSERT(maxLevels > 0);
+ maxTextureSize = 1 << (maxLevels - 1);
+
/* Border */
if (border != 0 && border != 1) {
char message[100];
}
/* Width */
- if (width < 2 * border || width > 2 + ctx->Const.MaxTextureSize
+ if (width < 2 * border || width > 2 + maxTextureSize
|| logbase2( width - 2 * border ) < 0) {
char message[100];
sprintf(message, "glCopyTexImage%dD(width=%d)", dimensions, width);
/* Height */
if (dimensions >= 2) {
- if (height < 2 * border || height > 2 + ctx->Const.MaxTextureSize
+ if (height < 2 * border || height > 2 + maxTextureSize
|| logbase2( height - 2 * border ) < 0) {
char message[100];
sprintf(message, "glCopyTexImage%dD(height=%d)", dimensions, height);
}
/* Level */
- if (level < 0 || level>=ctx->Const.MaxTextureLevels) {
+ if (level < 0 || level >= maxLevels) {
char message[100];
sprintf(message, "glCopyTexImage%dD(level=%d)", dimensions, level);
_mesa_error(ctx, GL_INVALID_VALUE, message);
return GL_TRUE;
}
- iformat = _mesa_base_tex_format( ctx, internalFormat );
+ iformat = _mesa_base_tex_format(ctx, internalFormat);
if (iformat < 0) {
char message[100];
sprintf(message, "glCopyTexImage%dD(internalFormat)", dimensions);
{
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
struct gl_texture_image *teximage;
+ GLint maxLevels = 0;
+ GLboolean compressed;
if (dimensions == 1) {
if (target != GL_TEXTURE_1D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
return GL_TRUE;
}
+ maxLevels = ctx->Const.MaxTextureLevels;
}
else if (dimensions == 2) {
if (ctx->Extensions.ARB_texture_cube_map) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
return GL_TRUE;
}
+ if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D)
+ maxLevels = ctx->Const.MaxTextureLevels;
+ else
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
}
else if (dimensions == 3) {
if (target != GL_TEXTURE_3D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
return GL_TRUE;
}
+ maxLevels = ctx->Const.Max3DTextureLevels;
}
- if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
+ ASSERT(maxLevels > 0);
+
+ if (level < 0 || level >= maxLevels) {
char message[100];
sprintf(message, "glCopyTexSubImage%dD(level=%d)", dimensions, level);
_mesa_error(ctx, GL_INVALID_VALUE, message);
}
}
+ compressed = is_compressed_format(ctx, teximage->IntFormat);
+ if (compressed) {
+ if (xoffset != -((GLint)teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage1/2/3D(xoffset != -border");
+ return GL_TRUE;
+ }
+ if (dimensions > 1 && yoffset != -((GLint)teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage2/3D(yoffset != -border");
+ return GL_TRUE;
+ }
+ if (dimensions > 2 && zoffset != -((GLint)teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage3D(zoffset != -border");
+ return GL_TRUE;
+ }
+ }
+
/* if we get here, the parameters are OK */
return GL_FALSE;
}
const struct gl_texture_unit *texUnit;
const struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ GLint maxLevels = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
+ texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!texObj || is_proxy_target(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
+ return;
+ }
+
+ if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (target == GL_TEXTURE_3D) {
+ maxLevels = ctx->Const.Max3DTextureLevels;
+ }
+ else {
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+
+ ASSERT(maxLevels > 0);
+
+ if (level < 0 || level >= maxLevels) {
_mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
return;
}
if (!pixels)
return;
- texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- if (!texObj || is_proxy_target(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
- return;
- }
-
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
if (!texImage) {
/* invalid mipmap level, not an error */
return;
}
- if (ctx->NewState & _NEW_PIXEL)
- _mesa_update_state(ctx);
-
- if (is_color_format(format) &&
- ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
- /* convert texture image to GL_RGBA, GL_FLOAT */
- GLint width = texImage->Width;
- GLint height = texImage->Height;
- GLint depth = texImage->Depth;
- GLint img, row;
- GLfloat *tmpImage, *convImage;
- tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
- if (!tmpImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
- return;
- }
- convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
- if (!convImage) {
- FREE(tmpImage);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
- return;
- }
-
- for (img = 0; img < depth; img++) {
- GLint convWidth, convHeight;
-
- /* convert texture data to GLfloat/GL_RGBA */
- for (row = 0; row < height; row++) {
- GLchan texels[1 << MAX_TEXTURE_LEVELS][4];
- GLint col;
- GLfloat *dst = tmpImage + row * width * 4;
- for (col = 0; col < width; col++) {
- (*texImage->FetchTexel)(texImage, col, row, img,
- texels[col]);
- }
- _mesa_unpack_float_color_span(ctx, width, GL_RGBA, dst,
- GL_RGBA, CHAN_TYPE, texels,
- &_mesa_native_packing,
- ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
- GL_FALSE);
- }
-
- convWidth = width;
- convHeight = height;
-
- /* convolve */
- if (target == GL_TEXTURE_1D) {
- if (ctx->Pixel.Convolution1DEnabled) {
- _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
- }
- }
- else {
- if (ctx->Pixel.Convolution2DEnabled) {
- _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
- tmpImage, convImage);
- }
- else if (ctx->Pixel.Separable2DEnabled) {
- _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
- tmpImage, convImage);
- }
- }
-
- /* pack convolved image */
- for (row = 0; row < convHeight; row++) {
- const GLfloat *src = convImage + row * convWidth * 4;
- GLvoid *dest = _mesa_image_address(&ctx->Pack, pixels,
- convWidth, convHeight,
- format, type, img, row, 0);
- _mesa_pack_float_rgba_span(ctx, convWidth,
- (const GLfloat(*)[4]) src,
- format, type, dest, &ctx->Pack,
- ctx->_ImageTransferState & IMAGE_POST_CONVOLUTION_BITS);
- }
- }
-
- FREE(tmpImage);
- FREE(convImage);
- }
- else {
- /* no convolution, or non-rgba image */
- GLint width = texImage->Width;
- GLint height = texImage->Height;
- GLint depth = texImage->Depth;
+ {
+ const GLint width = texImage->Width;
+ const GLint height = texImage->Height;
+ const GLint depth = texImage->Depth;
GLint img, row;
for (img = 0; img < depth; img++) {
for (row = 0; row < height; row++) {
}
_mesa_pack_index_span(ctx, width, type, dest,
indexRow, &ctx->Pack,
- ctx->_ImageTransferState);
+ 0 /* no image transfer */);
}
else if (format == GL_DEPTH_COMPONENT) {
GLfloat depthRow[MAX_WIDTH];
}
_mesa_pack_rgba_span(ctx, width, (const GLchan (*)[4])rgba,
format, type, dest, &ctx->Pack,
- ctx->_ImageTransferState);
+ 0 /* no image transfer */);
} /* format */
} /* row */
} /* img */
- } /* convolution */
+ }
}
texImage->Data = NULL;
}
clear_teximage_fields(texImage); /* not really needed, but helpful */
- init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
+ border, internalFormat);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
ASSERT(ctx->Driver.TexImage1D);
+
+#if 0 /* don't make default teximage anymore */
if (pixels) {
(*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
width, border, format, type, pixels,
FREE(dummy);
}
}
+#else
+ /* <pixels> may be null! */
+ (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
+ width, border, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
+#endif
ASSERT(texImage->TexFormat);
- texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
+ if (!texImage->FetchTexel) {
+ /* If driver didn't explicitly set this, use the default */
+ texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
+ }
ASSERT(texImage->FetchTexel);
+ if (texImage->IsCompressed) {
+ ASSERT(texImage->CompressedSize > 0);
+ }
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
struct gl_texture_image *texImage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
+ border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, format, type,
if (!texImage) {
texImage = _mesa_alloc_texture_image();
- set_tex_image(texObj, target, level, texImage);
+ _mesa_set_tex_image(texObj, target, level, texImage);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
return;
texImage->Data = NULL;
}
clear_teximage_fields(texImage); /* not really needed, but helpful */
- init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight,
+ 1, border, internalFormat);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
ASSERT(ctx->Driver.TexImage2D);
+
+#if 0 /* don't make default teximage anymore */
if (pixels) {
(*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
width, height, border, format, type, pixels,
FREE(dummy);
}
}
+#else
+ /* <pixels> may be null! */
+ (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
+ width, height, border, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
+#endif
ASSERT(texImage->TexFormat);
- texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
+ if (!texImage->FetchTexel) {
+ /* If driver didn't explicitly set this, use the default */
+ texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
+ }
ASSERT(texImage->FetchTexel);
+ if (texImage->IsCompressed) {
+ ASSERT(texImage->CompressedSize > 0);
+ }
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
- else if (target == GL_PROXY_TEXTURE_2D) {
+ else if (target == GL_PROXY_TEXTURE_2D ||
+ (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
+ ctx->Extensions.ARB_texture_cube_map)) {
/* Proxy texture: check for errors and update proxy state */
GLenum error = texture_error_check(ctx, target, level, internalFormat,
format, type, 2,
struct gl_texture_image *texImage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, postConvWidth,
+ postConvHeight, 1, border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, format, type,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
+ const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ?
+ ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
+ if (level >= 0 && level < maxLevels) {
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
}
}
* Note that width and height include the border.
*/
void
-_mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat,
+_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const GLvoid *pixels )
texImage->Data = NULL;
}
clear_teximage_fields(texImage); /* not really needed, but helpful */
- init_teximage_fields(ctx, texImage, width, height, depth, border,
- internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border,
+ internalFormat);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
ASSERT(ctx->Driver.TexImage3D);
+
+#if 0 /* don't make default teximage anymore */
if (pixels) {
(*ctx->Driver.TexImage3D)(ctx, target, level, (GLint) internalFormat,
width, height, depth, border,
FREE(dummy);
}
}
+#else
+ /* <pixels> may be null! */
+ (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
+ width, height, depth, border, format, type,
+ pixels, &ctx->Unpack, texObj, texImage);
+#endif
ASSERT(texImage->TexFormat);
- texImage->FetchTexel = texImage->TexFormat->FetchTexel3D;
+ if (!texImage->FetchTexel) {
+ /* If driver didn't explicitly set this, use the default */
+ texImage->FetchTexel = texImage->TexFormat->FetchTexel3D;
+ }
ASSERT(texImage->FetchTexel);
+ if (texImage->IsCompressed) {
+ ASSERT(texImage->CompressedSize > 0);
+ }
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
struct gl_texture_image *texImage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- init_teximage_fields(ctx, texImage, width, height, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
+ border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, format, type,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
+ if (level >= 0 && level < ctx->Const.Max3DTextureLevels) {
clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
}
}
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
/* XXX should test internal format */
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
/* XXX should test internal format */
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
if (is_color_format(internalFormat)) {
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
if (!texImage) {
texImage = _mesa_alloc_texture_image();
- set_tex_image(texObj, target, level, texImage);
+ _mesa_set_tex_image(texObj, target, level, texImage);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
return;
}
clear_teximage_fields(texImage); /* not really needed, but helpful */
- init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
+ border, internalFormat);
ASSERT(ctx->Driver.CopyTexImage1D);
x, y, width, border);
ASSERT(texImage->TexFormat);
- texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
+ if (!texImage->FetchTexel) {
+ /* If driver didn't explicitly set this, use the default */
+ texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
+ }
ASSERT(texImage->FetchTexel);
/* state update */
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
if (is_color_format(internalFormat)) {
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
if (!texImage) {
texImage = _mesa_alloc_texture_image();
- set_tex_image(texObj, target, level, texImage);
+ _mesa_set_tex_image(texObj, target, level, texImage);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
return;
}
clear_teximage_fields(texImage); /* not really needed, but helpful */
- init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, 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);
- texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
+ if (!texImage->FetchTexel) {
+ /* If driver didn't explicitly set this, use the default */
+ texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
+ }
ASSERT(texImage->FetchTexel);
/* state update */
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
/* XXX should test internal format */
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
/* XXX should test internal format */
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (ctx->NewState & _NEW_PIXEL)
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
/* XXX should test internal format */
texImage->Data = NULL;
}
- init_teximage_fields(ctx, texImage, width, 1, 1, border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, 1, 1,
+ border, internalFormat);
if (ctx->Extensions.ARB_texture_compression) {
ASSERT(ctx->Driver.CompressedTexImage1D);
struct gl_texture_image *texImage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- init_teximage_fields(ctx, texImage, width, 1, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, 1, 1,
+ border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, GL_NONE, GL_NONE,
}
}
else {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB(target)" );
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB(target)");
return;
}
}
texImage->Data = NULL;
}
- init_teximage_fields(ctx, texImage, width, height, 1, border,
- internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, height, 1, border,
+ internalFormat);
if (ctx->Extensions.ARB_texture_compression) {
ASSERT(ctx->Driver.CompressedTexImage2D);
struct gl_texture_image *texImage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- init_teximage_fields(ctx, texImage, width, height, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
+ border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, GL_NONE, GL_NONE,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
+ const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ?
+ ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
+ if (level >= 0 && level < maxLevels) {
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
}
}
}
else {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB(target)" );
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB(target)");
return;
}
}
texImage->Data = NULL;
}
- init_teximage_fields(ctx, texImage, width, height, depth, border,
- internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border,
+ internalFormat);
if (ctx->Extensions.ARB_texture_compression) {
ASSERT(ctx->Driver.CompressedTexImage3D);
struct gl_texture_image *texImage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- init_teximage_fields(ctx, texImage, width, height, depth,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
+ border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, GL_NONE, GL_NONE,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
+ if (level >= 0 && level < ctx->Const.Max3DTextureLevels) {
clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
}
}
}
else {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB(target)" );
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB(target)");
return;
}
}
const struct gl_texture_unit *texUnit;
const struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ GLint maxLevels;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)" );
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!texObj) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
+ return;
+ }
+
+ if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (target == GL_TEXTURE_3D) {
+ maxLevels = ctx->Const.Max3DTextureLevels;
+ }
+ else {
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+
+ ASSERT(maxLevels > 0);
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
return;
}
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-
if (!texImage) {
- /* invalid mipmap level */
+ /* probably invalid mipmap level */
_mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
return;
}