X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexcompress.c;h=4c6eaae4cf324272f5ab63e05788d500b6636480;hb=263581bba4d61291c54313648063a30c47106f0b;hp=680c0bb0239ae21397a413ab212b795b627c10b2;hpb=2ce0654ebabc7fc6a2881f51e496e4e1f7533087;p=mesa.git diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index 680c0bb0239..4c6eaae4cf3 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -1,10 +1,13 @@ -/* $Id: texcompress.c,v 1.2 2002/10/18 17:41:45 brianp Exp $ */ +/** + * \file texcompress.c + * Compressed textures functions. + */ /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 5.1 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2003 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"), @@ -26,16 +29,19 @@ #include "glheader.h" +#include "imports.h" #include "context.h" #include "image.h" -#include "mem.h" #include "texcompress.h" #include "texformat.h" /** * Get the list of supported internal compression formats. - * \param formats - the results list (may be NULL) + * + * \param ctx GL context. + * \param formats the resulting format list (may be NULL). + * * \return number of formats. */ GLuint @@ -48,6 +54,32 @@ _mesa_get_compressed_formats( GLcontext *ctx, GLint *formats ) formats[n++] = GL_COMPRESSED_RGB_FXT1_3DFX; formats[n++] = GL_COMPRESSED_RGBA_FXT1_3DFX; } + else { + n += 2; + } + } + if (ctx->Extensions.EXT_texture_compression_s3tc) { + if (formats) { + formats[n++] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + /* Skip this one because it has a restriction (all transparent + * pixels become black). See the texture compressions spec for + * a detailed explanation. This is what NVIDIA does. + formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + */ + formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } + else { + n += 3; + } + } + if (ctx->Extensions.S3_s3tc) { + if (formats) { + formats[n++] = GL_RGB_S3TC; + formats[n++] = GL_RGB4_S3TC; + formats[n++] = GL_RGBA_S3TC; + formats[n++] = GL_RGBA4_S3TC; + } else { n += 4; } @@ -57,13 +89,16 @@ _mesa_get_compressed_formats( GLcontext *ctx, GLint *formats ) } - /** - * Return bytes of storage needed for the given texture size and compressed - * format. - * \param width, height, depth - texture size in texels - * \param texFormat - one of the compressed format enums - * \return size in bytes, or zero if bad texFormat + * Return bytes of storage needed for the given texture size and + * compressed format. + * + * \param width texture width in texels. + * \param height texture height in texels. + * \param depth texture depth in texels. + * \param texFormat one of the compressed format enums + * + * \return size in bytes, or zero if bad \p texFormat. */ GLuint _mesa_compressed_texture_size( GLcontext *ctx, @@ -72,11 +107,55 @@ _mesa_compressed_texture_size( GLcontext *ctx, { GLuint size; + if (ctx->Driver.CompressedTextureSize) { + return ctx->Driver.CompressedTextureSize(ctx, width, height, depth, format); + } + + ASSERT(depth == 1); + switch (format) { case GL_COMPRESSED_RGB_FXT1_3DFX: case GL_COMPRESSED_RGBA_FXT1_3DFX: - /* round up to multiple of 4 */ - size = ((width + 7) / 8) * ((height + 3) / 4) * 16; + /* round up width to next multiple of 8, height to next multiple of 4 */ + width = (width + 7) & ~7; + height = (height + 3) & ~3; + /* 16 bytes per 8x4 tile of RGB[A] texels */ + size = width * height / 2; + /* Textures smaller than 8x4 will effectively be made into 8x4 and + * take 16 bytes. + */ + if (size < 16) + size = 16; + return size; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + /* round up width, height to next multiple of 4 */ + width = (width + 3) & ~3; + height = (height + 3) & ~3; + /* 8 bytes per 4x4 tile of RGB[A] texels */ + size = width * height / 2; + /* Textures smaller than 4x4 will effectively be made into 4x4 and + * take 8 bytes. + */ + if (size < 8) + size = 8; + return size; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + /* round up width, height to next multiple of 4 */ + width = (width + 3) & ~3; + height = (height + 3) & ~3; + /* 16 bytes per 4x4 tile of RGBA texels */ + size = width * height; /* simple! */ + /* Textures smaller than 4x4 will effectively be made into 4x4 and + * take 16 bytes. + */ + if (size < 16) + size = 16; return size; default: _mesa_problem(ctx, "bad texformat in compressed_texture_size"); @@ -85,60 +164,100 @@ _mesa_compressed_texture_size( GLcontext *ctx, } -/* +/** * Compute the bytes per row in a compressed texture image. + * We use this for computing the destination address for sub-texture updates. + * \param format one of the specific texture compression formats + * \param width image width in pixels + * \return stride, in bytes, between rows for compressed image */ GLint _mesa_compressed_row_stride(GLenum format, GLsizei width) { - GLint bytesPerTile, stride; + GLint stride; switch (format) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + stride = ((width + 7) / 8) * 16; /* 16 bytes per 8x4 tile */ + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + stride = ((width + 3) / 4) * 8; /* 8 bytes per 4x4 tile */ + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + stride = ((width + 3) / 4) * 16; /* 16 bytes per 4x4 tile */ + break; default: return 0; } - stride = ((width + 3) / 4) * bytesPerTile; return stride; } -/* +/** * Return the address of the pixel at (col, row, img) in a * compressed texture image. - * \param col, row, img - image position (3D) - * \param format - compressed image format - * \param width - image width - * \param image - the image address - * \return address of pixel at (row, col) + * + * \param col image position. + * \param row image position. + * \param img image position. + * \param format compressed image format. + * \param width image width. + * \param image the image address. + * + * \return address of pixel at (row, col). */ GLubyte * _mesa_compressed_image_address(GLint col, GLint row, GLint img, GLenum format, GLsizei width, const GLubyte *image) { - GLint bytesPerTile, stride; GLubyte *addr; - ASSERT((row & 3) == 0); - ASSERT((col & 3) == 0); (void) img; + /* We try to spot a "complete" subtexture "above" ROW, COL; + * this texture is given by appropriate rounding of WIDTH x ROW. + * Then we just add the amount left (usually on the left). + * + * Example for X*Y microtiles (Z bytes each) + * offset = Z * (((width + X - 1) / X) * (row / Y) + col / X); + */ + switch (format) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + addr = (GLubyte *) image + 16 * (((width + 7) / 8) * (row / 4) + col / 8); + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + addr = (GLubyte *) image + 8 * (((width + 3) / 4) * (row / 4) + col / 4); + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + addr = (GLubyte *) image + 16 * (((width + 3) / 4) * (row / 4) + col / 4); + break; default: return 0; } - stride = ((width + 3) / 4) * bytesPerTile; - - addr = (GLubyte *) image + (row / 4) * stride + (col / 4) * bytesPerTile; return addr; } - -/* - * \param srcRowStride - source stride, in pixels +/** + * \param srcRowStride source stride, in pixels */ void _mesa_compress_teximage( GLcontext *ctx, GLsizei width, GLsizei height,