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_state * | util_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. |
Definition in file u_gen_mipmap.c.
typedef ushort half_float |
Definition at line 93 of file u_gen_mipmap.c.
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 |
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 };
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.
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] |
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.
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 }