summaryrefslogtreecommitdiff
path: root/xc/extras/Mesa/src/teximage.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/extras/Mesa/src/teximage.c')
-rw-r--r--xc/extras/Mesa/src/teximage.c1181
1 files changed, 727 insertions, 454 deletions
diff --git a/xc/extras/Mesa/src/teximage.c b/xc/extras/Mesa/src/teximage.c
index 48cf19c68..1beccc5ce 100644
--- a/xc/extras/Mesa/src/teximage.c
+++ b/xc/extras/Mesa/src/teximage.c
@@ -1,7 +1,7 @@
/*
* Mesa 3-D graphics library
- * Version: 4.0.4
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -23,25 +23,20 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
-#ifdef PC_HEADER
-#include "all.h"
-#else
#include "glheader.h"
#include "context.h"
#include "convolve.h"
#include "image.h"
+#include "imports.h"
#include "macros.h"
-#include "mem.h"
#include "mmath.h"
#include "state.h"
+#include "texcompress.h"
#include "texformat.h"
#include "teximage.h"
#include "texstate.h"
#include "texstore.h"
#include "mtypes.h"
-#include "swrast/s_span.h" /* XXX SWRAST hack */
-#endif
/*
@@ -54,8 +49,8 @@
*/
-#ifdef DEBUG
-static void PrintTexture(const struct gl_texture_image *img)
+#if 0
+static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img)
{
#if CHAN_TYPE == GL_FLOAT
_mesa_problem(NULL, "PrintTexture doesn't support float channels");
@@ -64,7 +59,7 @@ static void PrintTexture(const struct gl_texture_image *img)
const GLchan *data = (const GLchan *) img->Data;
if (!data) {
- printf("No texture data\n");
+ _mesa_printf("No texture data\n");
return;
}
@@ -92,16 +87,16 @@ static void PrintTexture(const struct gl_texture_image *img)
for (i = 0; i < img->Height; i++) {
for (j = 0; j < img->Width; j++) {
if (c==1)
- printf("%02x ", data[0]);
+ _mesa_printf("%02x ", data[0]);
else if (c==2)
- printf("%02x%02x ", data[0], data[1]);
+ _mesa_printf("%02x%02x ", data[0], data[1]);
else if (c==3)
- printf("%02x%02x%02x ", data[0], data[1], data[2]);
+ _mesa_printf("%02x%02x%02x ", data[0], data[1], data[2]);
else if (c==4)
- printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]);
- data += c;
+ _mesa_printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]);
+ data += (img->RowStride - img->Width) * c;
}
- printf("\n");
+ _mesa_printf("\n");
}
#endif
}
@@ -142,6 +137,10 @@ logbase2( int n )
* Given an internal texture format enum or 1, 2, 3, 4 return the
* corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
* GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
+ *
+ * This is the format which is used during texture application (i.e. the
+ * texture format and env mode determine the arithmetic used.
+ *
* Return -1 if invalid enum.
*/
GLint
@@ -151,12 +150,6 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format )
* Ask the driver for the base format, if it doesn't
* know, it will return -1;
*/
- if (ctx->Driver.BaseCompressedTexFormat) {
- GLint ifmt = (*ctx->Driver.BaseCompressedTexFormat)(ctx, format);
- if (ifmt >= 0) {
- return ifmt;
- }
- }
switch (format) {
case GL_ALPHA:
case GL_ALPHA4:
@@ -213,7 +206,10 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format )
case GL_COLOR_INDEX8_EXT:
case GL_COLOR_INDEX12_EXT:
case GL_COLOR_INDEX16_EXT:
- return GL_COLOR_INDEX;
+ if (ctx->Extensions.EXT_paletted_texture)
+ return GL_COLOR_INDEX;
+ else
+ return -1;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16_SGIX:
case GL_DEPTH_COMPONENT24_SGIX:
@@ -222,6 +218,55 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format )
return GL_DEPTH_COMPONENT;
else
return -1;
+
+ /* GL_ARB_texture_compression */
+ case GL_COMPRESSED_ALPHA:
+ if (ctx->Extensions.ARB_texture_compression)
+ return GL_ALPHA;
+ else
+ return -1;
+ case GL_COMPRESSED_LUMINANCE:
+ if (ctx->Extensions.ARB_texture_compression)
+ return GL_LUMINANCE;
+ else
+ return -1;
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ if (ctx->Extensions.ARB_texture_compression)
+ return GL_LUMINANCE_ALPHA;
+ else
+ return -1;
+ case GL_COMPRESSED_INTENSITY:
+ if (ctx->Extensions.ARB_texture_compression)
+ return GL_INTENSITY;
+ else
+ return -1;
+ case GL_COMPRESSED_RGB:
+ if (ctx->Extensions.ARB_texture_compression)
+ return GL_RGB;
+ else
+ return -1;
+ case GL_COMPRESSED_RGBA:
+ if (ctx->Extensions.ARB_texture_compression)
+ return GL_RGBA;
+ else
+ return -1;
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ if (ctx->Extensions.TDFX_texture_compression_FXT1)
+ return GL_RGB;
+ else
+ return -1;
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ if (ctx->Extensions.TDFX_texture_compression_FXT1)
+ return GL_RGBA;
+ else
+ return -1;
+
+ case GL_YCBCR_MESA:
+ if (ctx->Extensions.MESA_ycbcr_texture)
+ return GL_YCBCR_MESA;
+ else
+ return -1;
+
default:
return -1; /* error */
}
@@ -279,6 +324,7 @@ is_color_format(GLenum format)
case GL_RGBA12:
case GL_RGBA16:
return GL_TRUE;
+ case GL_YCBCR_MESA: /* not considered to be RGB */
default:
return GL_FALSE;
}
@@ -303,25 +349,24 @@ is_index_format(GLenum format)
}
-/*
- * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
- * otherwise.
+/**
+ * Return GL_TRUE if internalFormat is a supported compressed format,
+ * return GL_FALSE otherwise.
+ * \param - internalFormat - the internal format token provided by the user
*/
static GLboolean
-is_compressed_format(GLcontext *ctx, GLenum internalFormat)
+is_compressed_format(GLenum internalFormat)
{
- if (ctx->Driver.BaseCompressedTexFormat) {
- GLint b = (*ctx->Driver.BaseCompressedTexFormat)(ctx, internalFormat);
- if (b > 0)
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
return GL_TRUE;
- else
+ default:
return GL_FALSE;
}
- return GL_FALSE;
}
-
/*
* Store a gl_texture_image pointer in a gl_texture_object structure
* according to the target and level parameters.
@@ -384,7 +429,7 @@ _mesa_alloc_texture_image( void )
void
_mesa_free_texture_image( struct gl_texture_image *teximage )
{
- if (teximage->Data) {
+ if (teximage->Data && !teximage->IsClientData) {
MESA_PBUFFER_FREE( teximage->Data );
teximage->Data = NULL;
}
@@ -532,6 +577,41 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
}
+/*
+ * Return the maximum number of allows mipmap levels for the given
+ * texture target.
+ */
+GLint
+_mesa_max_texture_levels(GLcontext *ctx, GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_2D:
+ return ctx->Const.MaxTextureLevels;
+ case GL_TEXTURE_3D:
+ case GL_PROXY_TEXTURE_3D:
+ return ctx->Const.Max3DTextureLevels;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ 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:
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ return ctx->Const.MaxCubeTextureLevels;
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ return 1;
+ break;
+ default:
+ return 0; /* bad target */
+ }
+}
+
+
#if 000 /* not used anymore */
/*
@@ -605,6 +685,7 @@ clear_teximage_fields(struct gl_texture_image *img)
img->Width = 0;
img->Height = 0;
img->Depth = 0;
+ img->RowStride = 0;
img->Width2 = 0;
img->Height2 = 0;
img->Depth2 = 0;
@@ -636,6 +717,7 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
img->Width = width;
img->Height = height;
img->Depth = depth;
+ img->RowStride = width;
img->WidthLog2 = logbase2(width - 2 * border);
if (height == 1) /* 1-D texture */
img->HeightLog2 = 0;
@@ -649,7 +731,13 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
img->Height2 = 1 << img->HeightLog2;
img->Depth2 = 1 << img->DepthLog2;
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
- img->IsCompressed = is_compressed_format(ctx, internalFormat);
+ img->IsCompressed = is_compressed_format(internalFormat);
+ if (img->IsCompressed)
+ img->CompressedSize = _mesa_compressed_texture_size(ctx, width, height,
+ depth, internalFormat);
+ else
+ img->CompressedSize = 0;
+
/* Compute Width/Height/DepthScale for mipmap lod computation */
if (target == GL_TEXTURE_RECTANGLE_NV) {
/* scale = 1.0 since texture coords directly map to texels */
@@ -661,7 +749,8 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
img->WidthScale = (GLfloat) img->Width;
img->HeightScale = (GLfloat) img->Height;
img->DepthScale = (GLfloat) img->Depth;
- }}
+ }
+}
@@ -680,7 +769,6 @@ texture_error_check( GLcontext *ctx, GLenum target,
GLint depth, GLint border )
{
GLboolean isProxy;
- GLint iformat;
GLint maxLevels = 0, maxTextureSize;
if (dimensions == 1) {
@@ -767,9 +855,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
/* Border */
if (border != 0 && border != 1) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(border=%d)", dimensions, border);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(border=%d)", dimensions, border);
}
return GL_TRUE;
}
@@ -783,9 +870,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
if (width < 1 || width > ctx->Const.MaxTextureRectSize) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(width=%d)", dimensions, width);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(width=%d)", dimensions, width);
}
return GL_TRUE;
}
@@ -793,9 +879,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
else if (width < 2 * border || width > 2 + maxTextureSize
|| logbase2( width - 2 * border ) < 0) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(width=%d)", dimensions, width);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(width=%d)", dimensions, width);
}
return GL_TRUE;
}
@@ -805,9 +890,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
if (height < 1 || height > ctx->Const.MaxTextureRectSize) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(height=%d)", dimensions, height);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(height=%d)", dimensions, height);
}
return GL_TRUE;
}
@@ -816,9 +900,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
if (height < 2 * border || height > 2 + maxTextureSize
|| logbase2( height - 2 * border ) < 0) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(height=%d)", dimensions, height);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(height=%d)", dimensions, height);
}
return GL_TRUE;
}
@@ -840,9 +923,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
if (depth < 2 * border || depth > 2 + maxTextureSize
|| logbase2( depth - 2 * border ) < 0) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage3D(depth=%d)", depth );
- _mesa_error( ctx, GL_INVALID_VALUE, message );
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glTexImage3D(depth=%d)", depth );
}
return GL_TRUE;
}
@@ -853,18 +935,16 @@ texture_error_check( GLcontext *ctx, GLenum target,
target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
if (level != 0) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(level=%d)", dimensions, level);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage2D(level=%d)", level);
}
return GL_TRUE;
}
}
else if (level < 0 || level >= maxLevels) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(level=%d)", dimensions, level);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(level=%d)", dimensions, level);
}
return GL_TRUE;
}
@@ -878,32 +958,85 @@ texture_error_check( GLcontext *ctx, GLenum target,
}
}
- iformat = _mesa_base_tex_format( ctx, internalFormat );
- if (iformat < 0) {
+ if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(internalFormat=0x%x)", dimensions,
- internalFormat);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(internalFormat=0x%x)",
+ dimensions, internalFormat);
}
return GL_TRUE;
}
- ASSERT(iformat > 0);
-
- if (!is_compressed_format( ctx, internalFormat ) &&
- !_mesa_is_legal_format_and_type( format, type )) {
+ if (!_mesa_is_legal_format_and_type(format, type)) {
/* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
* is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
*/
if (!isProxy) {
- char message[100];
- sprintf(message, "glTexImage%dD(format or type)", dimensions);
- _mesa_error(ctx, GL_INVALID_OPERATION, message);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%dD(format or type)", dimensions);
}
return GL_TRUE;
}
+ if (format == GL_YCBCR_MESA || internalFormat == GL_YCBCR_MESA) {
+ ASSERT(ctx->Extensions.MESA_ycbcr_texture);
+ if (format != GL_YCBCR_MESA ||
+ internalFormat != GL_YCBCR_MESA ||
+ (type != GL_UNSIGNED_SHORT_8_8_MESA &&
+ type != GL_UNSIGNED_SHORT_8_8_REV_MESA)) {
+ char message[100];
+ _mesa_sprintf(message,
+ "glTexImage%d(format/type/internalFormat YCBCR mismatch",
+ dimensions);
+ _mesa_error(ctx, GL_INVALID_ENUM, message);
+ return GL_TRUE; /* error */
+ }
+ if (target != GL_TEXTURE_2D &&
+ target != GL_PROXY_TEXTURE_2D &&
+ target != GL_TEXTURE_RECTANGLE_NV &&
+ target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
+ if (!isProxy)
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
+ return GL_TRUE;
+ }
+ if (border != 0) {
+ if (!isProxy) {
+ char message[100];
+ _mesa_sprintf(message,
+ "glTexImage%d(format=GL_YCBCR_MESA and border=%d)",
+ dimensions, border);
+ _mesa_error(ctx, GL_INVALID_VALUE, message);
+ }
+ return GL_TRUE;
+ }
+ }
+
+ if (is_compressed_format(internalFormat)) {
+ if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
+ /* OK */
+ }
+ else if (ctx->Extensions.ARB_texture_cube_map &&
+ (target == GL_PROXY_TEXTURE_CUBE_MAP ||
+ (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) {
+ /* OK */
+ }
+ else {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexImage%d(target)", dimensions);
+ return GL_TRUE;
+ }
+ }
+ if (border != 0) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%D(border!=0)", dimensions);
+ }
+ return GL_TRUE;
+ }
+ }
+
/* if we get here, the parameters are OK */
return GL_FALSE;
}
@@ -926,39 +1059,42 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
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) {
+ if (target == GL_TEXTURE_1D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else {
_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) {
- if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB ||
- target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) &&
- target != GL_TEXTURE_2D) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
- return GL_TRUE;
- }
+ if (ctx->Extensions.ARB_texture_cube_map &&
+ target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
}
- else if (target != GL_TEXTURE_2D) {
+ else if (ctx->Extensions.NV_texture_rectangle &&
+ target == GL_TEXTURE_RECTANGLE_NV) {
+ maxLevels = 1;
+ }
+ else if (target == GL_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else {
_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) {
+ if (target == GL_TEXTURE_3D) {
+ maxLevels = ctx->Const.Max3DTextureLevels;
+ }
+ else {
_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" );
@@ -968,28 +1104,22 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
ASSERT(maxLevels > 0);
if (level < 0 || level >= maxLevels) {
- char message[100];
- sprintf(message, "glTexSubImage2D(level=%d)", level);
- _mesa_error(ctx, GL_INVALID_ENUM, message);
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
return GL_TRUE;
}
if (width < 0) {
- char message[100];
- sprintf(message, "glTexSubImage%dD(width=%d)", dimensions, width);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexSubImage%dD(width=%d)", dimensions, width);
return GL_TRUE;
}
if (height < 0 && dimensions > 1) {
- char message[100];
- sprintf(message, "glTexSubImage%dD(height=%d)", dimensions, height);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexSubImage%dD(height=%d)", dimensions, height);
return GL_TRUE;
}
if (depth < 0 && dimensions > 2) {
- char message[100];
- sprintf(message, "glTexSubImage%dD(depth=%d)", dimensions, depth);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(depth=%d)", dimensions, depth);
return GL_TRUE;
}
@@ -1029,31 +1159,51 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
}
}
- 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);
+ if (!_mesa_is_legal_format_and_type(format, type)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexSubImage%dD(format or type)", dimensions);
return GL_TRUE;
}
- if (compressed) {
- if (xoffset != -((GLint)destTex->Border)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexSubImage1/2/3D(xoffset != -border");
+ if (destTex->IsCompressed) {
+ const struct gl_texture_unit *texUnit;
+ const struct gl_texture_object *texObj;
+ const struct gl_texture_image *texImage;
+ 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 (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
+ /* OK */
+ }
+ else if (ctx->Extensions.ARB_texture_cube_map &&
+ (target == GL_PROXY_TEXTURE_CUBE_MAP ||
+ (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) {
+ /* OK */
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexSubImage%D(target)", dimensions);
return GL_TRUE;
}
- if (dimensions > 1 && yoffset != -((GLint)destTex->Border)) {
+ /* offset must be multiple of 4 */
+ if ((xoffset & 3) || (yoffset & 3)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexSubImage2/3D(yoffset != -border");
+ "glTexSubImage%D(xoffset or yoffset)", dimensions);
return GL_TRUE;
}
- if (dimensions > 2 && zoffset != -((GLint)destTex->Border)) {
+ /* size must be multiple of 4 or equal to whole texture size */
+ if ((width & 3) && (GLuint) width != texImage->Width) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexSubImage3D(zoffset != -border");
+ "glTexSubImage%D(width)", dimensions);
return GL_TRUE;
- }
+ }
+ if ((height & 3) && (GLuint) height != texImage->Height) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage%D(width)", dimensions);
+ return GL_TRUE;
+ }
}
return GL_FALSE;
@@ -1070,7 +1220,6 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
GLenum target, GLint level, GLint internalFormat,
GLint width, GLint height, GLint border )
{
- GLint iformat;
GLint maxLevels = 0, maxTextureSize;
if (dimensions == 1) {
@@ -1111,18 +1260,16 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
/* Border */
if (border != 0 && border != 1) {
- char message[100];
- sprintf(message, "glCopyTexImage%dD(border)", dimensions);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(border)", dimensions);
return GL_TRUE;
}
/* Width */
if (width < 2 * border || width > 2 + maxTextureSize
|| logbase2( width - 2 * border ) < 0) {
- char message[100];
- sprintf(message, "glCopyTexImage%dD(width=%d)", dimensions, width);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(width=%d)", dimensions, width);
return GL_TRUE;
}
@@ -1130,9 +1277,8 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
if (dimensions >= 2) {
if (height < 2 * border || height > 2 + maxTextureSize
|| logbase2( height - 2 * border ) < 0) {
- char message[100];
- sprintf(message, "glCopyTexImage%dD(height=%d)", dimensions, height);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(height=%d)", dimensions, height);
return GL_TRUE;
}
}
@@ -1148,20 +1294,30 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
/* Level */
if (level < 0 || level >= maxLevels) {
- char message[100];
- sprintf(message, "glCopyTexImage%dD(level=%d)", dimensions, level);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
}
- iformat = _mesa_base_tex_format(ctx, internalFormat);
- if (iformat < 0) {
- char message[100];
- sprintf(message, "glCopyTexImage%dD(internalFormat)", dimensions);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ 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(internalFormat)) {
+ if (target != GL_TEXTURE_2D) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glCopyTexImage%d(target)", dimensions);
+ return GL_TRUE;
+ }
+ if (border != 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%D(border!=0)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
/* if we get here, the parameters are OK */
return GL_FALSE;
}
@@ -1176,7 +1332,6 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint 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) {
@@ -1198,7 +1353,7 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
return GL_TRUE;
}
- if (target == GL_TEXTURE_2D)
+ if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D)
maxLevels = ctx->Const.MaxTextureLevels;
else
maxLevels = ctx->Const.MaxCubeTextureLevels;
@@ -1214,93 +1369,95 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
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);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
}
if (width < 0) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(width=%d)", dimensions, width);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(width=%d)", dimensions, width);
return GL_TRUE;
}
if (dimensions > 1 && height < 0) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(height=%d)", dimensions, height);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(height=%d)", dimensions, height);
return GL_TRUE;
}
teximage = _mesa_select_tex_image(ctx, texUnit, target, level);
if (!teximage) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(undefined texture)", dimensions);
- _mesa_error(ctx, GL_INVALID_OPERATION, message);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage%dD(undefined texture level: %d)",
+ dimensions, level);
return GL_TRUE;
}
if (xoffset < -((GLint)teximage->Border)) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
return GL_TRUE;
}
if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(xoffset+width)", dimensions);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(xoffset+width)", dimensions);
return GL_TRUE;
}
if (dimensions > 1) {
if (yoffset < -((GLint)teximage->Border)) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
return GL_TRUE;
}
/* NOTE: we're adding the border here, not subtracting! */
if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(yoffset+height)", dimensions);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(yoffset+height)", dimensions);
return GL_TRUE;
}
}
if (dimensions > 2) {
if (zoffset < -((GLint)teximage->Border)) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(zoffset)", dimensions);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(zoffset)", dimensions);
return GL_TRUE;
}
if (zoffset > (GLint) (teximage->Depth + teximage->Border)) {
- char message[100];
- sprintf(message, "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
- _mesa_error(ctx, GL_INVALID_VALUE, message);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
return GL_TRUE;
}
}
- 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");
+ if (teximage->IsCompressed) {
+ if (target != GL_TEXTURE_2D) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glCopyTexSubImage%d(target)", dimensions);
return GL_TRUE;
}
- if (dimensions > 1 && yoffset != -((GLint)teximage->Border)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexSubImage2/3D(yoffset != -border");
+ /* offset must be multiple of 4 */
+ if ((xoffset & 3) || (yoffset & 3)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%D(xoffset or yoffset)", dimensions);
return GL_TRUE;
}
- if (dimensions > 2 && zoffset != -((GLint)teximage->Border)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexSubImage3D(zoffset != -border");
+ /* size must be multiple of 4 */
+ if ((width & 3) != 0 && (GLuint) width != teximage->Width) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%D(width)", dimensions);
return GL_TRUE;
- }
+ }
+ if ((height & 3) != 0 && (GLuint) height != teximage->Height) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%D(height)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ if (teximage->IntFormat == GL_YCBCR_MESA) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
+ return GL_TRUE;
}
/* if we get here, the parameters are OK */
@@ -1315,7 +1472,7 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
{
const struct gl_texture_unit *texUnit;
const struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
+ const struct gl_texture_image *texImage;
GLint maxLevels = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -1327,20 +1484,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
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 if (target == GL_TEXTURE_RECTANGLE_NV) {
- maxLevels = 1;
- }
- else {
- maxLevels = ctx->Const.MaxCubeTextureLevels;
- }
-
- ASSERT(maxLevels > 0);
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
if (level < 0 || level >= maxLevels) {
_mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
@@ -1366,6 +1511,10 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
}
+ if (!ctx->Extensions.MESA_ycbcr_texture && format == GL_YCBCR_MESA) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ }
+
/* XXX what if format/type doesn't match texture format/type? */
if (!pixels)
@@ -1390,7 +1539,7 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
for (img = 0; img < depth; img++) {
for (row = 0; row < height; row++) {
/* compute destination address in client memory */
- GLvoid *dest = _mesa_image_address( &ctx->Unpack, pixels,
+ GLvoid *dest = _mesa_image_address( &ctx->Pack, pixels,
width, height, format, type,
img, row, 0);
assert(dest);
@@ -1416,6 +1565,24 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
_mesa_pack_depth_span(ctx, width, dest, type,
depthRow, &ctx->Pack);
}
+ else if (format == GL_YCBCR_MESA) {
+ /* No pixel transfer */
+ const GLint rowstride = texImage->RowStride;
+ MEMCPY(dest,
+ (const GLushort *) texImage->Data + row * rowstride,
+ width * sizeof(GLushort));
+ /* check for byte swapping */
+ if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
+ && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
+ (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
+ && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
+ if (!ctx->Pack.SwapBytes)
+ _mesa_swap2((GLushort *) dest, width);
+ }
+ else if (ctx->Pack.SwapBytes) {
+ _mesa_swap2((GLushort *) dest, width);
+ }
+ }
else {
/* general case: convert row to RGBA format */
GLchan rgba[MAX_WIDTH][4];
@@ -1473,13 +1640,14 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
return;
}
}
- else if (texImage->Data) {
+ else if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
MESA_PBUFFER_FREE(texImage->Data);
- texImage->Data = NULL;
}
+ texImage->Data = NULL;
clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, 1, 1,
border, internalFormat);
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
@@ -1487,28 +1655,10 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
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,
- &ctx->Unpack, texObj, texImage);
- }
- else {
- GLubyte *dummy = make_null_texture(width, 1, 1, format);
- if (dummy) {
- (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
- width, border,
- format, GL_UNSIGNED_BYTE, dummy,
- &_mesa_native_packing, texObj, texImage);
- FREE(dummy);
- }
- }
-#else
- /* <pixels> may be null! */
+ /* 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);
-#endif
ASSERT(texImage->TexFormat);
if (!texImage->FetchTexel) {
@@ -1517,26 +1667,15 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
}
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_1D) {
/* Proxy texture: check for errors and update proxy state */
- GLenum error = texture_error_check(ctx, target, level, internalFormat,
- format, type, 1,
- postConvWidth, 1, 1, border);
+ GLboolean error = texture_error_check(ctx, target, level, internalFormat,
+ format, type, 1, postConvWidth, 1, 1, border);
if (!error) {
- struct gl_texture_unit *texUnit;
- struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
- border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, format, type,
@@ -1548,6 +1687,16 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]);
}
}
+ else {
+ /* no error, set the tex image parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, 1, 1,
+ border, internalFormat);
+ }
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
@@ -1600,43 +1749,25 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
return;
}
}
- else if (texImage->Data) {
+ else if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
MESA_PBUFFER_FREE(texImage->Data);
- texImage->Data = NULL;
}
+ texImage->Data = NULL;
clear_teximage_fields(texImage); /* not really needed, but helpful */
_mesa_init_teximage_fields(ctx, target, texImage,
- postConvWidth, postConvHeight,
- 1, border, internalFormat);
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
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,
- &ctx->Unpack, texObj, texImage);
- }
- else {
- GLubyte *dummy = make_null_texture(width, height, 1, format);
- if (dummy) {
- (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
- width, height, border,
- format, GL_UNSIGNED_BYTE, dummy,
- &_mesa_native_packing, texObj, texImage);
- FREE(dummy);
- }
- }
-#else
- /* <pixels> may be null! */
+ /* 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);
-#endif
ASSERT(texImage->TexFormat);
if (!texImage->FetchTexel) {
@@ -1645,10 +1776,6 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
}
ASSERT(texImage->FetchTexel);
- if (texImage->IsCompressed) {
- ASSERT(texImage->CompressedSize > 0);
- }
-
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
@@ -1659,16 +1786,9 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
(target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
ctx->Extensions.NV_texture_rectangle)) {
/* Proxy texture: check for errors and update proxy state */
- GLenum error = texture_error_check(ctx, target, level, internalFormat,
- format, type, 2,
- postConvWidth, postConvHeight, 1, border);
+ GLboolean error = texture_error_check(ctx, target, level, internalFormat,
+ format, type, 2, postConvWidth, postConvHeight, 1, border);
if (!error) {
- struct gl_texture_unit *texUnit;
- struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth,
- postConvHeight, 1, border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, format, type,
@@ -1682,6 +1802,16 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
}
}
+ else {
+ /* no error, set the tex image parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+ }
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
@@ -1695,7 +1825,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
* 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 )
@@ -1725,12 +1855,13 @@ _mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat,
return;
}
}
- else if (texImage->Data) {
+ else if (texImage->Data && !texImage->IsClientData) {
MESA_PBUFFER_FREE(texImage->Data);
- texImage->Data = NULL;
}
+ texImage->Data = NULL;
clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ width, height, depth,
border, internalFormat);
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
@@ -1738,30 +1869,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat,
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,
- format, type, pixels,
- &ctx->Unpack, texObj, texImage);
- }
- else {
- GLubyte *dummy = make_null_texture(width, height, depth, format);
- if (dummy) {
- (*ctx->Driver.TexImage3D)(ctx, target, level,
- (GLint) internalFormat,
- width, height, depth, border,
- format, GL_UNSIGNED_BYTE, dummy,
- &_mesa_native_packing, texObj, texImage);
- FREE(dummy);
- }
- }
-#else
- /* <pixels> may be null! */
+ /* 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);
-#endif
ASSERT(texImage->TexFormat);
if (!texImage->FetchTexel) {
@@ -1770,25 +1881,15 @@ _mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat,
}
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_3D) {
/* Proxy texture: check for errors and update proxy state */
- GLenum error = texture_error_check(ctx, target, level, internalFormat,
+ GLboolean error = texture_error_check(ctx, target, level, internalFormat,
format, type, 3, width, height, depth, border);
if (!error) {
- struct gl_texture_unit *texUnit;
- struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
- border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, format, type,
@@ -1800,6 +1901,15 @@ _mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat,
clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
}
}
+ else {
+ /* no error, set the tex image parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+ border, internalFormat);
+ }
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
@@ -1814,7 +1924,7 @@ _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
GLint border, GLenum format, GLenum type,
const GLvoid *pixels )
{
- _mesa_TexImage3D(target, level, internalFormat, width, height,
+ _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
depth, border, format, type, pixels);
}
@@ -1994,11 +2104,11 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
return;
}
}
- else if (texImage->Data) {
+ else if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
MESA_PBUFFER_FREE(texImage->Data);
- texImage->Data = NULL;
}
+ texImage->Data = NULL;
clear_teximage_fields(texImage); /* not really needed, but helpful */
_mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
@@ -2058,11 +2168,11 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
return;
}
}
- else if (texImage->Data) {
+ else if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
MESA_PBUFFER_FREE(texImage->Data);
- texImage->Data = NULL;
}
+ texImage->Data = NULL;
clear_teximage_fields(texImage); /* not really needed, but helpful */
_mesa_init_teximage_fields(ctx, target, texImage,
@@ -2200,6 +2310,176 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
+
+/**********************************************************************/
+/****** Compressed Textures ******/
+/**********************************************************************/
+
+
+/**
+ * Error checking for glCompressedTexImage[123]D().
+ * \return error code or GL_NO_ERROR.
+ */
+static GLenum
+compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
+ GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize)
+{
+ GLboolean isProxy = GL_FALSE;
+ GLint expectedSize, maxLevels = 0, maxTextureSize;
+
+ if (dimensions == 1) {
+ /* 1D compressed textures not allowed */
+ return GL_INVALID_ENUM;
+ }
+ else if (dimensions == 2) {
+ if (target == GL_PROXY_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ isProxy = GL_TRUE;
+ }
+ else if (target == GL_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ return GL_INVALID_ENUM; /*target*/
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ isProxy = GL_TRUE;
+ }
+ else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ return GL_INVALID_ENUM; /*target*/
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+ else {
+ return GL_INVALID_ENUM; /*target*/
+ }
+ }
+ else if (dimensions == 3) {
+ /* 3D compressed textures not allowed */
+ return GL_INVALID_ENUM;
+ }
+
+ maxTextureSize = 1 << (maxLevels - 1);
+
+ if (!is_compressed_format(internalFormat))
+ return GL_INVALID_ENUM;
+
+ if (border != 0)
+ return GL_INVALID_VALUE;
+
+ if (width < 1 || width > maxTextureSize || logbase2(width) < 0)
+ return GL_INVALID_VALUE;
+
+ if ((height < 1 || height > maxTextureSize || logbase2(height) < 0)
+ && dimensions > 1)
+ return GL_INVALID_VALUE;
+
+ if ((depth < 1 || depth > maxTextureSize || logbase2(depth) < 0)
+ && dimensions > 2)
+ return GL_INVALID_VALUE;
+
+ /* For cube map, width must equal height */
+ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height)
+ return GL_INVALID_VALUE;
+
+ if (level < 0 || level >= maxLevels)
+ return GL_INVALID_VALUE;
+
+ expectedSize = _mesa_compressed_texture_size(ctx, width, height, depth,
+ internalFormat);
+ if (expectedSize != imageSize)
+ return GL_INVALID_VALUE;
+
+ return GL_NO_ERROR;
+}
+
+
+/**
+ * Error checking for glCompressedTexSubImage[123]D().
+ * \return error code or GL_NO_ERROR.
+ */
+static GLenum
+compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize)
+{
+ GLboolean isProxy = GL_FALSE;
+ GLint expectedSize, maxLevels = 0, maxTextureSize;
+
+ if (dimensions == 1) {
+ /* 1D compressed textures not allowed */
+ return GL_INVALID_ENUM;
+ }
+ else if (dimensions == 2) {
+ if (target == GL_PROXY_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ isProxy = GL_TRUE;
+ }
+ else if (target == GL_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ return GL_INVALID_ENUM; /*target*/
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ isProxy = GL_TRUE;
+ }
+ else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ return GL_INVALID_ENUM; /*target*/
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+ else {
+ return GL_INVALID_ENUM; /*target*/
+ }
+ }
+ else if (dimensions == 3) {
+ /* 3D compressed textures not allowed */
+ return GL_INVALID_ENUM;
+ }
+
+ maxTextureSize = 1 << (maxLevels - 1);
+
+ if (!is_compressed_format(format))
+ return GL_INVALID_ENUM;
+
+ if (width < 1 || width > maxTextureSize || logbase2(width) < 0)
+ return GL_INVALID_VALUE;
+
+ if ((height < 1 || height > maxTextureSize || logbase2(height) < 0)
+ && dimensions > 1)
+ return GL_INVALID_VALUE;
+
+ if (level < 0 || level >= maxLevels)
+ return GL_INVALID_VALUE;
+
+ if ((xoffset & 3) != 0 || (yoffset & 3) != 0)
+ return GL_INVALID_VALUE;
+
+ if ((width & 3) != 0 && width != 2 && width != 1)
+ return GL_INVALID_VALUE;
+
+ if ((height & 3) != 0 && height != 2 && height != 1)
+ return GL_INVALID_VALUE;
+
+ expectedSize = _mesa_compressed_texture_size(ctx, width, height, depth,
+ format);
+ if (expectedSize != imageSize)
+ return GL_INVALID_VALUE;
+
+ return GL_NO_ERROR;
+}
+
+
+
void
_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
GLenum internalFormat, GLsizei width,
@@ -2209,28 +2489,15 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- switch (internalFormat) {
- case GL_COMPRESSED_ALPHA_ARB:
- case GL_COMPRESSED_LUMINANCE_ARB:
- case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
- case GL_COMPRESSED_INTENSITY_ARB:
- case GL_COMPRESSED_RGB_ARB:
- case GL_COMPRESSED_RGBA_ARB:
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB");
- return;
- default:
- /* silence compiler warning */
- ;
- }
-
if (target == GL_TEXTURE_1D) {
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
-
- if (texture_error_check(ctx, target, level, internalFormat,
- GL_NONE, GL_NONE, 1, width, 1, 1, border)) {
- return; /* error in texture image was detected */
+ GLenum error = compressed_texture_error_check(ctx, 1, target, level,
+ internalFormat, width, 1, 1, border, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexImage1D");
+ return;
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -2241,26 +2508,23 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
texImage = _mesa_alloc_texture_image();
texObj->Image[level] = texImage;
if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
return;
}
}
- else if (texImage->Data) {
+ else if (texImage->Data && !texImage->IsClientData) {
MESA_PBUFFER_FREE(texImage->Data);
- texImage->Data = NULL;
}
+ texImage->Data = NULL;
_mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
border, internalFormat);
- if (ctx->Extensions.ARB_texture_compression) {
- ASSERT(ctx->Driver.CompressedTexImage1D);
- (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
- internalFormat, width, border,
- imageSize, data,
- texObj, texImage);
- ASSERT(texImage->CompressedSize > 0); /* sanity */
- }
+ ASSERT(ctx->Driver.CompressedTexImage1D);
+ (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
+ internalFormat, width, border,
+ imageSize, data,
+ texObj, texImage);
/* state update */
texObj->Complete = GL_FALSE;
@@ -2268,15 +2532,9 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
}
else if (target == GL_PROXY_TEXTURE_1D) {
/* Proxy texture: check for errors and update proxy state */
- GLenum error = texture_error_check(ctx, target, level, internalFormat,
- GL_NONE, GL_NONE, 1, width, 1, 1, border);
+ GLenum error = compressed_texture_error_check(ctx, 1, target, level,
+ internalFormat, width, 1, 1, border, imageSize);
if (!error) {
- struct gl_texture_unit *texUnit;
- struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
- border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, GL_NONE, GL_NONE,
@@ -2288,9 +2546,18 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]);
}
}
+ else {
+ /* store the teximage parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
+ border, internalFormat);
+ }
}
else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB(target)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)");
return;
}
}
@@ -2305,33 +2572,18 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- switch (internalFormat) {
- case GL_COMPRESSED_ALPHA_ARB:
- case GL_COMPRESSED_LUMINANCE_ARB:
- case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
- case GL_COMPRESSED_INTENSITY_ARB:
- case GL_COMPRESSED_RGB_ARB:
- case GL_COMPRESSED_RGBA_ARB:
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB");
- return;
- default:
- /* silence compiler warning */
- ;
- }
-
if (target == GL_TEXTURE_2D ||
(ctx->Extensions.ARB_texture_cube_map &&
target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
- target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) ||
- (ctx->Extensions.NV_texture_rectangle &&
- target == GL_TEXTURE_RECTANGLE_NV)) {
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
-
- if (texture_error_check(ctx, target, level, internalFormat,
- GL_NONE, GL_NONE, 2, width, height, 1, border)) {
- return; /* error in texture image was detected */
+ GLenum error = compressed_texture_error_check(ctx, 2, target, level,
+ internalFormat, width, height, 1, border, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexImage2D");
+ return;
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -2342,42 +2594,35 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
texImage = _mesa_alloc_texture_image();
texObj->Image[level] = texImage;
if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
return;
}
}
- else if (texImage->Data) {
+ else if (texImage->Data && !texImage->IsClientData) {
MESA_PBUFFER_FREE(texImage->Data);
- texImage->Data = NULL;
}
+ texImage->Data = NULL;
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
border, internalFormat);
- if (ctx->Extensions.ARB_texture_compression) {
- ASSERT(ctx->Driver.CompressedTexImage2D);
- (*ctx->Driver.CompressedTexImage2D)(ctx, target, level,
- internalFormat, width, height,
- border, imageSize, data,
- texObj, texImage);
- ASSERT(texImage->CompressedSize > 0); /* sanity */
- }
+ 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;
}
- 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,
- GL_NONE, GL_NONE, 2, width, height, 1, border);
+ GLenum error = compressed_texture_error_check(ctx, 2, target, level,
+ internalFormat, width, height, 1, border, imageSize);
if (!error) {
- struct gl_texture_unit *texUnit;
- struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
- border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, GL_NONE, GL_NONE,
@@ -2391,9 +2636,18 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
}
}
+ else {
+ /* store the teximage parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+ border, internalFormat);
+ }
}
else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB(target)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)");
return;
}
}
@@ -2408,28 +2662,15 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- switch (internalFormat) {
- case GL_COMPRESSED_ALPHA_ARB:
- case GL_COMPRESSED_LUMINANCE_ARB:
- case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
- case GL_COMPRESSED_INTENSITY_ARB:
- case GL_COMPRESSED_RGB_ARB:
- case GL_COMPRESSED_RGBA_ARB:
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB");
- return;
- default:
- /* silence compiler warning */
- ;
- }
-
if (target == GL_TEXTURE_3D) {
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
-
- if (texture_error_check(ctx, target, level, internalFormat,
- GL_NONE, GL_NONE, 3, width, height, depth, border)) {
- return; /* error in texture image was detected */
+ GLenum error = compressed_texture_error_check(ctx, 3, target, level,
+ internalFormat, width, height, depth, border, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexImage3D");
+ return;
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -2440,27 +2681,24 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
texImage = _mesa_alloc_texture_image();
texObj->Image[level] = texImage;
if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
return;
}
}
- else if (texImage->Data) {
+ else if (texImage->Data && !texImage->IsClientData) {
MESA_PBUFFER_FREE(texImage->Data);
- texImage->Data = NULL;
}
+ texImage->Data = NULL;
_mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
border, internalFormat);
- if (ctx->Extensions.ARB_texture_compression) {
- ASSERT(ctx->Driver.CompressedTexImage3D);
- (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
- internalFormat,
- width, height, depth,
- border, imageSize, data,
- texObj, texImage);
- ASSERT(texImage->CompressedSize > 0); /* sanity */
- }
+ 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;
@@ -2468,16 +2706,9 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
}
else if (target == GL_PROXY_TEXTURE_3D) {
/* Proxy texture: check for errors and update proxy state */
- GLenum error = texture_error_check(ctx, target, level, internalFormat,
- GL_NONE, GL_NONE, 3, width, height, depth, border);
+ GLenum error = compressed_texture_error_check(ctx, 3, target, level,
+ internalFormat, width, height, depth, border, imageSize);
if (!error) {
- struct gl_texture_unit *texUnit;
- struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, depth,
- border, internalFormat);
ASSERT(ctx->Driver.TestProxyTexImage);
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
internalFormat, GL_NONE, GL_NONE,
@@ -2489,9 +2720,18 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
}
}
+ else {
+ /* store the teximage parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height,
+ depth, border, internalFormat);
+ }
}
else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB(target)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)");
return;
}
}
@@ -2505,12 +2745,15 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
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);
- if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
- width, 1, 1, format, GL_NONE)) {
- return; /* error was detected */
+ error = compressed_subtexture_error_check(ctx, 1, target, level,
+ xoffset, 0, 0, width, 1, 1, format, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexSubImage1D");
+ return;
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -2518,6 +2761,17 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
assert(texImage);
+ if ((GLint) format != texImage->IntFormat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTexSubImage1D(format)");
+ return;
+ }
+
+ if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)");
+ return;
+ }
+
if (width == 0 || !data)
return; /* no-op, not an error */
@@ -2540,12 +2794,15 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
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);
- if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
- width, height, 1, format, GL_NONE)) {
- return; /* error was detected */
+ error = compressed_subtexture_error_check(ctx, 2, target, level,
+ xoffset, yoffset, 0, width, height, 1, format, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexSubImage2D");
+ return;
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -2553,6 +2810,18 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
assert(texImage);
+ if ((GLint) format != texImage->IntFormat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTexSubImage2D(format)");
+ return;
+ }
+
+ 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)");
+ return;
+ }
+
if (width == 0 || height == 0 || !data)
return; /* no-op, not an error */
@@ -2575,12 +2844,15 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
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);
- if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
- width, height, depth, format, GL_NONE)) {
- return; /* error was detected */
+ error = compressed_subtexture_error_check(ctx, 3, target, level,
+ xoffset, yoffset, zoffset, width, height, depth, format, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexSubImage2D");
+ return;
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -2588,6 +2860,19 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
assert(texImage);
+ if ((GLint) format != texImage->IntFormat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTexSubImage3D(format)");
+ return;
+ }
+
+ 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)");
+ return;
+ }
+
if (width == 0 || height == 0 || depth == 0 || !data)
return; /* no-op, not an error */
@@ -2619,17 +2904,8 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
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);
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
if (level < 0 || level >= maxLevels) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
@@ -2656,9 +2932,6 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
if (!img)
return;
- if (ctx->Extensions.ARB_texture_compression) {
- ASSERT(ctx->Driver.GetCompressedTexImage);
- (*ctx->Driver.GetCompressedTexImage)(ctx, target, level, img, texObj,
- texImage);
- }
+ /* just memcpy, no pixelstore or pixel transfer */
+ MEMCPY(img, texImage->Data, texImage->CompressedSize);
}