u_gen_mipmap.c File Reference

Mipmap generation utility. More...

Include dependency graph for u_gen_mipmap.c:

Go to the source code of this file.

Data Structures

struct  gen_mipmap_state

Typedefs

typedef ushort half_float

Enumerations

enum  dtype {
  UBYTE, UBYTE_3_3_2, USHORT, USHORT_4_4_4_4,
  USHORT_5_6_5, USHORT_1_5_5_5_REV, UINT, FLOAT,
  HALF_FLOAT
}

Functions

static void do_row (enum dtype datatype, uint comps, int srcWidth, const void *srcRowA, const void *srcRowB, int dstWidth, void *dstRow)
 Average together two rows of a source image to produce a single new row in the dest image.
static void format_to_type_comps (enum pipe_format pformat, enum dtype *datatype, uint *comps)
static void reduce_1d (enum pipe_format pformat, int srcWidth, const ubyte *srcPtr, int dstWidth, ubyte *dstPtr)
static void reduce_2d (enum pipe_format pformat, int srcWidth, int srcHeight, int srcRowStride, const ubyte *srcPtr, int dstWidth, int dstHeight, int dstRowStride, ubyte *dstPtr)
 Strides are in bytes.
static void make_1d_mipmap (struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel)
static void make_2d_mipmap (struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel)
static void make_3d_mipmap (struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel)
static void fallback_gen_mipmap (struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel)
struct gen_mipmap_stateutil_create_gen_mipmap (struct pipe_context *pipe, struct cso_context *cso)
 Create a mipmap generation context.
static unsigned get_next_slot (struct gen_mipmap_state *ctx)
 Get next "slot" of vertex space in the vertex buffer.
static unsigned set_vertex_data (struct gen_mipmap_state *ctx, float width, float height)
void util_destroy_gen_mipmap (struct gen_mipmap_state *ctx)
 Destroy a mipmap generation context.
void util_gen_mipmap_flush (struct gen_mipmap_state *ctx)
void util_gen_mipmap (struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel, uint filter)
 Generate mipmap images.


Detailed Description

Mipmap generation utility.

Author:
Brian Paul

Definition in file u_gen_mipmap.c.


Typedef Documentation

typedef ushort half_float

Definition at line 93 of file u_gen_mipmap.c.


Enumeration Type Documentation

enum dtype

Enumerator:
UBYTE 
UBYTE_3_3_2 
USHORT 
USHORT_4_4_4_4 
USHORT_5_6_5 
USHORT_1_5_5_5_REV 
UINT 
FLOAT 
HALF_FLOAT 

Definition at line 79 of file u_gen_mipmap.c.

00080 {
00081    UBYTE,
00082    UBYTE_3_3_2,
00083    USHORT,
00084    USHORT_4_4_4_4,
00085    USHORT_5_6_5,
00086    USHORT_1_5_5_5_REV,
00087    UINT,
00088    FLOAT,
00089    HALF_FLOAT
00090 };


Function Documentation

static void do_row ( enum dtype  datatype,
uint  comps,
int  srcWidth,
const void *  srcRowA,
const void *  srcRowB,
int  dstWidth,
void *  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)

Definition at line 114 of file u_gen_mipmap.c.

References assert, debug_printf(), FLOAT, HALF_FLOAT, UBYTE, UBYTE_3_3_2, UINT, USHORT, USHORT_1_5_5_5_REV, USHORT_4_4_4_4, and USHORT_5_6_5.

