/*
- * Mesa 3-D graphics library
- * Version: 6.5.1
+ * mesa 3-D graphics library
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#include "glheader.h"
#include "bufferobj.h"
#include "context.h"
+#if FEATURE_convolve
#include "convolve.h"
+#endif
#include "fbobject.h"
#include "framebuffer.h"
#include "image.h"
}
}
- if (ctx->Extensions.SGIX_depth_texture ||
- ctx->Extensions.ARB_depth_texture) {
+ if (ctx->Extensions.ARB_depth_texture) {
switch (internalFormat) {
case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16_SGIX:
- case GL_DEPTH_COMPONENT24_SGIX:
- case GL_DEPTH_COMPONENT32_SGIX:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
return GL_DEPTH_COMPONENT;
default:
; /* fallthrough */
* index, depth, stencil, etc).
* \param format the image format value (may by an internal texture format)
* \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
+ * XXX maybe move this func to image.c
*/
-static GLboolean
-is_color_format(GLenum format)
+GLboolean
+_mesa_is_color_format(GLenum format)
{
switch (format) {
case GL_RED:
#endif /* FEATURE_EXT_texture_sRGB */
return GL_TRUE;
case GL_YCBCR_MESA: /* not considered to be RGB */
+ /* fall-through */
default:
return GL_FALSE;
}
is_depth_format(GLenum format)
{
switch (format) {
- case GL_DEPTH_COMPONENT16_ARB:
- case GL_DEPTH_COMPONENT24_ARB:
- case GL_DEPTH_COMPONENT32_ARB:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
case GL_DEPTH_COMPONENT:
return GL_TRUE;
default:
}
-static GLuint
-texture_face(GLenum target)
+/**
+ * For cube map faces, return a face index in [0,5].
+ * For other targets return 0;
+ */
+GLuint
+_mesa_tex_target_to_face(GLenum target)
{
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
{
ASSERT(tObj);
ASSERT(texImage);
+ /* XXX simplify this with _mesa_tex_target_to_face() */
switch (target) {
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_1D:
return texUnit->Current1D;
case GL_PROXY_TEXTURE_1D:
- return ctx->Texture.Proxy1D;
+ return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
case GL_TEXTURE_2D:
return texUnit->Current2D;
case GL_PROXY_TEXTURE_2D:
- return ctx->Texture.Proxy2D;
+ return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
case GL_TEXTURE_3D:
return texUnit->Current3D;
case GL_PROXY_TEXTURE_3D:
- return ctx->Texture.Proxy3D;
+ return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
? texUnit->CurrentCubeMap : NULL;
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
return ctx->Extensions.ARB_texture_cube_map
- ? ctx->Texture.ProxyCubeMap : NULL;
+ ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
case GL_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle
? texUnit->CurrentRect : NULL;
case GL_PROXY_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle
- ? ctx->Texture.ProxyRect : NULL;
+ ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
case GL_TEXTURE_1D_ARRAY_EXT:
return ctx->Extensions.MESA_texture_array
? texUnit->Current1DArray : NULL;
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
return ctx->Extensions.MESA_texture_array
- ? ctx->Texture.Proxy1DArray : NULL;
+ ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
case GL_TEXTURE_2D_ARRAY_EXT:
return ctx->Extensions.MESA_texture_array
? texUnit->Current2DArray : NULL;
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
return ctx->Extensions.MESA_texture_array
- ? ctx->Texture.Proxy2DArray : NULL;
+ ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
default:
_mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
return NULL;
if (level < 0 || level >= MAX_TEXTURE_LEVELS)
return NULL;
+ /* XXX simplify this with _mesa_tex_target_to_face() */
switch (target) {
case GL_TEXTURE_1D:
case GL_PROXY_TEXTURE_1D:
case GL_PROXY_TEXTURE_1D:
if (level >= ctx->Const.MaxTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy1D->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy1D->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy1D;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_2D:
if (level >= ctx->Const.MaxTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy2D->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy2D->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy2D;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_3D:
if (level >= ctx->Const.Max3DTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy3D->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy3D->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy3D;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_CUBE_MAP:
if (level >= ctx->Const.MaxCubeTextureLevels)
return NULL;
- texImage = ctx->Texture.ProxyCubeMap->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.ProxyCubeMap->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.ProxyCubeMap;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_RECTANGLE_NV:
if (level > 0)
return NULL;
- texImage = ctx->Texture.ProxyRect->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.ProxyRect->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.ProxyRect;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
if (level >= ctx->Const.MaxTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy1DArray->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy1DArray->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy1DArray;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
if (level >= ctx->Const.MaxTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy2DArray->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy2DArray->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy2DArray;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX];
}
return texImage;
default:
img->Width = width;
img->Height = height;
img->Depth = depth;
+
img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
- img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
- img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
img->WidthLog2 = logbase2(img->Width2);
- if (height == 1) /* 1-D texture */
+
+ if (height == 1) { /* 1-D texture */
+ img->Height2 = 1;
img->HeightLog2 = 0;
- else
+ }
+ else {
+ img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
img->HeightLog2 = logbase2(img->Height2);
- if (depth == 1) /* 2-D texture */
+ }
+
+ if (depth == 1) { /* 2-D texture */
+ img->Depth2 = 1;
img->DepthLog2 = 0;
- else
+ }
+ else {
+ img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
img->DepthLog2 = logbase2(img->Depth2);
+ }
+
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
+
img->IsCompressed = GL_FALSE;
img->CompressedSize = 0;
- if ((width == 1 || _mesa_bitcount(img->Width2) == 1) &&
- (height == 1 || _mesa_bitcount(img->Height2) == 1) &&
- (depth == 1 || _mesa_bitcount(img->Depth2) == 1))
+ if ((width == 1 || _mesa_is_pow_two(img->Width2)) &&
+ (height == 1 || _mesa_is_pow_two(img->Height2)) &&
+ (depth == 1 || _mesa_is_pow_two(img->Depth2)))
img->_IsPowerOfTwo = GL_TRUE;
else
img->_IsPowerOfTwo = GL_FALSE;
* A hardware driver might override this function if, for example, the
* max 3D texture size is 512x512x64 (i.e. not a cube).
*
+ * Note that width, height, depth == 0 is not an error. However, a
+ * texture with zero width/height/depth will be considered "incomplete"
+ * and texturing will effectively be disabled.
+ *
* \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
* GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
* GL_PROXY_TEXTURE_CUBE_MAP_ARB.
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
if (width < 2 * border || width > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(width - 2 * border) != 1) ||
+ width >0 && !_mesa_is_pow_two(width - 2 * border)) ||
level >= ctx->Const.MaxTextureLevels) {
/* bad width or level */
return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
if (width < 2 * border || width > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(width - 2 * border) != 1) ||
+ width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
height < 2 * border || height > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(height - 2 * border) != 1) ||
+ height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
level >= ctx->Const.MaxTextureLevels) {
/* bad width or height or level */
return GL_FALSE;
maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
if (width < 2 * border || width > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(width - 2 * border) != 1) ||
+ width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
height < 2 * border || height > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(height - 2 * border) != 1) ||
+ height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
depth < 2 * border || depth > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(depth - 2 * border) != 1) ||
+ depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) ||
level >= ctx->Const.Max3DTextureLevels) {
/* bad width or height or depth or level */
return GL_FALSE;
}
return GL_TRUE;
case GL_PROXY_TEXTURE_RECTANGLE_NV:
- if (width < 1 || width > ctx->Const.MaxTextureRectSize ||
- height < 1 || height > ctx->Const.MaxTextureRectSize ||
+ if (width < 0 || width > ctx->Const.MaxTextureRectSize ||
+ height < 0 || height > ctx->Const.MaxTextureRectSize ||
level != 0) {
/* bad width or height or level */
return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
if (width < 2 * border || width > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(width - 2 * border) != 1) ||
+ width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
height < 2 * border || height > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(height - 2 * border) != 1) ||
+ height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
level >= ctx->Const.MaxCubeTextureLevels) {
/* bad width or height */
return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
if (width < 2 * border || width > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(width - 2 * border) != 1) ||
+ width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
level >= ctx->Const.MaxTextureLevels) {
/* bad width or level */
return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
if (width < 2 * border || width > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(width - 2 * border) != 1) ||
+ width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
height < 2 * border || height > 2 + maxSize ||
(!ctx->Extensions.ARB_texture_non_power_of_two &&
- _mesa_bitcount(height - 2 * border) != 1) ||
+ height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
level >= ctx->Const.MaxTextureLevels) {
/* bad width or height or level */
return GL_FALSE;
}
+/**
+ * Helper function to determine whether a target supports compressed textures
+ */
+static GLboolean
+target_can_be_compressed(GLcontext *ctx, GLenum target)
+{
+ return (((target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D))
+ || ((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))))
+ || ((ctx->Extensions.MESA_texture_array &&
+ ((target == GL_PROXY_TEXTURE_2D_ARRAY_EXT) ||
+ (target == GL_TEXTURE_2D_ARRAY_EXT)))));
+}
+
+
/**
* Test the glTexImage[123]D() parameters for errors.
*
if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
proxy_target = GL_PROXY_TEXTURE_1D;
height = 1;
- width = 1;
+ depth = 1;
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
}
/* make sure internal format and format basically agree */
- colorFormat = is_color_format(format);
+ colorFormat = _mesa_is_color_format(format);
indexFormat = is_index_format(format);
- if ((is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
+ if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
(is_index_format(internalFormat) && !indexFormat) ||
(is_depth_format(internalFormat) != is_depth_format(format)) ||
(is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
/* additional checks for compressed textures */
if (is_compressed_format(ctx, 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 (!target_can_be_compressed(ctx, target) && !isProxy) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexImage%d(target)", dimensions);
+ return GL_TRUE;
}
if (border != 0) {
if (!isProxy) {
#endif
if (destTex->IsCompressed) {
- 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 (!target_can_be_compressed(ctx, target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTexSubImage%D(target)", dimensions);
return GL_TRUE;
}
if (is_compressed_format(ctx, internalFormat)) {
- if (target != GL_TEXTURE_2D) {
+ if (!target_can_be_compressed(ctx, target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexImage%d(target)", dimensions);
return GL_TRUE;
/**
* Test glCopyTexSubImage[12]D() parameters for errors.
+ * Note that this is the first part of error checking.
+ * See also copytexsubimage_error_check2() below for the second part.
*
* \param ctx GL context.
* \param dimensions texture image dimensions (must be 1, 2 or 3).
* \param target texture target given by the user.
* \param level image level given by the user.
- * \param xoffset sub-image x offset given by the user.
- * \param yoffset sub-image y offset given by the user.
- * \param zoffset sub-image z offset given by the user.
- * \param width image width given by the user.
- * \param height image height given by the user.
*
* \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
- *
- * Verifies each of the parameters against the constants specified in
- * __GLcontextRec::Const and the supported extensions, and according to the
- * OpenGL specification.
*/
static GLboolean
-copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height)
+copytexsubimage_error_check1( GLcontext *ctx, GLuint dimensions,
+ GLenum target, GLint level)
{
- /* Check target */
/* Check that the source buffer is complete */
if (ctx->ReadBuffer->Name) {
_mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
}
}
+ /* Check target */
if (dimensions == 1) {
if (target != GL_TEXTURE_1D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
return GL_TRUE;
}
- /* Check size */
- if (width < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexSubImage%dD(width=%d)", dimensions, width);
- return GL_TRUE;
- }
- if (dimensions > 1 && height < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexSubImage%dD(height=%d)", dimensions, height);
- return GL_TRUE;
- }
-
return GL_FALSE;
}
+
+/**
+ * Second part of error checking for glCopyTexSubImage[12]D().
+ * \param xoffset sub-image x offset given by the user.
+ * \param yoffset sub-image y offset given by the user.
+ * \param zoffset sub-image z offset given by the user.
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ */
static GLboolean
copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
GLenum target, GLint level,
GLsizei width, GLsizei height,
const struct gl_texture_image *teximage )
{
+ /* check that dest tex image exists */
if (!teximage) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyTexSubImage%dD(undefined texture level: %d)",
return GL_TRUE;
}
+ /* Check size */
+ if (width < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(width=%d)", dimensions, width);
+ return GL_TRUE;
+ }
+ if (dimensions > 1 && height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(height=%d)", dimensions, height);
+ return GL_TRUE;
+ }
+
+ /* check x/y offsets */
if (xoffset < -((GLint)teximage->Border)) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
}
}
+ /* check z offset */
if (dimensions > 2) {
if (zoffset < -((GLint)teximage->Border)) {
_mesa_error(ctx, GL_INVALID_VALUE,
}
if (teximage->IsCompressed) {
- if (target != GL_TEXTURE_2D) {
+ if (!target_can_be_compressed(ctx, target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexSubImage%d(target)", dimensions);
return GL_TRUE;
return;
}
- if (!ctx->Extensions.SGIX_depth_texture &&
- !ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
+ if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return;
}
return;
}
- if (!pixels)
- return;
-
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
* texture's format. Note that a color index texture can be converted
* to RGBA so that combo is allowed.
*/
- if (is_color_format(format)
- && !is_color_format(texImage->TexFormat->BaseFormat)
+ if (_mesa_is_color_format(format)
+ && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
&& !is_index_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
goto out;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (is_color_format(internalFormat)) {
+#if FEATURE_convolve
+ if (_mesa_is_color_format(internalFormat)) {
_mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
}
+#endif
if (target == GL_TEXTURE_1D) {
/* non-proxy target */
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- const GLuint face = texture_face(target);
+ const GLuint face = _mesa_tex_target_to_face(target);
if (texture_error_check(ctx, target, level, internalFormat,
format, type, 1, postConvWidth, 1, 1, border)) {
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- if (is_color_format(internalFormat)) {
+#if FEATURE_convolve
+ if (_mesa_is_color_format(internalFormat)) {
_mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
&postConvHeight);
}
+#endif
if (target == GL_TEXTURE_2D ||
(ctx->Extensions.ARB_texture_cube_map &&
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- const GLuint face = texture_face(target);
+ const GLuint face = _mesa_tex_target_to_face(target);
if (texture_error_check(ctx, target, level, internalFormat,
format, type, 2, postConvWidth, postConvHeight,
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
1, border)) {
/* when error, clear all proxy texture image parameters */
if (texImage)
- clear_teximage_fields(ctx->Texture.Proxy2D->Image[0][level]);
+ clear_teximage_fields(ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]);
}
else {
/* no error, set the tex image parameters */
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- const GLuint face = texture_face(target);
+ const GLuint face = _mesa_tex_target_to_face(target);
if (texture_error_check(ctx, target, level, (GLint) internalFormat,
format, type, 3, width, height, depth, border)) {
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
}
else {
/* no error, set the tex image parameters */
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height,
+ depth, border, internalFormat);
texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
internalFormat, format, type);
}
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
+#if FEATURE_convolve
/* XXX should test internal format */
- if (is_color_format(format)) {
+ if (_mesa_is_color_format(format)) {
_mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
}
+#endif
if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
postConvWidth, 1, 1, format, type)) {
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
+#if FEATURE_convolve
/* XXX should test internal format */
- if (is_color_format(format)) {
+ if (_mesa_is_color_format(format)) {
_mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
&postConvHeight);
}
+#endif
if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
postConvWidth, postConvHeight, 1, format, type)) {
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width;
- const GLuint face = texture_face(target);
+ const GLuint face = _mesa_tex_target_to_face(target);
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- if (is_color_format(internalFormat)) {
+#if FEATURE_convolve
+ if (_mesa_is_color_format(internalFormat)) {
_mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
}
+#endif
if (copytexture_error_check(ctx, 1, target, level, internalFormat,
postConvWidth, 1, border))
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width, postConvHeight = height;
- const GLuint face = texture_face(target);
+ const GLuint face = _mesa_tex_target_to_face(target);
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- if (is_color_format(internalFormat)) {
+#if FEATURE_convolve
+ if (_mesa_is_color_format(internalFormat)) {
_mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
&postConvHeight);
}
+#endif
if (copytexture_error_check(ctx, 2, target, level, internalFormat,
postConvWidth, postConvHeight, border))
update_fbo_texture(ctx, texObj, face, level);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width;
+ GLint yoffset = 0;
+ GLsizei height = 1;
+
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- /* XXX should test internal format */
- _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
-
- if (copytexsubimage_error_check(ctx, 1, target, level,
- xoffset, 0, 0, postConvWidth, 1))
+ if (copytexsubimage_error_check1(ctx, 1, target, level))
return;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+#if FEATURE_convolve
+ if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
+ _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
+ }
+#endif
+
if (copytexsubimage_error_check2(ctx, 1, target, level,
xoffset, 0, 0, postConvWidth, 1,
texImage))
/* If we have a border, xoffset=-1 is legal. Bias by border width */
xoffset += texImage->Border;
- ASSERT(ctx->Driver.CopyTexSubImage1D);
- (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width);
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage1D);
+ ctx->Driver.CopyTexSubImage1D(ctx, target, level,
+ xoffset, x, y, width);
+ }
+
ctx->NewState |= _NEW_TEXTURE;
}
out:
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- /* XXX should test internal format */
- _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
-
- if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
- postConvWidth, postConvHeight))
+ if (copytexsubimage_error_check1(ctx, 2, target, level))
return;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+#if FEATURE_convolve
+ if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
+ _mesa_adjust_image_for_convolution(ctx, 2,
+ &postConvWidth, &postConvHeight);
+ }
+#endif
+
if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
postConvWidth, postConvHeight, texImage))
goto out;
/* If we have a border, xoffset=-1 is legal. Bias by border width */
xoffset += texImage->Border;
yoffset += texImage->Border;
-
- ASSERT(ctx->Driver.CopyTexSubImage2D);
- (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level,
+
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage2D);
+ ctx->Driver.CopyTexSubImage2D(ctx, target, level,
xoffset, yoffset, x, y, width, height);
+ }
+
ctx->NewState |= _NEW_TEXTURE;
}
out:
if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- /* XXX should test internal format */
- _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
-
- if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset,
- zoffset, postConvWidth, postConvHeight))
+ if (copytexsubimage_error_check1(ctx, 3, target, level))
return;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+#if FEATURE_convolve
+ if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
+ _mesa_adjust_image_for_convolution(ctx, 2,
+ &postConvWidth, &postConvHeight);
+ }
+#endif
+
if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset,
zoffset, postConvWidth, postConvHeight,
texImage))
yoffset += texImage->Border;
zoffset += texImage->Border;
- ASSERT(ctx->Driver.CopyTexSubImage3D);
- (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level,
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage3D);
+ ctx->Driver.CopyTexSubImage3D(ctx, target, level,
xoffset, yoffset, zoffset,
x, y, width, height);
+ }
+
ctx->NewState |= _NEW_TEXTURE;
}
out:
* XXX We should probably use the proxy texture error check function here.
*/
if (width < 1 || width > maxTextureSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(width) != 1))
+ (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width)))
return GL_INVALID_VALUE;
if ((height < 1 || height > maxTextureSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(height) != 1))
+ (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height)))
&& dimensions > 1)
return GL_INVALID_VALUE;
if ((depth < 1 || depth > maxTextureSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(depth) != 1))
+ (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth)))
&& dimensions > 2)
return GL_INVALID_VALUE;
texObj, texImage);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
texObj, texImage);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
texObj, texImage);
/* state update */
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
out:
width, height, depth, /*size*/
format, imageSize);
if (error) {
- _mesa_error(ctx, error, "glCompressedTexSubImage2D");
+ _mesa_error(ctx, error, "glCompressedTexSubImage3D");
return;
}
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
if (!texObj) {
return;
}
-
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- /* probably invalid mipmap level */
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
- goto out;
+ if (texImage) {
+ if (texImage->IsCompressed) {
+ /* this typically calls _mesa_get_compressed_teximage() */
+ ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
+ texObj, texImage);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImageARB");
+ }
}
-
- if (!texImage->IsCompressed) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB");
- goto out;
+ else {
+ /* probably invalid mipmap level */
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetCompressedTexImageARB(level)");
}
-
- /* this typically calls _mesa_get_compressed_teximage() */
- ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,texImage);
}
- out:
_mesa_unlock_texture(ctx, texObj);
}