00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00036 #include "pipe/p_context.h"
00037 #include "pipe/p_debug.h"
00038 #include "pipe/p_defines.h"
00039 #include "pipe/p_inlines.h"
00040 #include "pipe/p_winsys.h"
00041 #include "pipe/p_shader_tokens.h"
00042
00043 #include "util/u_memory.h"
00044 #include "util/u_draw_quad.h"
00045 #include "util/u_gen_mipmap.h"
00046 #include "util/u_simple_shaders.h"
00047
00048 #include "tgsi/tgsi_build.h"
00049 #include "tgsi/tgsi_dump.h"
00050 #include "tgsi/tgsi_parse.h"
00051
00052 #include "cso_cache/cso_context.h"
00053
00054
00055 struct gen_mipmap_state
00056 {
00057 struct pipe_context *pipe;
00058 struct cso_context *cso;
00059
00060 struct pipe_blend_state blend;
00061 struct pipe_depth_stencil_alpha_state depthstencil;
00062 struct pipe_rasterizer_state rasterizer;
00063 struct pipe_sampler_state sampler;
00064 struct pipe_viewport_state viewport;
00065
00066 struct pipe_shader_state vert_shader;
00067 struct pipe_shader_state frag_shader;
00068 void *vs;
00069 void *fs;
00070
00071 struct pipe_buffer *vbuf;
00072 unsigned vbuf_slot;
00073
00074 float vertices[4][2][4];
00075 };
00076
00077
00078
00079 enum dtype
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 };
00091
00092
00093 typedef ushort half_float;
00094
00095
00096 #if 0
00097 extern half_float
00098 float_to_half(float f);
00099
00100 extern float
00101 half_to_float(half_float h);
00102 #endif
00103
00104
00113 static void
00114 do_row(enum dtype datatype, uint comps, int srcWidth,
00115 const void *srcRowA, const void *srcRowB,
00116 int dstWidth, void *dstRow)
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
00125
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 }
00472
00473
00474 static void
00475 format_to_type_comps(enum pipe_format pformat,
00476 enum dtype *datatype, uint *comps)
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 }
00515
00516
00517 static void
00518 reduce_1d(enum pipe_format pformat,
00519 int srcWidth, const ubyte *srcPtr,
00520 int dstWidth, ubyte *dstPtr)
00521 {
00522 enum dtype datatype;
00523 uint comps;
00524
00525 format_to_type_comps(pformat, &datatype, &comps);
00526
00527
00528 do_row(datatype, comps,
00529 srcWidth, srcPtr, srcPtr,
00530 dstWidth, dstPtr);
00531 }
00532
00533
00537 static void
00538 reduce_2d(enum pipe_format pformat,
00539 int srcWidth, int srcHeight,
00540 int srcRowStride, const ubyte *srcPtr,
00541 int dstWidth, int dstHeight,
00542 int dstRowStride, ubyte *dstPtr)
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
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 }
00576
00577
00578 static void
00579 make_1d_mipmap(struct gen_mipmap_state *ctx,
00580 struct pipe_texture *pt,
00581 uint face, uint baseLevel, uint lastLevel)
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 }
00617
00618
00619 static void
00620 make_2d_mipmap(struct gen_mipmap_state *ctx,
00621 struct pipe_texture *pt,
00622 uint face, uint baseLevel, uint lastLevel)
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 }
00662
00663
00664 static void
00665 make_3d_mipmap(struct gen_mipmap_state *ctx,
00666 struct pipe_texture *pt,
00667 uint face, uint baseLevel, uint lastLevel)
00668 {
00669 }
00670
00671
00672 static void
00673 fallback_gen_mipmap(struct gen_mipmap_state *ctx,
00674 struct pipe_texture *pt,
00675 uint face, uint baseLevel, uint lastLevel)
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 }
00692
00693
00699 struct gen_mipmap_state *
00700 util_create_gen_mipmap(struct pipe_context *pipe,
00701 struct cso_context *cso)
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
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
00722 memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
00723
00724
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
00730 ctx->rasterizer.gl_rasterization_rules = 1;
00731
00732
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
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
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
00761 ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader);
00762
00763
00764 for (i = 0; i < 4; i++) {
00765 ctx->vertices[i][0][2] = 0.0f;
00766 ctx->vertices[i][0][3] = 1.0f;
00767 ctx->vertices[i][1][2] = 0.0f;
00768 ctx->vertices[i][1][3] = 1.0f;
00769 }
00770
00771
00772
00773 return ctx;
00774 }
00775
00776
00781 static unsigned
00782 get_next_slot(struct gen_mipmap_state *ctx)
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 }
00798
00799
00800 static unsigned
00801 set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
00802 {
00803 void *buf;
00804 unsigned offset;
00805
00806 ctx->vertices[0][0][0] = 0.0f;
00807 ctx->vertices[0][0][1] = 0.0f;
00808 ctx->vertices[0][1][0] = 0.0f;
00809 ctx->vertices[0][1][1] = 0.0f;
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 }
00837
00838
00839
00843 void
00844 util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
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 }
00858
00859
00860
00861
00862
00863
00864 void util_gen_mipmap_flush( struct gen_mipmap_state *ctx )
00865 {
00866 pipe_buffer_reference(ctx->pipe->screen, &ctx->vbuf, NULL);
00867 ctx->vbuf_slot = 0;
00868 }
00869
00870
00882 void
00883 util_gen_mipmap(struct gen_mipmap_state *ctx,
00884 struct pipe_texture *pt,
00885 uint face, uint baseLevel, uint lastLevel, uint filter)
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
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
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
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
00922 memset(&fb, 0, sizeof(fb));
00923 fb.num_cbufs = 1;
00924
00925
00926 ctx->sampler.mag_img_filter = filter;
00927 ctx->sampler.min_img_filter = filter;
00928
00929
00930
00931
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
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
00950
00951
00952
00953
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
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,
00972 2);
00973
00974 pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
00975
00976
00977 pipe_surface_reference( &surf, NULL );
00978 }
00979
00980
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 }