00117 {
00118    const uint k0 = (srcWidth == dstWidth) ? 0 : 1;
00119    const uint colStride = (srcWidth == dstWidth) ? 1 : 2;
00120 
00121    assert(comps >= 1);
00122    assert(comps <= 4);
00123 
00124    /* This assertion is no longer valid with non-power-of-2 textures
00125    assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
00126    */
00127 
00128    if (datatype == UBYTE && comps == 4) {
00129       uint i, j, k;
00130       const ubyte(*rowA)[4] = (const ubyte(*)[4]) srcRowA;
00131       const ubyte(*rowB)[4] = (const ubyte(*)[4]) srcRowB;
00132       ubyte(*dst)[4] = (ubyte(*)[4]) dstRow;
00133       for (i = j = 0, k = k0; i < (uint) dstWidth;
00134            i++, j += colStride, k += colStride) {
00135          dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
00136          dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
00137          dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
00138          dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
00139       }
00140    }
00141    else if (datatype == UBYTE && comps == 3) {
00142       uint i, j, k;
00143       const ubyte(*rowA)[3] = (const ubyte(*)[3]) srcRowA;
00144       const ubyte(*rowB)[3] = (const ubyte(*)[3]) srcRowB;
00145       ubyte(*dst)[3] = (ubyte(*)[3]) dstRow;
00146       for (i = j = 0, k = k0; i < (uint) dstWidth;
00147            i++, j += colStride, k += colStride) {
00148          dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
00149          dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
00150          dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
00151       }
00152    }
00153    else if (datatype == UBYTE && comps == 2) {
00154       uint i, j, k;
00155       const ubyte(*rowA)[2] = (const ubyte(*)[2]) srcRowA;
00156       const ubyte(*rowB)[2] = (const ubyte(*)[2]) srcRowB;
00157       ubyte(*dst)[2] = (ubyte(*)[2]) dstRow;
00158       for (i = j = 0, k = k0; i < (uint) dstWidth;
00159            i++, j += colStride, k += colStride) {
00160          dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2;
00161          dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2;
00162       }
00163    }
00164    else if (datatype == UBYTE && comps == 1) {
00165       uint i, j, k;
00166       const ubyte *rowA = (const ubyte *) srcRowA;
00167       const ubyte *rowB = (const ubyte *) srcRowB;
00168       ubyte *dst = (ubyte *) dstRow;
00169       for (i = j = 0, k = k0; i < (uint) dstWidth;
00170            i++, j += colStride, k += colStride) {
00171          dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
00172       }
00173    }
00174 
00175    else if (datatype == USHORT && comps == 4) {
00176       uint i, j, k;
00177       const ushort(*rowA)[4] = (const ushort(*)[4]) srcRowA;
00178       const ushort(*rowB)[4] = (const ushort(*)[4]) srcRowB;
00179       ushort(*dst)[4] = (ushort(*)[4]) dstRow;
00180       for (i = j = 0, k = k0; i < (uint) dstWidth;
00181            i++, j += colStride, k += colStride) {
00182          dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
00183          dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
00184          dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
00185          dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
00186       }
00187    }
00188    else if (datatype == USHORT && comps == 3) {
00189       uint i, j, k;
00190       const ushort(*rowA)[3] = (const ushort(*)[3]) srcRowA;
00191       const ushort(*rowB)[3] = (const ushort(*)[3]) srcRowB;
00192       ushort(*dst)[3] = (ushort(*)[3]) dstRow;
00193       for (i = j = 0, k = k0; i < (uint) dstWidth;
00194            i++, j += colStride, k += colStride) {
00195          dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
00196          dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
00197          dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
00198       }
00199    }
00200    else if (datatype == USHORT && comps == 2) {
00201       uint i, j, k;
00202       const ushort(*rowA)[2] = (const ushort(*)[2]) srcRowA;
00203       const ushort(*rowB)[2] = (const ushort(*)[2]) srcRowB;
00204       ushort(*dst)[2] = (ushort(*)[2]) dstRow;
00205       for (i = j = 0, k = k0; i < (uint) dstWidth;
00206            i++, j += colStride, k += colStride) {
00207          dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
00208          dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
00209       }
00210    }
00211    else if (datatype == USHORT && comps == 1) {
00212       uint i, j, k;
00213       const ushort *rowA = (const ushort *) srcRowA;
00214       const ushort *rowB = (const ushort *) srcRowB;
00215       ushort *dst = (ushort *) dstRow;
00216       for (i = j = 0, k = k0; i < (uint) dstWidth;
00217            i++, j += colStride, k += colStride) {
00218          dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
00219       }
00220    }
00221 
00222    else if (datatype == FLOAT && comps == 4) {
00223       uint i, j, k;
00224       const float(*rowA)[4] = (const float(*)[4]) srcRowA;
00225       const float(*rowB)[4] = (const float(*)[4]) srcRowB;
00226       float(*dst)[4] = (float(*)[4]) dstRow;
00227       for (i = j = 0, k = k0; i < (uint) dstWidth;
00228            i++, j += colStride, k += colStride) {
00229          dst[i][0] = (rowA[j][0] + rowA[k][0] +
00230                       rowB[j][0] + rowB[k][0]) * 0.25F;
00231          dst[i][1] = (rowA[j][1] + rowA[k][1] +
00232                       rowB[j][1] + rowB[k][1]) * 0.25F;
00233          dst[i][2] = (rowA[j][2] + rowA[k][2] +
00234                       rowB[j][2] + rowB[k][2]) * 0.25F;
00235          dst[i][3] = (rowA[j][3] + rowA[k][3] +
00236                       rowB[j][3] + rowB[k][3]) * 0.25F;
00237       }
00238    }
00239    else if (datatype == FLOAT && comps == 3) {
00240       uint i, j, k;
00241       const float(*rowA)[3] = (const float(*)[3]) srcRowA;
00242       const float(*rowB)[3] = (const float(*)[3]) srcRowB;
00243       float(*dst)[3] = (float(*)[3]) dstRow;
00244       for (i = j = 0, k = k0; i < (uint) dstWidth;
00245            i++, j += colStride, k += colStride) {
00246          dst[i][0] = (rowA[j][0] + rowA[k][0] +
00247                       rowB[j][0] + rowB[k][0]) * 0.25F;
00248          dst[i][1] = (rowA[j][1] + rowA[k][1] +
00249                       rowB[j][1] + rowB[k][1]) * 0.25F;
00250          dst[i][2] = (rowA[j][2] + rowA[k][2] +
00251                       rowB[j][2] + rowB[k][2]) * 0.25F;
00252       }
00253    }
00254    else if (datatype == FLOAT && comps == 2) {
00255       uint i, j, k;
00256       const float(*rowA)[2] = (const float(*)[2]) srcRowA;
00257       const float(*rowB)[2] = (const float(*)[2]) srcRowB;
00258       float(*dst)[2] = (float(*)[2]) dstRow;
00259       for (i = j = 0, k = k0; i < (uint) dstWidth;
00260            i++, j += colStride, k += colStride) {
00261          dst[i][0] = (rowA[j][0] + rowA[k][0] +
00262                       rowB[j][0] + rowB[k][0]) * 0.25F;
00263          dst[i][1] = (rowA[j][1] + rowA[k][1] +
00264                       rowB[j][1] + rowB[k][1]) * 0.25F;
00265       }
00266    }
00267    else if (datatype == FLOAT && comps == 1) {
00268       uint i, j, k;
00269       const float *rowA = (const float *) srcRowA;
00270       const float *rowB = (const float *) srcRowB;
00271       float *dst = (float *) dstRow;
00272       for (i = j = 0, k = k0; i < (uint) dstWidth;
00273            i++, j += colStride, k += colStride) {
00274          dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
00275       }
00276    }
00277 
00278 #if 0
00279    else if (datatype == HALF_FLOAT && comps == 4) {
00280       uint i, j, k, comp;
00281       const half_float(*rowA)[4] = (const half_float(*)[4]) srcRowA;
00282       const half_float(*rowB)[4] = (const half_float(*)[4]) srcRowB;
00283       half_float(*dst)[4] = (half_float(*)[4]) dstRow;
00284       for (i = j = 0, k = k0; i < (uint) dstWidth;
00285            i++, j += colStride, k += colStride) {
00286          for (comp = 0; comp < 4; comp++) {
00287             float aj, ak, bj, bk;
00288             aj = half_to_float(rowA[j][comp]);
00289             ak = half_to_float(rowA[k][comp]);
00290             bj = half_to_float(rowB[j][comp]);
00291             bk = half_to_float(rowB[k][comp]);
00292             dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
00293          }
00294       }
00295    }
00296    else if (datatype == HALF_FLOAT && comps == 3) {
00297       uint i, j, k, comp;
00298       const half_float(*rowA)[3] = (const half_float(*)[3]) srcRowA;
00299       const half_float(*rowB)[3] = (const half_float(*)[3]) srcRowB;
00300       half_float(*dst)[3] = (half_float(*)[3]) dstRow;
00301       for (i = j = 0, k = k0; i < (uint) dstWidth;
00302            i++, j += colStride, k += colStride) {
00303          for (comp = 0; comp < 3; comp++) {
00304             float aj, ak, bj, bk;
00305             aj = half_to_float(rowA[j][comp]);
00306             ak = half_to_float(rowA[k][comp]);
00307             bj = half_to_float(rowB[j][comp]);
00308             bk = half_to_float(rowB[k][comp]);
00309             dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
00310          }
00311       }
00312    }
00313    else if (datatype == HALF_FLOAT && comps == 2) {
00314       uint i, j, k, comp;
00315       const half_float(*rowA)[2] = (const half_float(*)[2]) srcRowA;
00316       const half_float(*rowB)[2] = (const half_float(*)[2]) srcRowB;
00317       half_float(*dst)[2] = (half_float(*)[2]) dstRow;
00318       for (i = j = 0, k = k0; i < (uint) dstWidth;
00319            i++, j += colStride, k += colStride) {
00320          for (comp = 0; comp < 2; comp++) {
00321             float aj, ak, bj, bk;
00322             aj = half_to_float(rowA[j][comp]);
00323             ak = half_to_float(rowA[k][comp]);
00324             bj = half_to_float(rowB[j][comp]);
00325             bk = half_to_float(rowB[k][comp]);
00326             dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
00327          }
00328       }
00329    }
00330    else if (datatype == HALF_FLOAT && comps == 1) {
00331       uint i, j, k;
00332       const half_float *rowA = (const half_float *) srcRowA;
00333       const half_float *rowB = (const half_float *) srcRowB;
00334       half_float *dst = (half_float *) dstRow;
00335       for (i = j = 0, k = k0; i < (uint) dstWidth;
00336            i++, j += colStride, k += colStride) {
00337          float aj, ak, bj, bk;
00338          aj = half_to_float(rowA[j]);
00339          ak = half_to_float(rowA[k]);
00340          bj = half_to_float(rowB[j]);
00341          bk = half_to_float(rowB[k]);
00342          dst[i] = float_to_half((aj + ak + bj + bk) * 0.25F);
00343       }
00344    }
00345 #endif
00346 
00347    else if (datatype == UINT && comps == 1) {
00348       uint i, j, k;
00349       const uint *rowA = (const uint *) srcRowA;
00350       const uint *rowB = (const uint *) srcRowB;
00351       uint *dst = (uint *) dstRow;
00352       for (i = j = 0, k = k0; i < (uint) dstWidth;
00353            i++, j += colStride, k += colStride) {
00354          dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
00355       }
00356    }
00357 
00358    else if (datatype == USHORT_5_6_5 && comps == 3) {
00359       uint i, j, k;
00360       const ushort *rowA = (const ushort *) srcRowA;
00361       const ushort *rowB = (const ushort *) srcRowB;
00362       ushort *dst = (ushort *) dstRow;
00363       for (i = j = 0, k = k0; i < (uint) dstWidth;
00364            i++, j += colStride, k += colStride) {
00365          const int rowAr0 = rowA[j] & 0x1f;
00366          const int rowAr1 = rowA[k] & 0x1f;
00367          const int rowBr0 = rowB[j] & 0x1f;
00368          const int rowBr1 = rowB[k] & 0x1f;
00369          const int rowAg0 = (rowA[j] >> 5) & 0x3f;
00370          const int rowAg1 = (rowA[k] >> 5) & 0x3f;
00371          const int rowBg0 = (rowB[j] >> 5) & 0x3f;
00372          const int rowBg1 = (rowB[k] >> 5) & 0x3f;
00373          const int rowAb0 = (rowA[j] >> 11) & 0x1f;
00374          const int rowAb1 = (rowA[k] >> 11) & 0x1f;
00375          const int rowBb0 = (rowB[j] >> 11) & 0x1f;
00376          const int rowBb1 = (rowB[k] >> 11) & 0x1f;
00377          const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
00378          const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
00379          const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
00380          dst[i] = (blue << 11) | (green << 5) | red;
00381       }
00382    }
00383    else if (datatype == USHORT_4_4_4_4 && comps == 4) {
00384       uint i, j, k;
00385       const ushort *rowA = (const ushort *) srcRowA;
00386       const ushort *rowB = (const ushort *) srcRowB;
00387       ushort *dst = (ushort *) dstRow;
00388       for (i = j = 0, k = k0; i < (uint) dstWidth;
00389            i++, j += colStride, k += colStride) {
00390          const int rowAr0 = rowA[j] & 0xf;
00391          const int rowAr1 = rowA[k] & 0xf;
00392          const int rowBr0 = rowB[j] & 0xf;
00393          const int rowBr1 = rowB[k] & 0xf;
00394          const int rowAg0 = (rowA[j] >> 4) & 0xf;
00395          const int rowAg1 = (rowA[k] >> 4) & 0xf;
00396          const int rowBg0 = (rowB[j] >> 4) & 0xf;
00397          const int rowBg1 = (rowB[k] >> 4) & 0xf;
00398          const int rowAb0 = (rowA[j] >> 8) & 0xf;
00399          const int rowAb1 = (rowA[k] >> 8) & 0xf;
00400          const int rowBb0 = (rowB[j] >> 8) & 0xf;
00401          const int rowBb1 = (rowB[k] >> 8) & 0xf;
00402          const int rowAa0 = (rowA[j] >> 12) & 0xf;
00403          const int rowAa1 = (rowA[k] >> 12) & 0xf;
00404          const int rowBa0 = (rowB[j] >> 12) & 0xf;
00405          const int rowBa1 = (rowB[k] >> 12) & 0xf;
00406          const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
00407          const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
00408          const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
00409          const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
00410          dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
00411       }
00412    }
00413    else if (datatype == USHORT_1_5_5_5_REV && comps == 4) {
00414       uint i, j, k;
00415       const ushort *rowA = (const ushort *) srcRowA;
00416       const ushort *rowB = (const ushort *) srcRowB;
00417       ushort *dst = (ushort *) dstRow;
00418       for (i = j = 0, k = k0; i < (uint) dstWidth;
00419            i++, j += colStride, k += colStride) {
00420          const int rowAr0 = rowA[j] & 0x1f;
00421          const int rowAr1 = rowA[k] & 0x1f;
00422          const int rowBr0 = rowB[j] & 0x1f;
00423          const int rowBr1 = rowB[k] & 0x1f;
00424          const int rowAg0 = (rowA[j] >> 5) & 0x1f;
00425          const int rowAg1 = (rowA[k] >> 5) & 0x1f;
00426          const int rowBg0 = (rowB[j] >> 5) & 0x1f;
00427          const int rowBg1 = (rowB[k] >> 5) & 0x1f;
00428          const int rowAb0 = (rowA[j] >> 10) & 0x1f;
00429          const int rowAb1 = (rowA[k] >> 10) & 0x1f;
00430          const int rowBb0 = (rowB[j] >> 10) & 0x1f;
00431          const int rowBb1 = (rowB[k] >> 10) & 0x1f;
00432          const int rowAa0 = (rowA[j] >> 15) & 0x1;
00433          const int rowAa1 = (rowA[k] >> 15) & 0x1;
00434          const int rowBa0 = (rowB[j] >> 15) & 0x1;
00435          const int rowBa1 = (rowB[k] >> 15) & 0x1;
00436          const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
00437          const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
00438          const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
00439          const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
00440          dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
00441       }
00442    }
00443    else if (datatype == UBYTE_3_3_2 && comps == 3) {
00444       uint i, j, k;
00445       const ubyte *rowA = (const ubyte *) srcRowA;
00446       const ubyte *rowB = (const ubyte *) srcRowB;
00447       ubyte *dst = (ubyte *) dstRow;
00448       for (i = j = 0, k = k0; i < (uint) dstWidth;
00449            i++, j += colStride, k += colStride) {
00450          const int rowAr0 = rowA[j] & 0x3;
00451          const int rowAr1 = rowA[k] & 0x3;
00452          const int rowBr0 = rowB[j] & 0x3;
00453          const int rowBr1 = rowB[k] & 0x3;
00454          const int rowAg0 = (rowA[j] >> 2) & 0x7;
00455          const int rowAg1 = (rowA[k] >> 2) & 0x7;
00456          const int rowBg0 = (rowB[j] >> 2) & 0x7;
00457          const int rowBg1 = (rowB[k] >> 2) & 0x7;
00458          const int rowAb0 = (rowA[j] >> 5) & 0x7;
00459          const int rowAb1 = (rowA[k] >> 5) & 0x7;
00460          const int rowBb0 = (rowB[j] >> 5) & 0x7;
00461          const int rowBb1 = (rowB[k] >> 5) & 0x7;
00462          const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
00463          const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
00464          const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
00465          dst[i] = (blue << 5) | (green << 2) | red;
00466       }
00467    }
00468    else {
00469       debug_printf("bad format in do_row()");
00470    }
00471 }

