core | glapi | vbo | math | shader | swrast | swrast_setup | tnl | tnl_dd

mipmap.c File Reference


Detailed Description

mipmap generation and teximage resizing functions.

#include "imports.h"
#include "mipmap.h"
#include "texcompress.h"
#include "texformat.h"
#include "teximage.h"
#include "image.h"

Defines

#define INNER_LOOP(TYPE, HOP, WOP)
#define RESCALE_IMAGE(TYPE)
Support macros for do_row and do_row_3d
The macro madness is here for two reasons.

First, it compacts the code slightly. Second, it makes it much easier to adjust the specifics of the filter to tune the rounding characteristics.

#define DECLARE_ROW_POINTERS(t, e)
#define DECLARE_ROW_POINTERS0(t)
#define FILTER_SUM_3D(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk)
#define FILTER_3D(e)
#define FILTER_SUM_3D_SIGNED(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk)
#define FILTER_3D_SIGNED(e)
#define FILTER_F_3D(e)
#define FILTER_HF_3D(e)

Functions

static GLint bytes_per_pixel (GLenum datatype, GLuint comps)
static void do_row (GLenum datatype, GLuint comps, GLint srcWidth, const GLvoid *srcRowA, const GLvoid *srcRowB, GLint dstWidth, GLvoid *dstRow)
 Average together two rows of a source image to produce a single new row in the dest image.
static void do_row_3D (GLenum datatype, GLuint comps, GLint srcWidth, const GLvoid *srcRowA, const GLvoid *srcRowB, const GLvoid *srcRowC, const GLvoid *srcRowD, GLint dstWidth, GLvoid *dstRow)
 Average together four rows of a source image to produce a single new row in the dest image.
static void make_1d_mipmap (GLenum datatype, GLuint comps, GLint border, GLint srcWidth, const GLubyte *srcPtr, GLint dstWidth, GLubyte *dstPtr)
static void make_2d_mipmap (GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, GLint srcRowStride, GLint dstWidth, GLint dstHeight, GLubyte *dstPtr, GLint dstRowStride)
static void make_3d_mipmap (GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, GLint srcDepth, const GLubyte *srcPtr, GLint srcRowStride, GLint dstWidth, GLint dstHeight, GLint dstDepth, GLubyte *dstPtr, GLint dstRowStride)
static void make_1d_stack_mipmap (GLenum datatype, GLuint comps, GLint border, GLint srcWidth, const GLubyte *srcPtr, GLuint srcRowStride, GLint dstWidth, GLint dstHeight, GLubyte *dstPtr, GLuint dstRowStride)
static void make_2d_stack_mipmap (GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, GLint srcRowStride, GLint dstWidth, GLint dstHeight, GLint dstDepth, GLubyte *dstPtr, GLint dstRowStride)
void _mesa_generate_mipmap_level (GLenum target, GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, GLint srcDepth, const GLubyte *srcData, GLint srcRowStride, GLint dstWidth, GLint dstHeight, GLint dstDepth, GLubyte *dstData, GLint dstRowStride)
 Down-sample a texture image to produce the next lower mipmap level.
static GLboolean next_mipmap_level_size (GLenum target, GLint border, GLint srcWidth, GLint srcHeight, GLint srcDepth, GLint *dstWidth, GLint *dstHeight, GLint *dstDepth)
 compute next (level+1) image size
void _mesa_generate_mipmap (GLcontext *ctx, GLenum target, struct gl_texture_object *texObj)
 Automatic mipmap generation.
void _mesa_rescale_teximage2d (GLuint bytesPerPixel, GLuint srcStrideInPixels, GLuint dstRowStride, GLint srcWidth, GLint srcHeight, GLint dstWidth, GLint dstHeight, const GLvoid *srcImage, GLvoid *dstImage)
 Helper function for drivers which need to rescale texture images to certain aspect ratios.
void _mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight, GLsizei outWidth, GLsizei outHeight, GLint comps, const GLchan *src, GLint srcRowStride, GLchan *dest)
 Upscale an image by replication, not (typical) stretching.


Define Documentation

#define DECLARE_ROW_POINTERS ( t,
 ) 

Value:

const t(*rowA)[e] = (const t(*)[e]) srcRowA; \
      const t(*rowB)[e] = (const t(*)[e]) srcRowB; \
      const t(*rowC)[e] = (const t(*)[e]) srcRowC; \
      const t(*rowD)[e] = (const t(*)[e]) srcRowD; \
      t(*dst)[e] = (t(*)[e]) dstRow

#define DECLARE_ROW_POINTERS0 (  ) 

Value:

const t *rowA = (const t *) srcRowA; \
      const t *rowB = (const t *) srcRowB; \
      const t *rowC = (const t *) srcRowC; \
      const t *rowD = (const t *) srcRowD; \
      t *dst = (t *) dstRow

#define FILTER_3D (  ) 

Value:

