#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 DECLARE_ROW_POINTERS | ( | t, | |||
e | ) |
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 | ( | t | ) |
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 | ( | e | ) |
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 | ( | e | ) |
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 | ( | e | ) |
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 | ( | e | ) |
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)
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.
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.
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.
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] |
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