static void fallback_gen_mipmap ( struct gen_mipmap_state ctx,
struct pipe_texture pt,
uint  face,
uint  baseLevel,
uint  lastLevel 
) [static]

Definition at line 673 of file u_gen_mipmap.c.

References assert, make_1d_mipmap(), make_2d_mipmap(), make_3d_mipmap(), PIPE_TEXTURE_1D, PIPE_TEXTURE_2D, PIPE_TEXTURE_3D, PIPE_TEXTURE_CUBE, and pipe_texture::target.

00676 {
00677    switch (pt->target) {
00678    case PIPE_TEXTURE_1D:
00679       make_1d_mipmap(ctx, pt, face, baseLevel, lastLevel);
00680       break;
00681    case PIPE_TEXTURE_2D:
00682    case PIPE_TEXTURE_CUBE:
00683       make_2d_mipmap(ctx, pt, face, baseLevel, lastLevel);
00684       break;
00685    case PIPE_TEXTURE_3D:
00686       make_3d_mipmap(ctx, pt, face, baseLevel, lastLevel);
00687       break;
00688    default:
00689       assert(0);
00690    }
00691 }

static void format_to_type_comps ( enum pipe_format  pformat,
enum dtype datatype,
uint comps 
) [static]

Definition at line 475 of file u_gen_mipmap.c.