do { \
      dst[i][e] = FILTER_SUM_3D(rowA[j][e], rowA[k][e], \
                                rowB[j][e], rowB[k][e], \
                                rowC[j][e], rowC[k][e], \
                                rowD[j][e], rowD[k][e]); \
   } while(0)

#define FILTER_3D_SIGNED (  ) 

Value:

do { \
      dst[i][e] = FILTER_SUM_3D_SIGNED(rowA[j][e], rowA[k][e], \
                                       rowB[j][e], rowB[k][e], \
                                       rowC[j][e], rowC[k][e], \
                                       rowD[j][e], rowD[k][e]); \
   } while(0)

#define FILTER_F_3D (  ) 

Value:

do { \
      dst[i][e] = (rowA[j][e] + rowA[k][e] \
                   + rowB[j][e] + rowB[k][e] \
                   + rowC[j][e] + rowC[k][e] \
                   + rowD[j][e] + rowD[k][e]) * 0.125F; \
   } while(0)

#define FILTER_HF_3D (  ) 

Value:

do { \
      const GLfloat aj = _mesa_half_to_float(rowA[j][e]); \
      const GLfloat ak = _mesa_half_to_float(rowA[k][e]); \
      const GLfloat bj = _mesa_half_to_float(rowB[j][e]); \
      const GLfloat bk = _mesa_half_to_float(rowB[k][e]); \
      const GLfloat cj = _mesa_half_to_float(rowC[j][e]); \
      const GLfloat ck = _mesa_half_to_float(rowC[k][e]); \
      const GLfloat dj = _mesa_half_to_float(rowD[j][e]); \
      const GLfloat dk = _mesa_half_to_float(rowD[k][e]); \
      dst[i][e] = _mesa_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \
                                      * 0.125F); \
   } while(0)

#define FILTER_SUM_3D ( Aj,
Ak,
Bj,
Bk,
Cj,
Ck,
Dj,
Dk   ) 

Value:

((unsigned) Aj + (unsigned) Ak \
    + (unsigned) Bj + (unsigned) Bk \
    + (unsigned) Cj + (unsigned) Ck \
    + (unsigned) Dj + (unsigned) Dk \
    + 4) >> 3

#define FILTER_SUM_3D_SIGNED ( Aj,
Ak,
Bj,
Bk,
Cj,
Ck,
Dj,
Dk   ) 

Value:

(Aj + Ak \
    + Bj + Bk \
    + Cj + Ck \
    + Dj + Dk \
    + 4) / 8

#define INNER_LOOP ( TYPE,
HOP,
WOP   ) 

Value:

for ( row = 0 ; row < dstHeight ; row++ ) {                             \
      GLint srcRow = row HOP hScale;                                    \
      for ( col = 0 ; col < dstWidth ; col++ ) {                        \
         GLint srcCol = col WOP wScale;                                 \
         dst[col] = src[srcRow * srcStrideInPixels + srcCol];           \
      }                                                                 \
      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);                  \
   }                                                                    \

#define RESCALE_IMAGE ( TYPE   ) 

Value:

do {                                                                    \
   const TYPE *src = (const TYPE *)srcImage;                            \
   TYPE *dst = (TYPE *)dstImage;                                        \
                                                                        \
   if ( srcHeight < dstHeight ) {                                       \
      const GLint hScale = dstHeight / srcHeight;                       \
      if ( srcWidth < dstWidth ) {                                      \
         const GLint wScale = dstWidth / srcWidth;                      \
         INNER_LOOP( TYPE, /, / );                                      \
      }                                                                 \
      else {                                                            \
         const GLint wScale = srcWidth / dstWidth;                      \
         INNER_LOOP( TYPE, /, * );                                      \
      }                                                                 \
   }                                                                    \
   else {                                                               \
      const GLint hScale = srcHeight / dstHeight;                       \
      if ( srcWidth < dstWidth ) {                                      \
         const GLint wScale = dstWidth / srcWidth;                      \
         INNER_LOOP( TYPE, *, / );                                      \
      }                                                                 \
      else {                                                            \
         const GLint wScale = srcWidth / dstWidth;                      \
         INNER_LOOP( TYPE, *, * );                                      \
      }                                                                 \
   }                                                                    \
} while (0)


Function Documentation

void _mesa_generate_mipmap ( GLcontext ctx,
GLenum  target,
struct gl_texture_object texObj 
)

Automatic mipmap generation.

This is the fallback/default function for ctx->Driver.GenerateMipmap(). Generate a complete set of mipmaps from texObj's BaseLevel image. Stop at texObj's MaxLevel or when we get to the 1x1 texture. For cube maps, target will be one of GL_TEXTURE_CUBE_MAP_POSITIVE/NEGATIVE_X/Y/Z; never GL_TEXTURE_CUBE_MAP.

void _mesa_generate_mipmap_level ( GLenum  target,
GLenum  datatype,
GLuint  comps,
GLint  border,
GLint  srcWidth,
GLint  srcHeight,
GLint  srcDepth,
const GLubyte *  srcData,
GLint  srcRowStride,
GLint  dstWidth,
GLint  dstHeight,
GLint  dstDepth,
GLubyte *  dstData,
GLint  dstRowStride 
)

