-/**
- * \file teximage.c
- * Texture images manipulation functions.
- *
- * \note Mesa's native texture data type is GLchan. Native formats are
- * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA, and
- * GL_COLOR_INDEX.
- *
- * \note Device drivers are free to implement any internal format they want.
- */
-
/*
* Mesa 3-D graphics library
- * Version: 5.1
+ * Version: 6.1
*
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2004 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"),
*/
+/**
+ * \file teximage.c
+ * Texture images manipulation functions.
+ *
+ * \note Mesa's native texture data type is GLchan. Native formats are
+ * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA, and
+ * GL_COLOR_INDEX.
+ *
+ * \note Device drivers are free to implement any internal format they want.
+ */
+
+
#include "glheader.h"
#include "context.h"
#include "convolve.h"
/*
* Compute floor(log_base_2(n)).
- * If n <= 0 return -1.
+ * If n < 0 return -1.
*/
static int
logbase2( int n )
GLint i = 1;
GLint log2 = 0;
- if (n <= 0) {
+ if (n < 0)
return -1;
- }
+
+ if (n == 0)
+ return 0;
while ( n > i ) {
i *= 2;
return GL_RGBA;
else
return -1;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ if (ctx->Extensions.EXT_texture_compression_s3tc)
+ return GL_RGB;
+ else
+ return -1;
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ if (ctx->Extensions.EXT_texture_compression_s3tc)
+ return GL_RGBA;
+ else
+ return -1;
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ if (ctx->Extensions.S3_s3tc)
+ return GL_RGB;
+ else
+ return -1;
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ if (ctx->Extensions.S3_s3tc)
+ return GL_RGBA;
+ else
+ return -1;
case GL_YCBCR_MESA:
if (ctx->Extensions.MESA_ycbcr_texture)
* are supported.
*/
static GLboolean
-is_compressed_format(GLenum internalFormat)
+is_compressed_format(GLcontext *ctx, GLenum internalFormat)
{
switch (internalFormat) {
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
return GL_TRUE;
default:
+ if (ctx->Driver.IsCompressedFormat) {
+ return ctx->Driver.IsCompressedFormat(ctx, internalFormat);
+ }
return GL_FALSE;
}
}
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_TEXTURE_CUBE_MAP_ARB:
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
return ctx->Const.MaxCubeTextureLevels;
break;
img->DepthLog2 = 0;
img->Data = NULL;
img->TexFormat = &_mesa_null_texformat;
- img->FetchTexel = NULL;
+ img->FetchTexelc = NULL;
+ img->FetchTexelf = NULL;
img->IsCompressed = 0;
img->CompressedSize = 0;
}
img->Height2 = height - 2 * border; /*1 << img->HeightLog2;*/
img->Depth2 = depth - 2 * border; /*1 << img->DepthLog2;*/
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
- img->IsCompressed = is_compressed_format(internalFormat);
+ img->IsCompressed = is_compressed_format(ctx, internalFormat);
if (img->IsCompressed)
img->CompressedSize = _mesa_compressed_texture_size(ctx, width, height,
depth, internalFormat);
return GL_TRUE;
}
- if (width < 1 || height < 1 || depth < 1) {
+ if (width < 0 || height < 0 || depth < 0) {
if (!isProxy) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(width, height or depth < 1)", dimensions);
+ "glTexImage%dD(width, height or depth < 0)", dimensions);
}
return GL_TRUE;
}
}
}
- if (is_compressed_format(internalFormat)) {
+ if (is_compressed_format(ctx, internalFormat)) {
if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
/* OK */
}
return GL_TRUE;
}
- if (is_compressed_format(internalFormat)) {
+ if (is_compressed_format(ctx, internalFormat)) {
if (target != GL_TEXTURE_2D) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexImage%d(target)", dimensions);
* \param type pixel data type.
* \param pixels pixel data.
*/
-void
+void GLAPIENTRY
_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
GLenum type, GLvoid *pixels )
{
GLuint indexRow[MAX_WIDTH];
GLint col;
for (col = 0; col < width; col++) {
- (*texImage->FetchTexel)(texImage, col, row, img,
- (GLvoid *) &indexRow[col]);
+ GLchan indx;
+ (*texImage->FetchTexelc)(texImage, col, row, img, &indx);
+ indexRow[col] = indx;
}
_mesa_pack_index_span(ctx, width, type, dest,
indexRow, &ctx->Pack,
GLfloat depthRow[MAX_WIDTH];
GLint col;
for (col = 0; col < width; col++) {
- (*texImage->FetchTexel)(texImage, col, row, img,
- (GLvoid *) &depthRow[col]);
+ (*texImage->FetchTexelf)(texImage, col, row, img,
+ (GLvoid *) &depthRow[col]);
}
_mesa_pack_depth_span(ctx, width, dest, type,
depthRow, &ctx->Pack);
GLchan rgba[MAX_WIDTH][4];
GLint col;
for (col = 0; col < width; col++) {
- (*texImage->FetchTexel)(texImage, col, row, img,
- (GLvoid *) rgba[col]);
+ (*texImage->FetchTexelc)(texImage, col, row, img, rgba[col]);
}
_mesa_pack_rgba_span(ctx, width, (const GLchan (*)[4])rgba,
format, type, dest, &ctx->Pack,
/*
* Called from the API. Note that width includes the border.
*/
-void
+void GLAPIENTRY
_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLint border, GLenum format,
GLenum type, const GLvoid *pixels )
&ctx->Unpack, texObj, texImage);
ASSERT(texImage->TexFormat);
- if (!texImage->FetchTexel) {
- /* If driver didn't explicitly set this, use the default */
- texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
- }
- ASSERT(texImage->FetchTexel);
+
+ /* If driver didn't explicitly set this, use the defaults */
+ if (!texImage->FetchTexelc)
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
+ if (!texImage->FetchTexelf)
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
+ ASSERT(texImage->FetchTexelc);
+ ASSERT(texImage->FetchTexelf);
/* state update */
texObj->Complete = GL_FALSE;
}
-void
+void GLAPIENTRY
_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type,
&ctx->Unpack, texObj, texImage);
ASSERT(texImage->TexFormat);
- if (!texImage->FetchTexel) {
- /* If driver didn't explicitly set this, use the default */
- texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
- }
- ASSERT(texImage->FetchTexel);
+
+ /* If driver didn't explicitly set these, use the defaults */
+ if (!texImage->FetchTexelc)
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
+ if (!texImage->FetchTexelf)
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
+ ASSERT(texImage->FetchTexelc);
+ ASSERT(texImage->FetchTexelf);
/* state update */
texObj->Complete = GL_FALSE;
* Called by the API or display list executor.
* Note that width and height include the border.
*/
-void
+void GLAPIENTRY
_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
pixels, &ctx->Unpack, texObj, texImage);
ASSERT(texImage->TexFormat);
- if (!texImage->FetchTexel) {
- /* If driver didn't explicitly set this, use the default */
- texImage->FetchTexel = texImage->TexFormat->FetchTexel3D;
- }
- ASSERT(texImage->FetchTexel);
+
+ /* If driver didn't explicitly set these, use the defaults */
+ if (!texImage->FetchTexelc)
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
+ if (!texImage->FetchTexelf)
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
+ ASSERT(texImage->FetchTexelc);
+ ASSERT(texImage->FetchTexelf);
/* state update */
texObj->Complete = GL_FALSE;
}
-void
+void GLAPIENTRY
_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
-void
+void GLAPIENTRY
_mesa_TexSubImage1D( GLenum target, GLint level,
GLint xoffset, GLsizei width,
GLenum format, GLenum type,
}
-void
+void GLAPIENTRY
_mesa_TexSubImage2D( GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
-void
+void GLAPIENTRY
_mesa_TexSubImage3D( GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
-void
+void GLAPIENTRY
_mesa_CopyTexImage1D( GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y,
x, y, width, border);
ASSERT(texImage->TexFormat);
- if (!texImage->FetchTexel) {
- /* If driver didn't explicitly set this, use the default */
- texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
- }
- ASSERT(texImage->FetchTexel);
+
+ /* If driver didn't explicitly set these, use the defaults */
+ if (!texImage->FetchTexelc)
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
+ if (!texImage->FetchTexelf)
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
+ ASSERT(texImage->FetchTexelc);
+ ASSERT(texImage->FetchTexelf);
/* state update */
texObj->Complete = GL_FALSE;
-void
+void GLAPIENTRY
_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border )
x, y, width, height, border);
ASSERT(texImage->TexFormat);
- if (!texImage->FetchTexel) {
- /* If driver didn't explicitly set this, use the default */
- texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
- }
- ASSERT(texImage->FetchTexel);
+
+ /* If driver didn't explicitly set these, use the defaults */
+ if (!texImage->FetchTexelc)
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
+ if (!texImage->FetchTexelf)
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
+ ASSERT(texImage->FetchTexelc);
+ ASSERT(texImage->FetchTexelf);
/* state update */
texObj->Complete = GL_FALSE;
-void
+void GLAPIENTRY
_mesa_CopyTexSubImage1D( GLenum target, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width )
{
struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width;
GET_CURRENT_CONTEXT(ctx);
return;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
ASSERT(texImage);
-void
+void GLAPIENTRY
_mesa_CopyTexSubImage2D( GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height )
{
struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width, postConvHeight = height;
GET_CURRENT_CONTEXT(ctx);
return;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
ASSERT(texImage);
-void
+void GLAPIENTRY
_mesa_CopyTexSubImage3D( GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height )
{
struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width, postConvHeight = height;
GET_CURRENT_CONTEXT(ctx);
return;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
ASSERT(texImage);
GLsizei height, GLsizei depth, GLint border,
GLsizei imageSize)
{
- GLboolean isProxy = GL_FALSE;
GLint expectedSize, maxLevels = 0, maxTextureSize;
if (dimensions == 1) {
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;
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) {
maxTextureSize = 1 << (maxLevels - 1);
- if (!is_compressed_format(internalFormat))
+ if (!is_compressed_format(ctx, internalFormat))
return GL_INVALID_ENUM;
if (border != 0)
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLsizei imageSize)
{
- GLboolean isProxy = GL_FALSE;
GLint expectedSize, maxLevels = 0, maxTextureSize;
if (dimensions == 1) {
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;
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) {
maxTextureSize = 1 << (maxLevels - 1);
- if (!is_compressed_format(format))
+ if (!is_compressed_format(ctx, format))
return GL_INVALID_ENUM;
if (width < 1 || width > maxTextureSize)
-void
+void GLAPIENTRY
_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
GLenum internalFormat, GLsizei width,
GLint border, GLsizei imageSize,
}
-void
+void GLAPIENTRY
_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
GLenum internalFormat, GLsizei width,
GLsizei height, GLint border, GLsizei imageSize,
}
-void
+void GLAPIENTRY
_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
GLenum internalFormat, GLsizei width,
GLsizei height, GLsizei depth, GLint border,
}
-void
+void GLAPIENTRY
_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
GLsizei width, GLenum format,
GLsizei imageSize, const GLvoid *data)
}
-void
+void GLAPIENTRY
_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLsizei width, GLsizei height,
GLenum format, GLsizei imageSize,
error = compressed_subtexture_error_check(ctx, 2, target, level,
xoffset, yoffset, 0, width, height, 1, format, imageSize);
if (error) {
+ /* XXX proxy target? */
_mesa_error(ctx, error, "glCompressedTexSubImage2D");
return;
}
}
-void
+void GLAPIENTRY
_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLint zoffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum format,
}
-void
+void GLAPIENTRY
_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
{
const struct gl_texture_unit *texUnit;