References assert, PIPE_FORMAT_A1R5G5B5_UNORM, PIPE_FORMAT_A4R4G4B4_UNORM, PIPE_FORMAT_A8_UNORM, PIPE_FORMAT_A8L8_UNORM, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_FORMAT_I8_UNORM, PIPE_FORMAT_L8_UNORM, PIPE_FORMAT_R5G6B5_UNORM, PIPE_FORMAT_X8R8G8B8_UNORM, UBYTE, USHORT_1_5_5_5_REV, USHORT_4_4_4_4, and USHORT_5_6_5.

00477 {
00478    switch (pformat) {
00479    case PIPE_FORMAT_A8R8G8B8_UNORM:
00480    case PIPE_FORMAT_X8R8G8B8_UNORM:
00481    case PIPE_FORMAT_B8G8R8A8_UNORM:
00482    case PIPE_FORMAT_B8G8R8X8_UNORM:
00483       *datatype = UBYTE;
00484       *comps = 4;
00485       return;
00486    case PIPE_FORMAT_A1R5G5B5_UNORM:
00487       *datatype = USHORT_1_5_5_5_REV;
00488       *comps = 4;
00489       return;
00490    case PIPE_FORMAT_A4R4G4B4_UNORM:
00491       *datatype = USHORT_4_4_4_4;
00492       *comps = 4;
00493       return;
00494    case PIPE_FORMAT_R5G6B5_UNORM:
00495       *datatype = USHORT_5_6_5;
00496       *comps = 3;
00497       return;
00498    case PIPE_FORMAT_L8_UNORM:
00499    case PIPE_FORMAT_A8_UNORM:
00500    case PIPE_FORMAT_I8_UNORM:
00501       *datatype = UBYTE;
00502       *comps = 1;
00503       return;
00504    case PIPE_FORMAT_A8L8_UNORM:
00505       *datatype = UBYTE;
00506       *comps = 2;
00507       return;
00508    default:
00509       assert(0);
00510       *datatype = UBYTE;
00511       *comps = 0;
00512       break;
00513    }
00514 }