Down-sample a texture image to produce the next lower mipmap level.

Parameters:
comps components per texel (1, 2, 3 or 4)
srcRowStride stride between source rows, in texels
dstRowStride stride between destination rows, in texels

void _mesa_rescale_teximage2d ( GLuint  bytesPerPixel,
GLuint  srcStrideInPixels,
GLuint  dstRowStride,
GLint  srcWidth,
GLint  srcHeight,
GLint  dstWidth,
GLint  dstHeight,
const GLvoid *  srcImage,
GLvoid *  dstImage 
)

Helper function for drivers which need to rescale texture images to certain aspect ratios.

Nearest filtering only (for broken hardware that can't support all aspect ratios). This can be made a lot faster, but I don't really care enough...

void _mesa_upscale_teximage2d ( GLsizei  inWidth,
GLsizei  inHeight,
GLsizei  outWidth,
GLsizei  outHeight,
GLint  comps,
const GLchan *  src,
GLint  srcRowStride,
GLchan *  dest 
)

Upscale an image by replication, not (typical) stretching.

We use this when the image width or height is less than a certain size (4, 8) and we need to upscale an image.

static GLint bytes_per_pixel ( GLenum  datatype,
GLuint  comps 
) [static]

static void do_row ( GLenum  datatype,
GLuint  comps,
GLint  srcWidth,
const GLvoid *  srcRowA,
const GLvoid *  srcRowB,
GLint  dstWidth,
GLvoid *  dstRow 
) [static]

Average together two rows of a source image to produce a single new row in the dest image.

It's legal for the two source rows to point to the same data. The source width must be equal to either the dest width or two times the dest width.

Parameters:
datatype GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc.
comps number of components per pixel (1..4)

static void do_row_3D ( GLenum  datatype,
GLuint  comps,
GLint  srcWidth,
const GLvoid *  srcRowA,
const GLvoid *  srcRowB,
const GLvoid *  srcRowC,
const GLvoid *  srcRowD,
GLint  dstWidth,
GLvoid *  dstRow 
) [static]

Average together four rows of a source image to produce a single new row in the dest image.

It's legal for the two source rows to point to the same data. The source width must be equal to either the dest width or two times the dest width.

Parameters:
datatype GL pixel type GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc.
comps number of components per pixel (1..4)
srcWidth Width of a row in the source data
srcRowA Pointer to one of the rows of source data
srcRowB Pointer to one of the rows of source data
srcRowC Pointer to one of the rows of source data
srcRowD Pointer to one of the rows of source data
dstWidth Width of a row in the destination data
srcRowA Pointer to the row of destination data

static void make_1d_mipmap ( GLenum  datatype,
GLuint  comps,
GLint  border,
GLint  srcWidth,
const GLubyte *  srcPtr,
GLint  dstWidth,
GLubyte *  dstPtr 
) [static]

static void make_1d_stack_mipmap ( GLenum  datatype,
GLuint  comps,
GLint  border,
GLint  srcWidth,
const GLubyte *  srcPtr,
GLuint  srcRowStride,
GLint  dstWidth,
GLint  dstHeight,
GLubyte *  dstPtr,
GLuint  dstRowStride 
) [static]

static void make_2d_mipmap ( GLenum  datatype,
GLuint  comps,
GLint  border,
GLint  srcWidth,
GLint  srcHeight,
const GLubyte *  srcPtr,
GLint  srcRowStride,
GLint  dstWidth,
GLint  dstHeight,
GLubyte *  dstPtr,
GLint  dstRowStride 
) [static]

static void make_2d_stack_mipmap ( GLenum  datatype,
GLuint  comps,
GLint  border,
GLint  srcWidth,
GLint  srcHeight,
const GLubyte *  srcPtr,
GLint  srcRowStride,
GLint  dstWidth,
GLint  dstHeight,
GLint  dstDepth,
GLubyte *  dstPtr,
GLint  dstRowStride 
) [static]

Bug:
There is quite a bit of refactoring that could be done with this function and make_2d_mipmap.

static void make_3d_mipmap ( GLenum  datatype,
GLuint  comps,
GLint  border,
GLint  srcWidth,
GLint  srcHeight,
GLint  srcDepth,
const GLubyte *  srcPtr,
GLint  srcRowStride,
GLint  dstWidth,
GLint  dstHeight,
GLint  dstDepth,
GLubyte *  dstPtr,
GLint  dstRowStride 
) [static]

static GLboolean next_mipmap_level_size ( GLenum  target,
GLint  border,
GLint  srcWidth,
GLint  srcHeight,
GLint  srcDepth,
GLint *  dstWidth,
GLint *  dstHeight,
GLint *  dstDepth 
) [static]

compute next (level+1) image size

Returns:
GL_FALSE if no smaller size can be generated (eg. src is 1x1x1 size)


Generated on Sun Sep 27 06:47:46 2009 for Mesa Main by  doxygen 1.5.4