-/* $Id: xm_api.c,v 1.24 2001/06/04 22:33:02 brianp Exp $ */
+/* $Id: xm_api.c,v 1.25 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
#include "conf.h"
#endif
#include "macros.h"
+#include "texformat.h"
+#include "texstore.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "array_cache/acache.h"
}
_mesa_enable_sw_extensions(ctx);
+ _mesa_enable_extension(ctx, "GL_ARB_texture_compression");
+ ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
+ ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
+ ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
if (CHECK_BYTE_ORDER(v)) {
c->swapbytes = GL_FALSE;
-/* $Id: dd.h,v 1.61 2001/04/04 21:54:20 brianp Exp $ */
+/* $Id: dd.h,v 1.62 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
* should do the job.
*/
- GLboolean (*IsCompressedFormat)(GLcontext *ctx, GLint internalFormat);
- /* Called to tell if a format is a compressed format.
- */
-
void (*GetCompressedTexImage)( GLcontext *ctx, GLenum target,
- GLint lod, void *image,
+ GLint level, void *image,
const struct gl_texture_object *texObj,
struct gl_texture_image *texImage );
/* Called by glGetCompressedTexImageARB.
- * <target>, <lod>, <image> are specified by user.
+ * <target>, <level>, <image> are specified by user.
* <texObj> is the source texture object.
* <texImage> is the source texture image.
*/
* Example: if internalFormat==GL_COMPRESSED_RGB_FXT1_3DFX, return GL_RGB.
*/
+ GLint (*CompressedTextureSize)(GLcontext *ctx,
+ const struct gl_texture_image *texImage);
+
#if 000
/* ... Note the
* return value differences between this function and
* do the right thing with it.
*/
- GLsizei (*CompressedImageSize)(GLcontext *ctx,
- GLenum internalFormat,
- GLuint numDimensions,
- GLuint width,
- GLuint height,
- GLuint depth);
- /* Calculate the size of a compressed image, given the image's
- * format and dimensions.
- */
#endif
/***
-/* $Id: extensions.c,v 1.61 2001/05/29 15:23:49 brianp Exp $ */
+/* $Id: extensions.c,v 1.62 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
}
+
+/*
+ * Enable all OpenGL 1.3 features and extensions.
+ */
+void
+_mesa_enable_1_3_extensions(GLcontext *ctx)
+{
+ const char *extensions[] = {
+ "GL_ARB_multisample",
+ "GL_ARB_multitexture",
+ "GL_ARB_texture_border_clamp",
+ "GL_ARB_texture_compression",
+ "GL_ARB_texture_cube_map",
+ "GL_ARB_texture_env_add",
+ "GL_ARB_texture_env_combine",
+ "GL_ARB_texture_env_dot3",
+ "GL_ARB_transpose_matrix",
+ NULL
+ };
+ GLuint i;
+
+ for (i = 0; extensions[i]; i++) {
+ _mesa_enable_extension(ctx, extensions[i]);
+ }
+}
+
+
+
/*
* Add a new extenstion. This would be called from a Mesa driver.
*/
-/* $Id: extensions.h,v 1.13 2001/03/12 00:48:37 gareth Exp $ */
+/* $Id: extensions.h,v 1.14 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
extern void _mesa_enable_imaging_extensions(GLcontext *ctx);
+extern void _mesa_enable_1_3_extensions(GLcontext *ctx);
+
extern void _mesa_add_extension( GLcontext *ctx, GLboolean enabled,
const char *name, GLboolean *flag_ptr );
-/* $Id: state.c,v 1.66 2001/05/29 15:23:49 brianp Exp $ */
+/* $Id: state.c,v 1.67 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
ASSERT(ctx->Driver.CopyTexSubImage2D);
ASSERT(ctx->Driver.CopyTexSubImage3D);
if (ctx->Extensions.ARB_texture_compression) {
+ ASSERT(ctx->Driver.BaseCompressedTexFormat);
+ ASSERT(ctx->Driver.CompressedTextureSize);
+ ASSERT(ctx->Driver.GetCompressedTexImage);
+#if 0 /* HW drivers need these, but not SW rasterizers */
ASSERT(ctx->Driver.CompressedTexImage1D);
ASSERT(ctx->Driver.CompressedTexImage2D);
ASSERT(ctx->Driver.CompressedTexImage3D);
ASSERT(ctx->Driver.CompressedTexSubImage1D);
ASSERT(ctx->Driver.CompressedTexSubImage2D);
ASSERT(ctx->Driver.CompressedTexSubImage3D);
- ASSERT(ctx->Driver.IsCompressedFormat);
- ASSERT(ctx->Driver.GetCompressedTexImage);
- ASSERT(ctx->Driver.BaseCompressedTexFormat);
+#endif
}
}
-/* $Id: texformat.c,v 1.10 2001/04/20 16:46:04 brianp Exp $ */
+/* $Id: texformat.c,v 1.11 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
}
-/* Given an internal texture format or 1, 2, 3, 4 initialize the texture
- * image structure's default format and type information. Drivers will
- * initialize these fields accordingly if they override the default
- * storage format.
+/* Given an internal texture format (or 1, 2, 3, 4) return a pointer
+ * to a gl_texture_format which which to store the texture.
+ * This is called via ctx->Driver.ChooseTextureFormat().
+ * Hardware drivers should not use this function, but instead a
+ * specialized function.
*/
const struct gl_texture_format *
_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
case GL_DEPTH_COMPONENT16_SGIX:
case GL_DEPTH_COMPONENT24_SGIX:
case GL_DEPTH_COMPONENT32_SGIX:
- if ( !ctx->Extensions.SGIX_depth_texture )
- _mesa_problem( ctx, "depth format without GL_SGIX_depth_texture" );
+ if (!ctx->Extensions.SGIX_depth_texture)
+ _mesa_problem(ctx, "depth format without GL_SGIX_depth_texture");
return &_mesa_texformat_depth_component;
+ case GL_COMPRESSED_ALPHA_ARB:
+ if (!ctx->Extensions.ARB_texture_compression)
+ _mesa_problem(ctx, "texture compression extension not enabled");
+ return &_mesa_texformat_alpha;
+ case GL_COMPRESSED_LUMINANCE_ARB:
+ if (!ctx->Extensions.ARB_texture_compression)
+ _mesa_problem(ctx, "texture compression extension not enabled");
+ return &_mesa_texformat_luminance;
+ case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
+ if (!ctx->Extensions.ARB_texture_compression)
+ _mesa_problem(ctx, "texture compression extension not enabled");
+ return &_mesa_texformat_luminance_alpha;
+ case GL_COMPRESSED_INTENSITY_ARB:
+ if (!ctx->Extensions.ARB_texture_compression)
+ _mesa_problem(ctx, "texture compression extension not enabled");
+ return &_mesa_texformat_intensity;
+ case GL_COMPRESSED_RGB_ARB:
+ if (!ctx->Extensions.ARB_texture_compression)
+ _mesa_problem(ctx, "texture compression extension not enabled");
+ return &_mesa_texformat_rgb;
+ case GL_COMPRESSED_RGBA_ARB:
+ if (!ctx->Extensions.ARB_texture_compression)
+ _mesa_problem(ctx, "texture compression extension not enabled");
+ return &_mesa_texformat_rgba;
+
default:
- _mesa_problem( ctx, "unexpected format in _mesa_choose_tex_format()" );
- printf("intformat = %d %x\n", internalFormat, internalFormat );
+ _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
+ printf("intformat = %d %x\n", internalFormat, internalFormat);
return NULL;
}
}
+
+
+
+
+/*
+ * Return the base texture format for the given compressed format
+ * Called via ctx->Driver.BaseCompressedTexFormat().
+ * This function is used by software rasterizers. Hardware drivers
+ * which support texture compression should not use this function but
+ * a specialized function instead.
+ */
+GLint
+_mesa_base_compressed_texformat(GLcontext *ctx, GLint intFormat)
+{
+ switch (intFormat) {
+ case GL_COMPRESSED_ALPHA_ARB:
+ return GL_ALPHA;
+ case GL_COMPRESSED_LUMINANCE_ARB:
+ return GL_LUMINANCE;
+ case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
+ return GL_LUMINANCE_ALPHA;
+ case GL_COMPRESSED_INTENSITY_ARB:
+ return GL_INTENSITY;
+ case GL_COMPRESSED_RGB_ARB:
+ return GL_RGB;
+ case GL_COMPRESSED_RGBA_ARB:
+ return GL_RGBA;
+ default:
+ return -1; /* not a recognized compressed format */
+ }
+}
+
+
+/*
+ * Called via ctx->Driver.CompressedTextureSize().
+ * This function is only used by software rasterizers.
+ * Hardware drivers will have to implement a specialized function.
+ */
+GLint
+_mesa_compressed_texture_size(GLcontext *ctx,
+ const struct gl_texture_image *texImage)
+{
+ GLint b;
+ assert(texImage);
+ assert(texImage->TexFormat);
+
+ b = texImage->Width * texImage->Height * texImage->Depth *
+ texImage->TexFormat->TexelBytes;
+ assert(b > 0);
+ return b;
+}
-/* $Id: texformat.h,v 1.6 2001/04/04 21:54:21 brianp Exp $ */
+/* $Id: texformat.h,v 1.7 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
GLenum format, GLenum type );
+extern GLint
+_mesa_base_compressed_texformat(GLcontext *ctx, GLint intFormat);
+
+extern GLint
+_mesa_compressed_texture_size(GLcontext *ctx,
+ const struct gl_texture_image *texImage);
+
/* The default formats, GLchan per component:
*/
-/* $Id: teximage.c,v 1.97 2001/06/13 14:56:14 brianp Exp $ */
+/* $Id: teximage.c,v 1.98 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
static GLboolean
is_compressed_format(GLcontext *ctx, GLenum internalFormat)
{
- if (ctx->Driver.IsCompressedFormat) {
- return (*ctx->Driver.IsCompressedFormat)(ctx, internalFormat);
- }
- return GL_FALSE;
+ if (ctx->Driver.BaseCompressedTexFormat) {
+ GLint b = (*ctx->Driver.BaseCompressedTexFormat)(ctx, internalFormat);
+ if (b > 0)
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ }
+ return GL_FALSE;
}
{
ASSERT(img);
img->Format = _mesa_base_tex_format( ctx, internalFormat );
+ ASSERT(img->Format > 0);
img->IntFormat = internalFormat;
img->Border = border;
img->Width = width;
return GL_TRUE;
}
+ ASSERT(iformat > 0);
+
if (!is_compressed_format( ctx, internalFormat ) &&
!_mesa_is_legal_format_and_type( format, type )) {
/* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
struct gl_texture_image *destTex;
GLint maxLevels = 0;
+ GLboolean compressed;
if (dimensions == 1) {
if (target != GL_TEXTURE_1D) {
}
}
- if (!is_compressed_format(ctx, destTex->IntFormat) &&
- !_mesa_is_legal_format_and_type(format, type)) {
+ compressed = is_compressed_format(ctx, destTex->IntFormat);
+
+ if (!compressed && !_mesa_is_legal_format_and_type(format, type)) {
char message[100];
sprintf(message, "glTexSubImage%dD(format or type)", dimensions);
_mesa_error(ctx, GL_INVALID_ENUM, message);
return GL_TRUE;
}
+ if (compressed) {
+ if (xoffset != -destTex->Border) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage1/2/3D(xoffset != -border");
+ return GL_TRUE;
+ }
+ if (dimensions > 1 && yoffset != -destTex->Border) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage2/3D(yoffset != -border");
+ return GL_TRUE;
+ }
+ if (dimensions > 2 && zoffset != -destTex->Border) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage3D(zoffset != -border");
+ return GL_TRUE;
+ }
+ }
+
return GL_FALSE;
}
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) {
}
}
+ compressed = is_compressed_format(ctx, teximage->IntFormat);
+ if (compressed) {
+ if (xoffset != -teximage->Border) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage1/2/3D(xoffset != -border");
+ return GL_TRUE;
+ }
+ if (dimensions > 1 && yoffset != -teximage->Border) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage2/3D(yoffset != -border");
+ return GL_TRUE;
+ }
+ if (dimensions > 2 && zoffset != -teximage->Border) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage3D(zoffset != -border");
+ return GL_TRUE;
+ }
+ }
+
/* if we get here, the parameters are OK */
return GL_FALSE;
}
}
ASSERT(texImage->FetchTexel);
+ if (texImage->IsCompressed) {
+ ASSERT(texImage->CompressedSize > 0);
+ }
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
ASSERT(texImage->FetchTexel);
+ if (texImage->IsCompressed) {
+ ASSERT(texImage->CompressedSize > 0);
+ }
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
}
ASSERT(texImage->FetchTexel);
+ if (texImage->IsCompressed) {
+ ASSERT(texImage->CompressedSize > 0);
+ }
+
/* state update */
texObj->Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- /* invalid mipmap level */
+ /* probably invalid mipmap level */
_mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
return;
}
-/* $Id: texstore.c,v 1.28 2001/06/13 14:56:14 brianp Exp $ */
+/* $Id: texstore.c,v 1.29 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
GLboolean freeSourceData = GL_FALSE;
GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
+ assert(baseInternalFormat > 0);
+
if (transferOps & IMAGE_CONVOLUTION_BIT) {
_mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
&postConvHeight);
struct gl_texture_image *texImage)
{
GLint postConvWidth = width;
- GLint texelBytes;
+ GLint texelBytes, sizeInBytes;
if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
_mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
texelBytes = texImage->TexFormat->TexelBytes;
+ /* Compute image size, in bytes */
+ if (texImage->IsCompressed) {
+ assert(ctx->Driver.CompressedTextureSize);
+ sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage);
+ assert(sizeInBytes > 0);
+ texImage->CompressedSize = sizeInBytes;
+ }
+ else {
+ sizeInBytes = postConvWidth * texelBytes;
+ }
+
/* allocate memory */
- texImage->Data = MALLOC(postConvWidth * texelBytes);
+ texImage->Data = MALLOC(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
return;
* The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
* GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
*
+ * NOTE: if real texture compression is supported, this whole function
+ * will need to be overridden.
*/
void
_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
struct gl_texture_image *texImage)
{
GLint postConvWidth = width, postConvHeight = height;
- GLint texelBytes;
+ GLint texelBytes, sizeInBytes;
if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
_mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
texelBytes = texImage->TexFormat->TexelBytes;
+ /* Compute image size, in bytes */
+ if (texImage->IsCompressed) {
+ assert(ctx->Driver.CompressedTextureSize);
+ sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage);
+ assert(sizeInBytes > 0);
+ texImage->CompressedSize = sizeInBytes;
+ }
+ else {
+ sizeInBytes = postConvWidth * postConvHeight * texelBytes;
+ }
+
/* allocate memory */
- texImage->Data = MALLOC(postConvWidth * postConvHeight * texelBytes);
+ texImage->Data = MALLOC(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
return;
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- GLint texelBytes;
+ GLint texelBytes, sizeInBytes;
/* choose the texture format */
assert(ctx->Driver.ChooseTextureFormat);
texelBytes = texImage->TexFormat->TexelBytes;
+ /* Compute image size, in bytes */
+ if (texImage->IsCompressed) {
+ assert(ctx->Driver.CompressedTextureSize);
+ sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage);
+ assert(sizeInBytes > 0);
+ texImage->CompressedSize = sizeInBytes;
+ }
+ else {
+ sizeInBytes = width * height * depth * texelBytes;
+ }
+
/* allocate memory */
- texImage->Data = MALLOC(width * height * depth * texelBytes);
+ texImage->Data = MALLOC(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
return;
/*
+ * Fallback for Driver.GetCompressedTexImage3D()
+ * This will probably work find for hardware drivers. That is, hardware
+ * drivers won't have to override this function, unless the compressed
+ * texture must first be fetched from the TRAM.
+ */
+void
+_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target,
+ GLint level, void *image,
+ const struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ assert(texImage->IsCompressed);
+ assert(texImage->CompressedSize > 0);
+ MEMCPY(image, texImage->Data, texImage->CompressedSize);
+}
+
+
+
+/*
* This is the fallback for Driver.TestProxyTexImage().
*/
GLboolean
-/* $Id: texstore.h,v 1.8 2001/05/21 16:41:04 brianp Exp $ */
+/* $Id: texstore.h,v 1.9 2001/06/15 14:18:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
struct gl_texture_image *texImage);
+extern void
+_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target,
+ GLint level, void *image,
+ const struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
extern GLboolean
_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
GLint internalFormat, GLenum format, GLenum type,