static unsigned get_next_slot ( struct gen_mipmap_state ctx  )  [static]

Get next "slot" of vertex space in the vertex buffer.

We're allocating one large vertex buffer and using it piece by piece.

Definition at line 782 of file u_gen_mipmap.c.

References gen_mipmap_state::pipe, pipe_buffer_create(), PIPE_BUFFER_USAGE_VERTEX, pipe_context::screen, util_gen_mipmap_flush(), gen_mipmap_state::vbuf, gen_mipmap_state::vbuf_slot, and gen_mipmap_state::vertices.

00783 {
00784    const unsigned max_slots = 4096 / sizeof ctx->vertices;
00785 
00786    if (ctx->vbuf_slot >= max_slots) 
00787       util_gen_mipmap_flush( ctx );
00788 
00789    if (!ctx->vbuf) {
00790       ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
00791                                      32,
00792                                      PIPE_BUFFER_USAGE_VERTEX,
00793                                      max_slots * sizeof ctx->vertices);
00794    }
00795    
00796    return ctx->vbuf_slot++ * sizeof ctx->vertices;
00797 }

static void make_1d_mipmap ( struct gen_mipmap_state ctx,
struct pipe_texture pt,
uint  face,
uint  baseLevel,
uint  lastLevel 
) [static]

Definition at line 579 of file u_gen_mipmap.c.

References pipe_surface::buffer, pipe_texture::format, pipe_screen::get_tex_surface, pipe_surface::offset, gen_mipmap_state::pipe, pipe_buffer_map(), pipe_buffer_unmap(), PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_surface_reference(), reduce_1d(), pipe_context::screen, and pipe_surface::width.

00582 {
00583    struct pipe_context *pipe = ctx->pipe;
00584    struct pipe_screen *screen = pipe->screen;
00585    const uint zslice = 0;
00586    uint dstLevel;
00587 
00588    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
00589       const uint srcLevel = dstLevel - 1;
00590       struct pipe_surface *srcSurf, *dstSurf;
00591       void *srcMap, *dstMap;
00592       
00593       srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
00594                                         PIPE_BUFFER_USAGE_CPU_READ);
00595 
00596       dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
00597                                         PIPE_BUFFER_USAGE_CPU_WRITE);
00598 
00599       srcMap = ((ubyte *) pipe_buffer_map(screen, srcSurf->buffer,
00600                                           PIPE_BUFFER_USAGE_CPU_READ)
00601                 + srcSurf->offset);
00602       dstMap = ((ubyte *) pipe_buffer_map(screen, dstSurf->buffer,
00603                                           PIPE_BUFFER_USAGE_CPU_WRITE)
00604                 + dstSurf->offset);
00605 
00606       reduce_1d(pt->format,
00607                 srcSurf->width, srcMap,
00608                 dstSurf->width, dstMap);
00609 
00610       pipe_buffer_unmap(screen, srcSurf->buffer);
00611       pipe_buffer_unmap(screen, dstSurf->buffer);
00612 
00613       pipe_surface_reference(&srcSurf, NULL);
00614       pipe_surface_reference(&dstSurf, NULL);
00615    }
00616 }

static void make_2d_mipmap ( struct gen_mipmap_state ctx,
struct pipe_texture pt,
uint  face,
uint  baseLevel,
uint  lastLevel 
) [static]

Definition at line 620 of file u_gen_mipmap.c.

References assert, pipe_texture::block, pipe_surface::buffer, pipe_texture::format, pipe_screen::get_tex_surface, pipe_surface::height, pipe_format_block::height, pipe_surface::offset, gen_mipmap_state::pipe, pipe_buffer_map(), pipe_buffer_unmap(), PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_surface_reference(), reduce_2d(), pipe_context::screen, pipe_surface::stride, pipe_surface::width, and pipe_format_block::width.

00623 {
00624    struct pipe_context *pipe = ctx->pipe;
00625    struct pipe_screen *screen = pipe->screen;
00626    const uint zslice = 0;
00627    uint dstLevel;
00628    
00629    assert(pt->block.width == 1);
00630    assert(pt->block.height == 1);
00631 
00632    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
00633       const uint srcLevel = dstLevel - 1;
00634       struct pipe_surface *srcSurf, *dstSurf;
00635       ubyte *srcMap, *dstMap;
00636       
00637       srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
00638                                         PIPE_BUFFER_USAGE_CPU_READ);
00639       dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
00640                                         PIPE_BUFFER_USAGE_CPU_WRITE);
00641 
00642       srcMap = ((ubyte *) pipe_buffer_map(screen, srcSurf->buffer,
00643                                           PIPE_BUFFER_USAGE_CPU_READ)
00644                 + srcSurf->offset);
00645       dstMap = ((ubyte *) pipe_buffer_map(screen, dstSurf->buffer,
00646                                           PIPE_BUFFER_USAGE_CPU_WRITE)
00647                 + dstSurf->offset);
00648 
00649       reduce_2d(pt->format,
00650                 srcSurf->width, srcSurf->height,
00651                 srcSurf->stride, srcMap,
00652                 dstSurf->width, dstSurf->height,
00653                 dstSurf->stride, dstMap);
00654 
00655       pipe_buffer_unmap(screen, srcSurf->buffer);
00656       pipe_buffer_unmap(screen, dstSurf->buffer);
00657 
00658       pipe_surface_reference(&srcSurf, NULL);
00659       pipe_surface_reference(&dstSurf, NULL);
00660    }
00661 }

