X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_gen_mipmap.c;h=ca797486a0e023f9e623c4ddee123f556fcc4d01;hb=a18e209edb5348eb167e9d7184597031bbbbe622;hp=5f395ec6e9ae47d5b7c7caec663577ed6bba293a;hpb=56f36ed16662f83e0cb29c2c08dce4ce0d3f4912;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 5f395ec6e9a..ca797486a0e 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -2,6 +2,7 @@ * * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. + * Copyright 2008 VMware, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -34,11 +35,11 @@ #include "pipe/p_context.h" -#include "pipe/p_debug.h" +#include "util/u_debug.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_winsys.h" #include "pipe/p_shader_tokens.h" +#include "pipe/p_state.h" #include "util/u_memory.h" #include "util/u_draw_quad.h" @@ -61,10 +62,7 @@ struct gen_mipmap_state struct pipe_depth_stencil_alpha_state depthstencil; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; - struct pipe_viewport_state viewport; - struct pipe_shader_state vert_shader; - struct pipe_shader_state frag_shader; void *vs; void *fs; @@ -78,28 +76,97 @@ struct gen_mipmap_state 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 + DTYPE_UBYTE, + DTYPE_UBYTE_3_3_2, + DTYPE_USHORT, + DTYPE_USHORT_4_4_4_4, + DTYPE_USHORT_5_6_5, + DTYPE_USHORT_1_5_5_5_REV, + DTYPE_UINT, + DTYPE_FLOAT, + DTYPE_HALF_FLOAT }; typedef ushort half_float; -#if 0 -extern half_float -float_to_half(float f); +static half_float +float_to_half(float f) +{ + /* XXX fix this */ + return 0; +} + +static float +half_to_float(half_float h) +{ + /* XXX fix this */ + return 0.0f; +} + -extern float -half_to_float(half_float h); -#endif + + +/** + * \name Support macros for do_row and do_row_3d + * + * The macro madness is here for two reasons. First, it compacts the code + * slightly. Second, it makes it much easier to adjust the specifics of the + * filter to tune the rounding characteristics. + */ +/*@{*/ +#define DECLARE_ROW_POINTERS(t, e) \ + const t(*rowA)[e] = (const t(*)[e]) srcRowA; \ + const t(*rowB)[e] = (const t(*)[e]) srcRowB; \ + const t(*rowC)[e] = (const t(*)[e]) srcRowC; \ + const t(*rowD)[e] = (const t(*)[e]) srcRowD; \ + t(*dst)[e] = (t(*)[e]) dstRow + +#define DECLARE_ROW_POINTERS0(t) \ + const t *rowA = (const t *) srcRowA; \ + const t *rowB = (const t *) srcRowB; \ + const t *rowC = (const t *) srcRowC; \ + const t *rowD = (const t *) srcRowD; \ + t *dst = (t *) dstRow + +#define FILTER_SUM_3D(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \ + ((unsigned) Aj + (unsigned) Ak \ + + (unsigned) Bj + (unsigned) Bk \ + + (unsigned) Cj + (unsigned) Ck \ + + (unsigned) Dj + (unsigned) Dk \ + + 4) >> 3 + +#define FILTER_3D(e) \ + do { \ + dst[i][e] = FILTER_SUM_3D(rowA[j][e], rowA[k][e], \ + rowB[j][e], rowB[k][e], \ + rowC[j][e], rowC[k][e], \ + rowD[j][e], rowD[k][e]); \ + } while(0) + +#define FILTER_F_3D(e) \ + do { \ + dst[i][e] = (rowA[j][e] + rowA[k][e] \ + + rowB[j][e] + rowB[k][e] \ + + rowC[j][e] + rowC[k][e] \ + + rowD[j][e] + rowD[k][e]) * 0.125F; \ + } while(0) + +#define FILTER_HF_3D(e) \ + do { \ + const float aj = half_to_float(rowA[j][e]); \ + const float ak = half_to_float(rowA[k][e]); \ + const float bj = half_to_float(rowB[j][e]); \ + const float bk = half_to_float(rowB[k][e]); \ + const float cj = half_to_float(rowC[j][e]); \ + const float ck = half_to_float(rowC[k][e]); \ + const float dj = half_to_float(rowD[j][e]); \ + const float dk = half_to_float(rowD[k][e]); \ + dst[i][e] = float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \ + * 0.125F); \ + } while(0) +/*@}*/ /** @@ -125,7 +192,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); */ - if (datatype == UBYTE && comps == 4) { + if (datatype == DTYPE_UBYTE && comps == 4) { uint i, j, k; const ubyte(*rowA)[4] = (const ubyte(*)[4]) srcRowA; const ubyte(*rowB)[4] = (const ubyte(*)[4]) srcRowB; @@ -138,7 +205,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; } } - else if (datatype == UBYTE && comps == 3) { + else if (datatype == DTYPE_UBYTE && comps == 3) { uint i, j, k; const ubyte(*rowA)[3] = (const ubyte(*)[3]) srcRowA; const ubyte(*rowB)[3] = (const ubyte(*)[3]) srcRowB; @@ -150,7 +217,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; } } - else if (datatype == UBYTE && comps == 2) { + else if (datatype == DTYPE_UBYTE && comps == 2) { uint i, j, k; const ubyte(*rowA)[2] = (const ubyte(*)[2]) srcRowA; const ubyte(*rowB)[2] = (const ubyte(*)[2]) srcRowB; @@ -161,7 +228,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2; } } - else if (datatype == UBYTE && comps == 1) { + else if (datatype == DTYPE_UBYTE && comps == 1) { uint i, j, k; const ubyte *rowA = (const ubyte *) srcRowA; const ubyte *rowB = (const ubyte *) srcRowB; @@ -172,7 +239,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } } - else if (datatype == USHORT && comps == 4) { + else if (datatype == DTYPE_USHORT && comps == 4) { uint i, j, k; const ushort(*rowA)[4] = (const ushort(*)[4]) srcRowA; const ushort(*rowB)[4] = (const ushort(*)[4]) srcRowB; @@ -185,7 +252,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; } } - else if (datatype == USHORT && comps == 3) { + else if (datatype == DTYPE_USHORT && comps == 3) { uint i, j, k; const ushort(*rowA)[3] = (const ushort(*)[3]) srcRowA; const ushort(*rowB)[3] = (const ushort(*)[3]) srcRowB; @@ -197,7 +264,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; } } - else if (datatype == USHORT && comps == 2) { + else if (datatype == DTYPE_USHORT && comps == 2) { uint i, j, k; const ushort(*rowA)[2] = (const ushort(*)[2]) srcRowA; const ushort(*rowB)[2] = (const ushort(*)[2]) srcRowB; @@ -208,7 +275,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; } } - else if (datatype == USHORT && comps == 1) { + else if (datatype == DTYPE_USHORT && comps == 1) { uint i, j, k; const ushort *rowA = (const ushort *) srcRowA; const ushort *rowB = (const ushort *) srcRowB; @@ -219,7 +286,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } } - else if (datatype == FLOAT && comps == 4) { + else if (datatype == DTYPE_FLOAT && comps == 4) { uint i, j, k; const float(*rowA)[4] = (const float(*)[4]) srcRowA; const float(*rowB)[4] = (const float(*)[4]) srcRowB; @@ -236,7 +303,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, rowB[j][3] + rowB[k][3]) * 0.25F; } } - else if (datatype == FLOAT && comps == 3) { + else if (datatype == DTYPE_FLOAT && comps == 3) { uint i, j, k; const float(*rowA)[3] = (const float(*)[3]) srcRowA; const float(*rowB)[3] = (const float(*)[3]) srcRowB; @@ -251,7 +318,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, rowB[j][2] + rowB[k][2]) * 0.25F; } } - else if (datatype == FLOAT && comps == 2) { + else if (datatype == DTYPE_FLOAT && comps == 2) { uint i, j, k; const float(*rowA)[2] = (const float(*)[2]) srcRowA; const float(*rowB)[2] = (const float(*)[2]) srcRowB; @@ -264,7 +331,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, rowB[j][1] + rowB[k][1]) * 0.25F; } } - else if (datatype == FLOAT && comps == 1) { + else if (datatype == DTYPE_FLOAT && comps == 1) { uint i, j, k; const float *rowA = (const float *) srcRowA; const float *rowB = (const float *) srcRowB; @@ -276,7 +343,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } #if 0 - else if (datatype == HALF_FLOAT && comps == 4) { + else if (datatype == HALF_DTYPE_FLOAT && comps == 4) { uint i, j, k, comp; const half_float(*rowA)[4] = (const half_float(*)[4]) srcRowA; const half_float(*rowB)[4] = (const half_float(*)[4]) srcRowB; @@ -293,7 +360,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } } } - else if (datatype == HALF_FLOAT && comps == 3) { + else if (datatype == DTYPE_HALF_FLOAT && comps == 3) { uint i, j, k, comp; const half_float(*rowA)[3] = (const half_float(*)[3]) srcRowA; const half_float(*rowB)[3] = (const half_float(*)[3]) srcRowB; @@ -310,7 +377,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } } } - else if (datatype == HALF_FLOAT && comps == 2) { + else if (datatype == DTYPE_HALF_FLOAT && comps == 2) { uint i, j, k, comp; const half_float(*rowA)[2] = (const half_float(*)[2]) srcRowA; const half_float(*rowB)[2] = (const half_float(*)[2]) srcRowB; @@ -327,7 +394,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } } } - else if (datatype == HALF_FLOAT && comps == 1) { + else if (datatype == DTYPE_HALF_FLOAT && comps == 1) { uint i, j, k; const half_float *rowA = (const half_float *) srcRowA; const half_float *rowB = (const half_float *) srcRowB; @@ -344,7 +411,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } #endif - else if (datatype == UINT && comps == 1) { + else if (datatype == DTYPE_UINT && comps == 1) { uint i, j, k; const uint *rowA = (const uint *) srcRowA; const uint *rowB = (const uint *) srcRowB; @@ -355,7 +422,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } } - else if (datatype == USHORT_5_6_5 && comps == 3) { + else if (datatype == DTYPE_USHORT_5_6_5 && comps == 3) { uint i, j, k; const ushort *rowA = (const ushort *) srcRowA; const ushort *rowB = (const ushort *) srcRowB; @@ -380,7 +447,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i] = (blue << 11) | (green << 5) | red; } } - else if (datatype == USHORT_4_4_4_4 && comps == 4) { + else if (datatype == DTYPE_USHORT_4_4_4_4 && comps == 4) { uint i, j, k; const ushort *rowA = (const ushort *) srcRowA; const ushort *rowB = (const ushort *) srcRowB; @@ -410,7 +477,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; } } - else if (datatype == USHORT_1_5_5_5_REV && comps == 4) { + else if (datatype == DTYPE_USHORT_1_5_5_5_REV && comps == 4) { uint i, j, k; const ushort *rowA = (const ushort *) srcRowA; const ushort *rowB = (const ushort *) srcRowB; @@ -420,7 +487,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, const int rowAr0 = rowA[j] & 0x1f; const int rowAr1 = rowA[k] & 0x1f; const int rowBr0 = rowB[j] & 0x1f; - const int rowBr1 = rowB[k] & 0xf; + const int rowBr1 = rowB[k] & 0x1f; const int rowAg0 = (rowA[j] >> 5) & 0x1f; const int rowAg1 = (rowA[k] >> 5) & 0x1f; const int rowBg0 = (rowB[j] >> 5) & 0x1f; @@ -440,7 +507,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; } } - else if (datatype == UBYTE_3_3_2 && comps == 3) { + else if (datatype == DTYPE_UBYTE_3_3_2 && comps == 3) { uint i, j, k; const ubyte *rowA = (const ubyte *) srcRowA; const ubyte *rowB = (const ubyte *) srcRowB; @@ -471,6 +538,385 @@ do_row(enum dtype datatype, uint comps, int srcWidth, } +/** + * Average together four rows of a source image to produce a single new + * row in the dest image. It's legal for the two source rows to point + * to the same data. The source width must be equal to either the + * dest width or two times the dest width. + * + * \param datatype GL pixel type \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, + * \c GL_FLOAT, etc. + * \param comps number of components per pixel (1..4) + * \param srcWidth Width of a row in the source data + * \param srcRowA Pointer to one of the rows of source data + * \param srcRowB Pointer to one of the rows of source data + * \param srcRowC Pointer to one of the rows of source data + * \param srcRowD Pointer to one of the rows of source data + * \param dstWidth Width of a row in the destination data + * \param srcRowA Pointer to the row of destination data + */ +static void +do_row_3D(enum dtype datatype, uint comps, int srcWidth, + const void *srcRowA, const void *srcRowB, + const void *srcRowC, const void *srcRowD, + int dstWidth, void *dstRow) +{ + const uint k0 = (srcWidth == dstWidth) ? 0 : 1; + const uint colStride = (srcWidth == dstWidth) ? 1 : 2; + uint i, j, k; + + assert(comps >= 1); + assert(comps <= 4); + + if ((datatype == DTYPE_UBYTE) && (comps == 4)) { + DECLARE_ROW_POINTERS(ubyte, 4); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + FILTER_3D(3); + } + } + else if ((datatype == DTYPE_UBYTE) && (comps == 3)) { + DECLARE_ROW_POINTERS(ubyte, 3); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + } + } + else if ((datatype == DTYPE_UBYTE) && (comps == 2)) { + DECLARE_ROW_POINTERS(ubyte, 2); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + } + } + else if ((datatype == DTYPE_UBYTE) && (comps == 1)) { + DECLARE_ROW_POINTERS(ubyte, 1); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + } + } + else if ((datatype == DTYPE_USHORT) && (comps == 4)) { + DECLARE_ROW_POINTERS(ushort, 4); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + FILTER_3D(3); + } + } + else if ((datatype == DTYPE_USHORT) && (comps == 3)) { + DECLARE_ROW_POINTERS(ushort, 3); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + } + } + else if ((datatype == DTYPE_USHORT) && (comps == 2)) { + DECLARE_ROW_POINTERS(ushort, 2); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + } + } + else if ((datatype == DTYPE_USHORT) && (comps == 1)) { + DECLARE_ROW_POINTERS(ushort, 1); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + } + } + else if ((datatype == DTYPE_FLOAT) && (comps == 4)) { + DECLARE_ROW_POINTERS(float, 4); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_F_3D(0); + FILTER_F_3D(1); + FILTER_F_3D(2); + FILTER_F_3D(3); + } + } + else if ((datatype == DTYPE_FLOAT) && (comps == 3)) { + DECLARE_ROW_POINTERS(float, 3); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_F_3D(0); + FILTER_F_3D(1); + FILTER_F_3D(2); + } + } + else if ((datatype == DTYPE_FLOAT) && (comps == 2)) { + DECLARE_ROW_POINTERS(float, 2); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_F_3D(0); + FILTER_F_3D(1); + } + } + else if ((datatype == DTYPE_FLOAT) && (comps == 1)) { + DECLARE_ROW_POINTERS(float, 1); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_F_3D(0); + } + } + else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 4)) { + DECLARE_ROW_POINTERS(half_float, 4); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_HF_3D(0); + FILTER_HF_3D(1); + FILTER_HF_3D(2); + FILTER_HF_3D(3); + } + } + else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 3)) { + DECLARE_ROW_POINTERS(half_float, 4); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_HF_3D(0); + FILTER_HF_3D(1); + FILTER_HF_3D(2); + } + } + else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 2)) { + DECLARE_ROW_POINTERS(half_float, 4); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_HF_3D(0); + FILTER_HF_3D(1); + } + } + else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 1)) { + DECLARE_ROW_POINTERS(half_float, 4); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_HF_3D(0); + } + } + else if ((datatype == DTYPE_UINT) && (comps == 1)) { + const uint *rowA = (const uint *) srcRowA; + const uint *rowB = (const uint *) srcRowB; + const uint *rowC = (const uint *) srcRowC; + const uint *rowD = (const uint *) srcRowD; + float *dst = (float *) dstRow; + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const uint64_t tmp = (((uint64_t) rowA[j] + (uint64_t) rowA[k]) + + ((uint64_t) rowB[j] + (uint64_t) rowB[k]) + + ((uint64_t) rowC[j] + (uint64_t) rowC[k]) + + ((uint64_t) rowD[j] + (uint64_t) rowD[k])); + dst[i] = (float)((double) tmp * 0.125); + } + } + else if ((datatype == DTYPE_USHORT_5_6_5) && (comps == 3)) { + DECLARE_ROW_POINTERS0(ushort); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const int rowAr0 = rowA[j] & 0x1f; + const int rowAr1 = rowA[k] & 0x1f; + const int rowBr0 = rowB[j] & 0x1f; + const int rowBr1 = rowB[k] & 0x1f; + const int rowCr0 = rowC[j] & 0x1f; + const int rowCr1 = rowC[k] & 0x1f; + const int rowDr0 = rowD[j] & 0x1f; + const int rowDr1 = rowD[k] & 0x1f; + const int rowAg0 = (rowA[j] >> 5) & 0x3f; + const int rowAg1 = (rowA[k] >> 5) & 0x3f; + const int rowBg0 = (rowB[j] >> 5) & 0x3f; + const int rowBg1 = (rowB[k] >> 5) & 0x3f; + const int rowCg0 = (rowC[j] >> 5) & 0x3f; + const int rowCg1 = (rowC[k] >> 5) & 0x3f; + const int rowDg0 = (rowD[j] >> 5) & 0x3f; + const int rowDg1 = (rowD[k] >> 5) & 0x3f; + const int rowAb0 = (rowA[j] >> 11) & 0x1f; + const int rowAb1 = (rowA[k] >> 11) & 0x1f; + const int rowBb0 = (rowB[j] >> 11) & 0x1f; + const int rowBb1 = (rowB[k] >> 11) & 0x1f; + const int rowCb0 = (rowC[j] >> 11) & 0x1f; + const int rowCb1 = (rowC[k] >> 11) & 0x1f; + const int rowDb0 = (rowD[j] >> 11) & 0x1f; + const int rowDb1 = (rowD[k] >> 11) & 0x1f; + const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + dst[i] = (b << 11) | (g << 5) | r; + } + } + else if ((datatype == DTYPE_USHORT_4_4_4_4) && (comps == 4)) { + DECLARE_ROW_POINTERS0(ushort); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const int rowAr0 = rowA[j] & 0xf; + const int rowAr1 = rowA[k] & 0xf; + const int rowBr0 = rowB[j] & 0xf; + const int rowBr1 = rowB[k] & 0xf; + const int rowCr0 = rowC[j] & 0xf; + const int rowCr1 = rowC[k] & 0xf; + const int rowDr0 = rowD[j] & 0xf; + const int rowDr1 = rowD[k] & 0xf; + const int rowAg0 = (rowA[j] >> 4) & 0xf; + const int rowAg1 = (rowA[k] >> 4) & 0xf; + const int rowBg0 = (rowB[j] >> 4) & 0xf; + const int rowBg1 = (rowB[k] >> 4) & 0xf; + const int rowCg0 = (rowC[j] >> 4) & 0xf; + const int rowCg1 = (rowC[k] >> 4) & 0xf; + const int rowDg0 = (rowD[j] >> 4) & 0xf; + const int rowDg1 = (rowD[k] >> 4) & 0xf; + const int rowAb0 = (rowA[j] >> 8) & 0xf; + const int rowAb1 = (rowA[k] >> 8) & 0xf; + const int rowBb0 = (rowB[j] >> 8) & 0xf; + const int rowBb1 = (rowB[k] >> 8) & 0xf; + const int rowCb0 = (rowC[j] >> 8) & 0xf; + const int rowCb1 = (rowC[k] >> 8) & 0xf; + const int rowDb0 = (rowD[j] >> 8) & 0xf; + const int rowDb1 = (rowD[k] >> 8) & 0xf; + const int rowAa0 = (rowA[j] >> 12) & 0xf; + const int rowAa1 = (rowA[k] >> 12) & 0xf; + const int rowBa0 = (rowB[j] >> 12) & 0xf; + const int rowBa1 = (rowB[k] >> 12) & 0xf; + const int rowCa0 = (rowC[j] >> 12) & 0xf; + const int rowCa1 = (rowC[k] >> 12) & 0xf; + const int rowDa0 = (rowD[j] >> 12) & 0xf; + const int rowDa1 = (rowD[k] >> 12) & 0xf; + const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + const int a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, + rowCa0, rowCa1, rowDa0, rowDa1); + + dst[i] = (a << 12) | (b << 8) | (g << 4) | r; + } + } + else if ((datatype == DTYPE_USHORT_1_5_5_5_REV) && (comps == 4)) { + DECLARE_ROW_POINTERS0(ushort); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const int rowAr0 = rowA[j] & 0x1f; + const int rowAr1 = rowA[k] & 0x1f; + const int rowBr0 = rowB[j] & 0x1f; + const int rowBr1 = rowB[k] & 0x1f; + const int rowCr0 = rowC[j] & 0x1f; + const int rowCr1 = rowC[k] & 0x1f; + const int rowDr0 = rowD[j] & 0x1f; + const int rowDr1 = rowD[k] & 0x1f; + const int rowAg0 = (rowA[j] >> 5) & 0x1f; + const int rowAg1 = (rowA[k] >> 5) & 0x1f; + const int rowBg0 = (rowB[j] >> 5) & 0x1f; + const int rowBg1 = (rowB[k] >> 5) & 0x1f; + const int rowCg0 = (rowC[j] >> 5) & 0x1f; + const int rowCg1 = (rowC[k] >> 5) & 0x1f; + const int rowDg0 = (rowD[j] >> 5) & 0x1f; + const int rowDg1 = (rowD[k] >> 5) & 0x1f; + const int rowAb0 = (rowA[j] >> 10) & 0x1f; + const int rowAb1 = (rowA[k] >> 10) & 0x1f; + const int rowBb0 = (rowB[j] >> 10) & 0x1f; + const int rowBb1 = (rowB[k] >> 10) & 0x1f; + const int rowCb0 = (rowC[j] >> 10) & 0x1f; + const int rowCb1 = (rowC[k] >> 10) & 0x1f; + const int rowDb0 = (rowD[j] >> 10) & 0x1f; + const int rowDb1 = (rowD[k] >> 10) & 0x1f; + const int rowAa0 = (rowA[j] >> 15) & 0x1; + const int rowAa1 = (rowA[k] >> 15) & 0x1; + const int rowBa0 = (rowB[j] >> 15) & 0x1; + const int rowBa1 = (rowB[k] >> 15) & 0x1; + const int rowCa0 = (rowC[j] >> 15) & 0x1; + const int rowCa1 = (rowC[k] >> 15) & 0x1; + const int rowDa0 = (rowD[j] >> 15) & 0x1; + const int rowDa1 = (rowD[k] >> 15) & 0x1; + const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + const int a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, + rowCa0, rowCa1, rowDa0, rowDa1); + + dst[i] = (a << 15) | (b << 10) | (g << 5) | r; + } + } + else if ((datatype == DTYPE_UBYTE_3_3_2) && (comps == 3)) { + DECLARE_ROW_POINTERS0(ushort); + + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const int rowAr0 = rowA[j] & 0x3; + const int rowAr1 = rowA[k] & 0x3; + const int rowBr0 = rowB[j] & 0x3; + const int rowBr1 = rowB[k] & 0x3; + const int rowCr0 = rowC[j] & 0x3; + const int rowCr1 = rowC[k] & 0x3; + const int rowDr0 = rowD[j] & 0x3; + const int rowDr1 = rowD[k] & 0x3; + const int rowAg0 = (rowA[j] >> 2) & 0x7; + const int rowAg1 = (rowA[k] >> 2) & 0x7; + const int rowBg0 = (rowB[j] >> 2) & 0x7; + const int rowBg1 = (rowB[k] >> 2) & 0x7; + const int rowCg0 = (rowC[j] >> 2) & 0x7; + const int rowCg1 = (rowC[k] >> 2) & 0x7; + const int rowDg0 = (rowD[j] >> 2) & 0x7; + const int rowDg1 = (rowD[k] >> 2) & 0x7; + const int rowAb0 = (rowA[j] >> 5) & 0x7; + const int rowAb1 = (rowA[k] >> 5) & 0x7; + const int rowBb0 = (rowB[j] >> 5) & 0x7; + const int rowBb1 = (rowB[k] >> 5) & 0x7; + const int rowCb0 = (rowC[j] >> 5) & 0x7; + const int rowCb1 = (rowC[k] >> 5) & 0x7; + const int rowDb0 = (rowD[j] >> 5) & 0x7; + const int rowDb1 = (rowD[k] >> 5) & 0x7; + const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + dst[i] = (b << 5) | (g << 2) | r; + } + } + else { + debug_printf("bad format in do_row_3D()"); + } +} + + + static void format_to_type_comps(enum pipe_format pformat, enum dtype *datatype, uint *comps) @@ -480,34 +926,34 @@ format_to_type_comps(enum pipe_format pformat, case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_B8G8R8X8_UNORM: - *datatype = UBYTE; + *datatype = DTYPE_UBYTE; *comps = 4; return; case PIPE_FORMAT_A1R5G5B5_UNORM: - *datatype = USHORT_1_5_5_5_REV; + *datatype = DTYPE_USHORT_1_5_5_5_REV; *comps = 4; return; case PIPE_FORMAT_A4R4G4B4_UNORM: - *datatype = USHORT_4_4_4_4; + *datatype = DTYPE_USHORT_4_4_4_4; *comps = 4; return; case PIPE_FORMAT_R5G6B5_UNORM: - *datatype = USHORT_5_6_5; + *datatype = DTYPE_USHORT_5_6_5; *comps = 3; return; case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: - *datatype = UBYTE; + *datatype = DTYPE_UBYTE; *comps = 1; return; case PIPE_FORMAT_A8L8_UNORM: - *datatype = UBYTE; + *datatype = DTYPE_UBYTE; *comps = 2; return; default: assert(0); - *datatype = UBYTE; + *datatype = DTYPE_UBYTE; *comps = 0; break; } @@ -575,6 +1021,87 @@ reduce_2d(enum pipe_format pformat, } +static void +reduce_3d(enum pipe_format pformat, + int srcWidth, int srcHeight, int srcDepth, + int srcRowStride, const ubyte *srcPtr, + int dstWidth, int dstHeight, int dstDepth, + int dstRowStride, ubyte *dstPtr) +{ + const int bpt = pf_get_size(pformat); + const int border = 0; + int img, row; + int bytesPerSrcImage, bytesPerDstImage; + int bytesPerSrcRow, bytesPerDstRow; + int srcImageOffset, srcRowOffset; + enum dtype datatype; + uint comps; + + format_to_type_comps(pformat, &datatype, &comps); + + bytesPerSrcImage = srcWidth * srcHeight * bpt; + bytesPerDstImage = dstWidth * dstHeight * bpt; + + bytesPerSrcRow = srcWidth * bpt; + bytesPerDstRow = dstWidth * bpt; + + /* Offset between adjacent src images to be averaged together */ + srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage; + + /* Offset between adjacent src rows to be averaged together */ + srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt; + + /* + * Need to average together up to 8 src pixels for each dest pixel. + * Break that down into 3 operations: + * 1. take two rows from source image and average them together. + * 2. take two rows from next source image and average them together. + * 3. take the two averaged rows and average them for the final dst row. + */ + + /* + _mesa_printf("mip3d %d x %d x %d -> %d x %d x %d\n", + srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth); + */ + + for (img = 0; img < dstDepth; img++) { + /* first source image pointer, skipping border */ + const ubyte *imgSrcA = srcPtr + + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border + + img * (bytesPerSrcImage + srcImageOffset); + /* second source image pointer, skipping border */ + const ubyte *imgSrcB = imgSrcA + srcImageOffset; + /* address of the dest image, skipping border */ + ubyte *imgDst = dstPtr + + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border + + img * bytesPerDstImage; + + /* setup the four source row pointers and the dest row pointer */ + const ubyte *srcImgARowA = imgSrcA; + const ubyte *srcImgARowB = imgSrcA + srcRowOffset; + const ubyte *srcImgBRowA = imgSrcB; + const ubyte *srcImgBRowB = imgSrcB + srcRowOffset; + ubyte *dstImgRow = imgDst; + + for (row = 0; row < dstHeight; row++) { + do_row_3D(datatype, comps, srcWidth, + srcImgARowA, srcImgARowB, + srcImgBRowA, srcImgBRowB, + dstWidth, dstImgRow); + + /* advance to next rows */ + srcImgARowA += bytesPerSrcRow + srcRowOffset; + srcImgARowB += bytesPerSrcRow + srcRowOffset; + srcImgBRowA += bytesPerSrcRow + srcRowOffset; + srcImgBRowB += bytesPerSrcRow + srcRowOffset; + dstImgRow += bytesPerDstRow; + } + } +} + + + + static void make_1d_mipmap(struct gen_mipmap_state *ctx, struct pipe_texture *pt, @@ -587,31 +1114,30 @@ make_1d_mipmap(struct gen_mipmap_state *ctx, for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; - struct pipe_surface *srcSurf, *dstSurf; + struct pipe_transfer *srcTrans, *dstTrans; void *srcMap, *dstMap; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, - PIPE_BUFFER_USAGE_CPU_READ); - - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, - PIPE_BUFFER_USAGE_CPU_WRITE); - - srcMap = ((ubyte *) pipe_buffer_map(screen, srcSurf->buffer, - PIPE_BUFFER_USAGE_CPU_READ) - + srcSurf->offset); - dstMap = ((ubyte *) pipe_buffer_map(screen, dstSurf->buffer, - PIPE_BUFFER_USAGE_CPU_WRITE) - + dstSurf->offset); + srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice, + PIPE_TRANSFER_READ, 0, 0, + pt->width[srcLevel], + pt->height[srcLevel]); + dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice, + PIPE_TRANSFER_WRITE, 0, 0, + pt->width[dstLevel], + pt->height[dstLevel]); + + srcMap = (ubyte *) screen->transfer_map(screen, srcTrans); + dstMap = (ubyte *) screen->transfer_map(screen, dstTrans); reduce_1d(pt->format, - srcSurf->width, srcMap, - dstSurf->width, dstMap); + srcTrans->width, srcMap, + dstTrans->width, dstMap); - pipe_buffer_unmap(screen, srcSurf->buffer); - pipe_buffer_unmap(screen, dstSurf->buffer); + screen->transfer_unmap(screen, srcTrans); + screen->transfer_unmap(screen, dstTrans); - pipe_surface_reference(&srcSurf, NULL); - pipe_surface_reference(&dstSurf, NULL); + screen->tex_transfer_destroy(srcTrans); + screen->tex_transfer_destroy(dstTrans); } } @@ -631,32 +1157,32 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; - struct pipe_surface *srcSurf, *dstSurf; + struct pipe_transfer *srcTrans, *dstTrans; ubyte *srcMap, *dstMap; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, - PIPE_BUFFER_USAGE_CPU_READ); - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, - PIPE_BUFFER_USAGE_CPU_WRITE); - - srcMap = ((ubyte *) pipe_buffer_map(screen, srcSurf->buffer, - PIPE_BUFFER_USAGE_CPU_READ) - + srcSurf->offset); - dstMap = ((ubyte *) pipe_buffer_map(screen, dstSurf->buffer, - PIPE_BUFFER_USAGE_CPU_WRITE) - + dstSurf->offset); + srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice, + PIPE_TRANSFER_READ, 0, 0, + pt->width[srcLevel], + pt->height[srcLevel]); + dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice, + PIPE_TRANSFER_WRITE, 0, 0, + pt->width[dstLevel], + pt->height[dstLevel]); + + srcMap = (ubyte *) screen->transfer_map(screen, srcTrans); + dstMap = (ubyte *) screen->transfer_map(screen, dstTrans); reduce_2d(pt->format, - srcSurf->width, srcSurf->height, - srcSurf->stride, srcMap, - dstSurf->width, dstSurf->height, - dstSurf->stride, dstMap); + srcTrans->width, srcTrans->height, + srcTrans->stride, srcMap, + dstTrans->width, dstTrans->height, + dstTrans->stride, dstMap); - pipe_buffer_unmap(screen, srcSurf->buffer); - pipe_buffer_unmap(screen, dstSurf->buffer); + screen->transfer_unmap(screen, srcTrans); + screen->transfer_unmap(screen, dstTrans); - pipe_surface_reference(&srcSurf, NULL); - pipe_surface_reference(&dstSurf, NULL); + screen->tex_transfer_destroy(srcTrans); + screen->tex_transfer_destroy(dstTrans); } } @@ -666,6 +1192,46 @@ make_3d_mipmap(struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel) { +#if 0 + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + uint dstLevel, zslice = 0; + + assert(pt->block.width == 1); + assert(pt->block.height == 1); + + for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { + const uint srcLevel = dstLevel - 1; + struct pipe_transfer *srcTrans, *dstTrans; + ubyte *srcMap, *dstMap; + + srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice, + PIPE_TRANSFER_READ, 0, 0, + pt->width[srcLevel], + pt->height[srcLevel]); + dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice, + PIPE_TRANSFER_WRITE, 0, 0, + pt->width[dstLevel], + pt->height[dstLevel]); + + srcMap = (ubyte *) screen->transfer_map(screen, srcTrans); + dstMap = (ubyte *) screen->transfer_map(screen, dstTrans); + + reduce_3d(pt->format, + srcTrans->width, srcTrans->height, + srcTrans->stride, srcMap, + dstTrans->width, dstTrans->height, + dstTrans->stride, dstMap); + + screen->transfer_unmap(screen, srcTrans); + screen->transfer_unmap(screen, dstTrans); + + screen->tex_transfer_destroy(srcTrans); + screen->tex_transfer_destroy(dstTrans); + } +#else + (void) reduce_3d; +#endif } @@ -712,10 +1278,6 @@ util_create_gen_mipmap(struct pipe_context *pipe, /* disabled blending/masking */ memset(&ctx->blend, 0, sizeof(ctx->blend)); - ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; ctx->blend.colormask = PIPE_MASK_RGBA; /* no-op depth/stencil/alpha */ @@ -725,8 +1287,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; - ctx->rasterizer.bypass_clipping = 1; - /*ctx->rasterizer.bypass_vs = 1;*/ + ctx->rasterizer.bypass_vs_clip_and_viewport = 1; ctx->rasterizer.gl_rasterization_rules = 1; /* sampler state */ @@ -737,51 +1298,39 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; ctx->sampler.normalized_coords = 1; - /* viewport state (identity, verts are in wincoords) */ - ctx->viewport.scale[0] = 1.0; - ctx->viewport.scale[1] = 1.0; - ctx->viewport.scale[2] = 1.0; - ctx->viewport.scale[3] = 1.0; - ctx->viewport.translate[0] = 0.0; - ctx->viewport.translate[1] = 0.0; - ctx->viewport.translate[2] = 0.0; - ctx->viewport.translate[3] = 0.0; - - /* vertex shader */ + /* vertex shader - still needed to specify mapping from fragment + * shader input semantics to vertex elements + */ { const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC }; const uint semantic_indexes[] = { 0, 0 }; ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indexes, - &ctx->vert_shader); + semantic_indexes); } /* fragment shader */ - ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader); - - ctx->vbuf = pipe_buffer_create(pipe->screen, - 32, - PIPE_BUFFER_USAGE_VERTEX, - sizeof(ctx->vertices)); - if (!ctx->vbuf) { - FREE(ctx); - return NULL; - } + ctx->fs = util_make_fragment_tex_shader(pipe); /* vertex data that doesn't change */ for (i = 0; i < 4; i++) { ctx->vertices[i][0][2] = 0.0f; /* z */ ctx->vertices[i][0][3] = 1.0f; /* w */ - ctx->vertices[i][1][2] = 0.0f; /* r */ ctx->vertices[i][1][3] = 1.0f; /* q */ } + /* Note: the actual vertex buffer is allocated as needed below */ + return ctx; } -static unsigned get_next_slot( struct gen_mipmap_state *ctx ) +/** + * Get next "slot" of vertex space in the vertex buffer. + * We're allocating one large vertex buffer and using it piece by piece. + */ +static unsigned +get_next_slot(struct gen_mipmap_state *ctx) { const unsigned max_slots = 4096 / sizeof ctx->vertices; @@ -798,40 +1347,111 @@ static unsigned get_next_slot( struct gen_mipmap_state *ctx ) return ctx->vbuf_slot++ * sizeof ctx->vertices; } + static unsigned -set_vertex_data(struct gen_mipmap_state *ctx, float width, float height) +set_vertex_data(struct gen_mipmap_state *ctx, + enum pipe_texture_target tex_target, + uint face, float width, float height) { - void *buf; unsigned offset; + /* vert[0].position */ ctx->vertices[0][0][0] = 0.0f; /*x*/ ctx->vertices[0][0][1] = 0.0f; /*y*/ - ctx->vertices[0][1][0] = 0.0f; /*s*/ - ctx->vertices[0][1][1] = 0.0f; /*t*/ + /* vert[1].position */ ctx->vertices[1][0][0] = width; ctx->vertices[1][0][1] = 0.0f; - ctx->vertices[1][1][0] = 1.0f; - ctx->vertices[1][1][1] = 0.0f; + /* vert[2].position */ ctx->vertices[2][0][0] = width; ctx->vertices[2][0][1] = height; - ctx->vertices[2][1][0] = 1.0f; - ctx->vertices[2][1][1] = 1.0f; + /* vert[3].position */ ctx->vertices[3][0][0] = 0.0f; ctx->vertices[3][0][1] = height; - ctx->vertices[3][1][0] = 0.0f; - ctx->vertices[3][1][1] = 1.0f; - offset = get_next_slot( ctx ); + /* Setup vertex texcoords. This is a little tricky for cube maps. */ + if (tex_target == PIPE_TEXTURE_CUBE) { + static const float st[4][2] = { + {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} + }; + float rx, ry, rz; + uint i; + + /* loop over quad verts */ + for (i = 0; i < 4; i++) { + /* Compute sc = +/-scale and tc = +/-scale. + * Not +/-1 to avoid cube face selection ambiguity near the edges, + * though that can still sometimes happen with this scale factor... + */ + const float scale = 0.9999f; + const float sc = (2.0f * st[i][0] - 1.0f) * scale; + const float tc = (2.0f * st[i][1] - 1.0f) * scale; + + switch (face) { + case PIPE_TEX_FACE_POS_X: + rx = 1.0f; + ry = -tc; + rz = -sc; + break; + case PIPE_TEX_FACE_NEG_X: + rx = -1.0f; + ry = -tc; + rz = sc; + break; + case PIPE_TEX_FACE_POS_Y: + rx = sc; + ry = 1.0f; + rz = tc; + break; + case PIPE_TEX_FACE_NEG_Y: + rx = sc; + ry = -1.0f; + rz = -tc; + break; + case PIPE_TEX_FACE_POS_Z: + rx = sc; + ry = -tc; + rz = 1.0f; + break; + case PIPE_TEX_FACE_NEG_Z: + rx = -sc; + ry = -tc; + rz = -1.0f; + break; + default: + assert(0); + } - buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf, - PIPE_BUFFER_USAGE_CPU_WRITE); + ctx->vertices[i][1][0] = rx; /*s*/ + ctx->vertices[i][1][1] = ry; /*t*/ + ctx->vertices[i][1][2] = rz; /*r*/ + } + } + else { + /* 1D/2D */ + ctx->vertices[0][1][0] = 0.0f; /*s*/ + ctx->vertices[0][1][1] = 0.0f; /*t*/ + ctx->vertices[0][1][2] = 0.0f; /*r*/ + + ctx->vertices[1][1][0] = 1.0f; + ctx->vertices[1][1][1] = 0.0f; + ctx->vertices[1][1][2] = 0.0f; + + ctx->vertices[2][1][0] = 1.0f; + ctx->vertices[2][1][1] = 1.0f; + ctx->vertices[2][1][2] = 0.0f; + + ctx->vertices[3][1][0] = 0.0f; + ctx->vertices[3][1][1] = 1.0f; + ctx->vertices[3][1][2] = 0.0f; + } - memcpy((char *)buf + offset, ctx->vertices, sizeof(ctx->vertices)); + offset = get_next_slot( ctx ); - pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf); + pipe_buffer_write(ctx->pipe->screen, ctx->vbuf, + offset, sizeof(ctx->vertices), ctx->vertices); return offset; } @@ -849,10 +1469,7 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); - FREE((void*) ctx->vert_shader.tokens); - FREE((void*) ctx->frag_shader.tokens); - - pipe_buffer_reference(pipe->screen, &ctx->vbuf, NULL); + pipe_buffer_reference(&ctx->vbuf, NULL); FREE(ctx); } @@ -864,7 +1481,7 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) */ void util_gen_mipmap_flush( struct gen_mipmap_state *ctx ) { - pipe_buffer_reference(ctx->pipe->screen, &ctx->vbuf, NULL); + pipe_buffer_reference(&ctx->vbuf, NULL); ctx->vbuf_slot = 0; } @@ -908,20 +1525,18 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); - cso_save_viewport(ctx->cso); /* bind our state */ cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - cso_set_viewport(ctx->cso, &ctx->viewport); cso_set_fragment_shader_handle(ctx->cso, ctx->fs); cso_set_vertex_shader_handle(ctx->cso, ctx->vs); /* init framebuffer state */ memset(&fb, 0, sizeof(fb)); - fb.num_cbufs = 1; + fb.nr_cbufs = 1; /* set min/mag to same filter for faster sw speed */ ctx->sampler.mag_img_filter = filter; @@ -960,8 +1575,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_sampler_textures(ctx->cso, 1, &pt); - /* quad coords in window coords (bypassing clipping, viewport mapping) */ + /* quad coords in window coords (bypassing vs, clip and viewport) */ offset = set_vertex_data(ctx, + pt->target, + face, (float) pt->width[dstLevel], (float) pt->height[dstLevel]); @@ -987,5 +1604,4 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); - cso_restore_viewport(ctx->cso); }