static void make_3d_mipmap ( struct gen_mipmap_state ctx,
struct pipe_texture pt,
uint  face,
uint  baseLevel,
uint  lastLevel 
) [static]

Definition at line 665 of file u_gen_mipmap.c.

00668 {
00669 }

static void reduce_1d ( enum pipe_format  pformat,
int  srcWidth,
const ubyte srcPtr,
int  dstWidth,
ubyte dstPtr 
) [static]

Definition at line 518 of file u_gen_mipmap.c.

References do_row(), and format_to_type_comps().

00521 {
00522    enum dtype datatype;
00523    uint comps;
00524 
00525    format_to_type_comps(pformat, &datatype, &comps);
00526 
00527    /* we just duplicate the input row, kind of hack, saves code */
00528    do_row(datatype, comps,
00529           srcWidth, srcPtr, srcPtr,
00530           dstWidth, dstPtr);
00531 }

static void reduce_2d ( enum pipe_format  pformat,
int  srcWidth,
int  srcHeight,
int  srcRowStride,
const ubyte srcPtr,
int  dstWidth,
int  dstHeight,
int  dstRowStride,
ubyte dstPtr 
) [static]

Strides are in bytes.

If zero, it'll be computed as width * bpp.

Definition at line 538 of file u_gen_mipmap.c.

References do_row(), format_to_type_comps(), and pf_get_size().

00543 {
00544    enum dtype datatype;
00545    uint comps;
00546    const int bpt = pf_get_size(pformat);
00547    const ubyte *srcA, *srcB;
00548    ubyte *dst;
00549    int row;
00550 
00551    format_to_type_comps(pformat, &datatype, &comps);
00552 
00553    if (!srcRowStride)
00554       srcRowStride = bpt * srcWidth;
00555 
00556    if (!dstRowStride)
00557       dstRowStride = bpt * dstWidth;
00558 
00559    /* Compute src and dst pointers */
00560    srcA = srcPtr;
00561    if (srcHeight > 1) 
00562       srcB = srcA + srcRowStride;
00563    else
00564       srcB = srcA;
00565    dst = dstPtr;
00566 
00567    for (row = 0; row < dstHeight; row++) {
00568       do_row(datatype, comps,
00569              srcWidth, srcA, srcB,
00570              dstWidth, dst);
00571       srcA += 2 * srcRowStride;
00572       srcB += 2 * srcRowStride;
00573       dst += dstRowStride;
00574    }
00575 }

static unsigned set_vertex_data ( struct gen_mipmap_state ctx,
float  width,
float  height 
) [static]

Definition at line 801 of file u_gen_mipmap.c.

References get_next_slot(), offset(), gen_mipmap_state::pipe, pipe_buffer_map(), pipe_buffer_unmap(), PIPE_BUFFER_USAGE_CPU_WRITE, pipe_context::screen, gen_mipmap_state::vbuf, and gen_mipmap_state::vertices.

00802 {
00803    void *buf;
00804    unsigned offset;
00805 
00806    ctx->vertices[0][0][0] = 0.0f; /*x*/
00807    ctx->vertices[0][0][1] = 0.0f; /*y*/
00808    ctx->vertices[0][1][0] = 0.0f; /*s*/
00809    ctx->vertices[0][1][1] = 0.0f; /*t*/
00810 
00811    ctx->vertices[1][0][0] = width;
00812    ctx->vertices[1][0][1] = 0.0f;
00813    ctx->vertices[1][1][0] = 1.0f;
00814    ctx->vertices[1][1][1] = 0.0f;
00815 
00816    ctx->vertices[2][0][0] = width;
00817    ctx->vertices[2][0][1] = height;
00818    ctx->vertices[2][1][0] = 1.0f;
00819    ctx->vertices[2][1][1] = 1.0f;
00820 
00821    ctx->vertices[3][0][0] = 0.0f;
00822    ctx->vertices[3][0][1] = height;
00823    ctx->vertices[3][1][0] = 0.0f;
00824    ctx->vertices[3][1][1] = 1.0f;
00825 
00826    offset = get_next_slot( ctx );
00827 
00828    buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf,
00829                          PIPE_BUFFER_USAGE_CPU_WRITE);
00830 
00831    memcpy((char *)buf + offset, ctx->vertices, sizeof(ctx->vertices));
00832 
00833    pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf);
00834 
00835    return offset;
00836 }

struct gen_mipmap_state* util_create_gen_mipmap ( struct pipe_context pipe,
struct cso_context cso 
) [read]

Create a mipmap generation context.

The idea is to create one of these and re-use it each time we need to generate a mipmap.

Definition at line 700 of file u_gen_mipmap.c.

References pipe_blend_state::alpha_dst_factor, pipe_blend_state::alpha_src_factor, gen_mipmap_state::blend, pipe_rasterizer_state::bypass_clipping, CALLOC_STRUCT, pipe_blend_state::colormask, gen_mipmap_state::cso, pipe_rasterizer_state::cull_mode, gen_mipmap_state::depthstencil, gen_mipmap_state::frag_shader, pipe_rasterizer_state::front_winding, gen_mipmap_state::fs, pipe_rasterizer_state::gl_rasterization_rules, pipe_sampler_state::min_mip_filter, pipe_sampler_state::normalized_coords, gen_mipmap_state::pipe, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO, PIPE_MASK_RGBA, PIPE_TEX_MIPFILTER_NEAREST, PIPE_TEX_WRAP_CLAMP_TO_EDGE, PIPE_WINDING_CW, PIPE_WINDING_NONE, gen_mipmap_state::rasterizer, pipe_blend_state::rgb_dst_factor, pipe_blend_state::rgb_src_factor, gen_mipmap_state::sampler, pipe_viewport_state::scale, semantic_names, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_POSITION, pipe_viewport_state::translate, util_make_fragment_tex_shader(), util_make_vertex_passthrough_shader(), gen_mipmap_state::vert_shader, gen_mipmap_state::vertices, gen_mipmap_state::viewport, gen_mipmap_state::vs, pipe_sampler_state::wrap_r, pipe_sampler_state::wrap_s, and pipe_sampler_state::wrap_t.

00702 {
00703    struct gen_mipmap_state *ctx;
00704    uint i;
00705 
00706    ctx = CALLOC_STRUCT(gen_mipmap_state);
00707    if (!ctx)
00708       return NULL;
00709 
00710    ctx->pipe = pipe;
00711    ctx->cso = cso;
00712 
00713    /* disabled blending/masking */
00714    memset(&ctx->blend, 0, sizeof(ctx->blend));
00715    ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
00716    ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
00717    ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
00718    ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
00719    ctx->blend.colormask = PIPE_MASK_RGBA;
00720 
00721    /* no-op depth/stencil/alpha */
00722    memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
00723 
00724    /* rasterizer */
00725    memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
00726    ctx->rasterizer.front_winding = PIPE_WINDING_CW;
00727    ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
00728    ctx->rasterizer.bypass_clipping = 1;
00729    /*ctx->rasterizer.bypass_vs = 1;*/
00730    ctx->rasterizer.gl_rasterization_rules = 1;
00731 
00732    /* sampler state */
00733    memset(&ctx->sampler, 0, sizeof(ctx->sampler));
00734    ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
00735    ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
00736    ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
00737    ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
00738    ctx->sampler.normalized_coords = 1;
00739 
00740    /* viewport state (identity, verts are in wincoords) */
00741    ctx->viewport.scale[0] = 1.0;
00742    ctx->viewport.scale[1] = 1.0;
00743    ctx->viewport.scale[2] = 1.0;
00744    ctx->viewport.scale[3] = 1.0;
00745    ctx->viewport.translate[0] = 0.0;
00746    ctx->viewport.translate[1] = 0.0;
00747    ctx->viewport.translate[2] = 0.0;
00748    ctx->viewport.translate[3] = 0.0;
00749 
00750    /* vertex shader */
00751    {
00752       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
00753                                       TGSI_SEMANTIC_GENERIC };
00754       const uint semantic_indexes[] = { 0, 0 };
00755       ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
00756                                                     semantic_indexes,
00757                                                     &ctx->vert_shader);
00758    }
00759 
00760    /* fragment shader */
00761    ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader);
00762 
00763    /* vertex data that doesn't change */
00764    for (i = 0; i < 4; i++) {
00765       ctx->vertices[i][0][2] = 0.0f; /* z */
00766       ctx->vertices[i][0][3] = 1.0f; /* w */
00767       ctx->vertices[i][1][2] = 0.0f; /* r */
00768       ctx->vertices[i][1][3] = 1.0f; /* q */
00769    }
00770 
00771    /* Note: the actual vertex buffer is allocated as needed below */
00772 
00773    return ctx;
00774 }

void util_destroy_gen_mipmap ( struct gen_mipmap_state ctx  ) 

Destroy a mipmap generation context.

Definition at line 844 of file u_gen_mipmap.c.

References pipe_context::delete_fs_state, pipe_context::delete_vs_state, gen_mipmap_state::frag_shader, FREE, gen_mipmap_state::fs, gen_mipmap_state::pipe, pipe_buffer_reference(), pipe_context::screen, pipe_shader_state::tokens, gen_mipmap_state::vbuf, gen_mipmap_state::vert_shader, and gen_mipmap_state::vs.

00845 {
00846    struct pipe_context *pipe = ctx->pipe;
00847 
00848    pipe->delete_vs_state(pipe, ctx->vs);
00849    pipe->delete_fs_state(pipe, ctx->fs);
00850 
00851    FREE((void*) ctx->vert_shader.tokens);
00852    FREE((void*) ctx->frag_shader.tokens);
00853 
00854    pipe_buffer_reference(pipe->screen, &ctx->vbuf, NULL);
00855 
00856    FREE(ctx);
00857 }

void util_gen_mipmap ( struct gen_mipmap_state ctx,
struct pipe_texture pt,
uint  face,
uint  baseLevel,
uint  lastLevel,
uint  filter 
)

Generate mipmap images.

It's assumed all needed texture memory is already allocated.

Parameters:
pt the texture to generate mipmap levels for
face which cube face to generate mipmaps for (0 for non-cube maps)
baseLevel the first mipmap level to use as a src
lastLevel the last mipmap level to generate
filter the minification filter used to generate mipmap levels with
filter one of PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST

Definition at line 883 of file u_gen_mipmap.c.

References gen_mipmap_state::blend, pipe_framebuffer_state::cbufs, gen_mipmap_state::cso, cso_restore_blend(), cso_restore_depth_stencil_alpha(), cso_restore_fragment_shader(), cso_restore_framebuffer(), cso_restore_rasterizer(), cso_restore_sampler_textures(), cso_restore_samplers(), cso_restore_vertex_shader(), cso_restore_viewport(), cso_save_blend(), cso_save_depth_stencil_alpha(), cso_save_fragment_shader(), cso_save_framebuffer(), cso_save_rasterizer(), cso_save_sampler_textures(), cso_save_samplers(), cso_save_vertex_shader(), cso_save_viewport(), cso_set_blend(), cso_set_depth_stencil_alpha(), cso_set_fragment_shader_handle(), cso_set_framebuffer(), cso_set_rasterizer(), cso_set_sampler_textures(), cso_set_vertex_shader_handle(), cso_set_viewport(), cso_single_sampler(), cso_single_sampler_done(), gen_mipmap_state::depthstencil, fallback_gen_mipmap(), pipe_context::flush, pipe_texture::format, gen_mipmap_state::fs, pipe_screen::get_tex_surface, pipe_texture::height, pipe_framebuffer_state::height, pipe_screen::is_format_supported, pipe_sampler_state::lod_bias, pipe_sampler_state::mag_img_filter, pipe_sampler_state::max_lod, pipe_sampler_state::min_img_filter, pipe_sampler_state::min_lod, pipe_framebuffer_state::num_cbufs, offset(), gen_mipmap_state::pipe, PIPE_BUFFER_USAGE_GPU_WRITE, PIPE_FLUSH_RENDER_CACHE, PIPE_PRIM_TRIANGLE_FAN, pipe_surface_reference(), PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, gen_mipmap_state::rasterizer, gen_mipmap_state::sampler, pipe_context::screen, set_vertex_data(), util_draw_vertex_buffer(), gen_mipmap_state::vbuf, gen_mipmap_state::viewport, gen_mipmap_state::vs, pipe_texture::width, and pipe_framebuffer_state::width.

00886 {
00887    struct pipe_context *pipe = ctx->pipe;
00888    struct pipe_screen *screen = pipe->screen;
00889    struct pipe_framebuffer_state fb;
00890    uint dstLevel;
00891    uint zslice = 0;
00892    uint offset;
00893 
00894    /* check if we can render in the texture's format */
00895    if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D,
00896                                     PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
00897       fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
00898       return;
00899    }
00900 
00901    /* save state (restored below) */
00902    cso_save_blend(ctx->cso);
00903    cso_save_depth_stencil_alpha(ctx->cso);
00904    cso_save_rasterizer(ctx->cso);
00905    cso_save_samplers(ctx->cso);
00906    cso_save_sampler_textures(ctx->cso);
00907    cso_save_framebuffer(ctx->cso);
00908    cso_save_fragment_shader(ctx->cso);
00909    cso_save_vertex_shader(ctx->cso);
00910    cso_save_viewport(ctx->cso);
00911 
00912    /* bind our state */
00913    cso_set_blend(ctx->cso, &ctx->blend);
00914    cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
00915    cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
00916    cso_set_viewport(ctx->cso, &ctx->viewport);
00917 
00918    cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
00919    cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
00920 
00921    /* init framebuffer state */
00922    memset(&fb, 0, sizeof(fb));
00923    fb.num_cbufs = 1;
00924 
00925    /* set min/mag to same filter for faster sw speed */
00926    ctx->sampler.mag_img_filter = filter;
00927    ctx->sampler.min_img_filter = filter;
00928 
00929    /*
00930     * XXX for small mipmap levels, it may be faster to use the software
00931     * fallback path...
00932     */
00933    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
00934       const uint srcLevel = dstLevel - 1;
00935 
00936       struct pipe_surface *surf = 
00937          screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
00938                                  PIPE_BUFFER_USAGE_GPU_WRITE);
00939 
00940       /*
00941        * Setup framebuffer / dest surface
00942        */
00943       fb.cbufs[0] = surf;
00944       fb.width = pt->width[dstLevel];
00945       fb.height = pt->height[dstLevel];
00946       cso_set_framebuffer(ctx->cso, &fb);
00947 
00948       /*
00949        * Setup sampler state
00950        * Note: we should only have to set the min/max LOD clamps to ensure
00951        * we grab texels from the right mipmap level.  But some hardware
00952        * has trouble with min clamping so we also set the lod_bias to
00953        * try to work around that.
00954        */
00955       ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel;
00956       ctx->sampler.lod_bias = (float) srcLevel;
00957       cso_single_sampler(ctx->cso, 0, &ctx->sampler);
00958       cso_single_sampler_done(ctx->cso);
00959 
00960       cso_set_sampler_textures(ctx->cso, 1, &pt);
00961 
00962       /* quad coords in window coords (bypassing clipping, viewport mapping) */
00963       offset = set_vertex_data(ctx,
00964                                (float) pt->width[dstLevel],
00965                                (float) pt->height[dstLevel]);
00966 
00967       util_draw_vertex_buffer(ctx->pipe, 
00968                               ctx->vbuf,
00969                               offset,
00970                               PIPE_PRIM_TRIANGLE_FAN,
00971                               4,  /* verts */
00972                               2); /* attribs/vert */
00973 
00974       pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
00975 
00976       /* need to signal that the texture has changed _after_ rendering to it */
00977       pipe_surface_reference( &surf, NULL );
00978    }
00979 
00980    /* restore state we changed */
00981    cso_restore_blend(ctx->cso);
00982    cso_restore_depth_stencil_alpha(ctx->cso);
00983    cso_restore_rasterizer(ctx->cso);
00984    cso_restore_samplers(ctx->cso);
00985    cso_restore_sampler_textures(ctx->cso);
00986    cso_restore_framebuffer(ctx->cso);
00987    cso_restore_fragment_shader(ctx->cso);
00988    cso_restore_vertex_shader(ctx->cso);
00989    cso_restore_viewport(ctx->cso);
00990 }

void util_gen_mipmap_flush ( struct gen_mipmap_state ctx  ) 

Definition at line 864 of file u_gen_mipmap.c.

References gen_mipmap_state::pipe, pipe_buffer_reference(), pipe_context::screen, gen_mipmap_state::vbuf, and gen_mipmap_state::vbuf_slot.

00865 {
00866    pipe_buffer_reference(ctx->pipe->screen, &ctx->vbuf, NULL);
00867    ctx->vbuf_slot = 0;
00868 } 


Generated on Tue Sep 29 06:25:28 2009 for Gallium3D by  doxygen 1.5.4