diff options
Diffstat (limited to 'mesalib/src')
35 files changed, 450 insertions, 1365 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_format.csv b/mesalib/src/gallium/auxiliary/util/u_format.csv index 8fb068b81..8aa5c364d 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.csv +++ b/mesalib/src/gallium/auxiliary/util/u_format.csv @@ -373,3 +373,6 @@ PIPE_FORMAT_R16A16_SINT , plain, 1, 1, sp16 , sp16 , , , x00 PIPE_FORMAT_R32A32_UINT , plain, 1, 1, up32 , up32 , , , x00y, rgb PIPE_FORMAT_R32A32_SINT , plain, 1, 1, sp32 , sp32 , , , x00y, rgb PIPE_FORMAT_R10G10B10A2_UINT , plain, 1, 1, up10 , up10 , up10, up2 , xyzw, rgb + +PIPE_FORMAT_B5G6R5_SRGB , plain, 1, 1, un5 , un6 , un5 , , zyx1, srgb + diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h index 747e1429d..1dd5d52f1 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.h +++ b/mesalib/src/gallium/auxiliary/util/u_format.h @@ -906,6 +906,8 @@ util_format_srgb(enum pipe_format format) return PIPE_FORMAT_DXT3_SRGBA; case PIPE_FORMAT_DXT5_RGBA: return PIPE_FORMAT_DXT5_SRGBA; + case PIPE_FORMAT_B5G6R5_UNORM: + return PIPE_FORMAT_B5G6R5_SRGB; default: return PIPE_FORMAT_NONE; } @@ -949,6 +951,8 @@ util_format_linear(enum pipe_format format) return PIPE_FORMAT_DXT3_RGBA; case PIPE_FORMAT_DXT5_SRGBA: return PIPE_FORMAT_DXT5_RGBA; + case PIPE_FORMAT_B5G6R5_SRGB: + return PIPE_FORMAT_B5G6R5_UNORM; default: return format; } diff --git a/mesalib/src/gallium/auxiliary/util/u_format_pack.py b/mesalib/src/gallium/auxiliary/util/u_format_pack.py index d1f68c804..8072fdb13 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format_pack.py +++ b/mesalib/src/gallium/auxiliary/util/u_format_pack.py @@ -272,8 +272,11 @@ def conversion_expr(src_channel, if src_colorspace == SRGB: assert src_channel.type == UNSIGNED assert src_channel.norm - assert src_channel.size == 8 + assert src_channel.size <= 8 + assert src_channel.size >= 4 assert dst_colorspace == RGB + if src_channel.size < 8: + value = '%s << %x | %s >> %x' % (value, 8 - src_channel.size, value, 2 * src_channel.size - 8) if dst_channel.type == FLOAT: return 'util_format_srgb_8unorm_to_linear_float(%s)' % value else: @@ -284,15 +287,20 @@ def conversion_expr(src_channel, elif dst_colorspace == SRGB: assert dst_channel.type == UNSIGNED assert dst_channel.norm - assert dst_channel.size == 8 + assert dst_channel.size <= 8 assert src_colorspace == RGB if src_channel.type == FLOAT: - return 'util_format_linear_float_to_srgb_8unorm(%s)' % value + value = 'util_format_linear_float_to_srgb_8unorm(%s)' % value else: assert src_channel.type == UNSIGNED assert src_channel.norm assert src_channel.size == 8 - return 'util_format_linear_to_srgb_8unorm(%s)' % value + value = 'util_format_linear_to_srgb_8unorm(%s)' % value + # XXX rounding is all wrong. + if dst_channel.size < 8: + return '%s >> %x' % (value, 8 - dst_channel.size) + else: + return value elif src_colorspace == ZS: pass elif dst_colorspace == ZS: diff --git a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c index dad3ad2ec..a2f42189f 100644 --- a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -78,1165 +78,6 @@ struct gen_mipmap_state }; - -enum dtype -{ - 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 uint16_t half_float; - - -/** - * \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 = util_half_to_float(rowA[j][e]); \ - const float ak = util_half_to_float(rowA[k][e]); \ - const float bj = util_half_to_float(rowB[j][e]); \ - const float bk = util_half_to_float(rowB[k][e]); \ - const float cj = util_half_to_float(rowC[j][e]); \ - const float ck = util_half_to_float(rowC[k][e]); \ - const float dj = util_half_to_float(rowD[j][e]); \ - const float dk = util_half_to_float(rowD[k][e]); \ - dst[i][e] = util_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \ - * 0.125F); \ - } while(0) -/*@}*/ - - -/** - * 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. - * \param datatype GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc. - * \param comps number of components per pixel (1..4) - */ -static void -do_row(enum dtype datatype, uint comps, int srcWidth, - const void *srcRowA, const void *srcRowB, - int dstWidth, void *dstRow) -{ - const uint k0 = (srcWidth == dstWidth) ? 0 : 1; - const uint colStride = (srcWidth == dstWidth) ? 1 : 2; - - assert(comps >= 1); - assert(comps <= 4); - - /* This assertion is no longer valid with non-power-of-2 textures - assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); - */ - - 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; - ubyte(*dst)[4] = (ubyte(*)[4]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; - dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; - dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; - } - } - 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; - ubyte(*dst)[3] = (ubyte(*)[3]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; - dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; - } - } - 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; - ubyte(*dst)[2] = (ubyte(*)[2]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2; - dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2; - } - } - else if (datatype == DTYPE_UBYTE && comps == 1) { - uint i, j, k; - const ubyte *rowA = (const ubyte *) srcRowA; - const ubyte *rowB = (const ubyte *) srcRowB; - ubyte *dst = (ubyte *) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; - } - } - - 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; - ushort(*dst)[4] = (ushort(*)[4]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; - dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; - dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; - } - } - 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; - ushort(*dst)[3] = (ushort(*)[3]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; - dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; - } - } - 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; - ushort(*dst)[2] = (ushort(*)[2]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; - } - } - else if (datatype == DTYPE_USHORT && comps == 1) { - uint i, j, k; - const ushort *rowA = (const ushort *) srcRowA; - const ushort *rowB = (const ushort *) srcRowB; - ushort *dst = (ushort *) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 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; - float(*dst)[4] = (float(*)[4]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) * 0.25F; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) * 0.25F; - dst[i][2] = (rowA[j][2] + rowA[k][2] + - rowB[j][2] + rowB[k][2]) * 0.25F; - dst[i][3] = (rowA[j][3] + rowA[k][3] + - rowB[j][3] + rowB[k][3]) * 0.25F; - } - } - 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; - float(*dst)[3] = (float(*)[3]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) * 0.25F; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) * 0.25F; - dst[i][2] = (rowA[j][2] + rowA[k][2] + - rowB[j][2] + rowB[k][2]) * 0.25F; - } - } - 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; - float(*dst)[2] = (float(*)[2]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) * 0.25F; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) * 0.25F; - } - } - else if (datatype == DTYPE_FLOAT && comps == 1) { - uint i, j, k; - const float *rowA = (const float *) srcRowA; - const float *rowB = (const float *) srcRowB; - float *dst = (float *) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; - } - } - - else if (datatype == DTYPE_HALF_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; - half_float(*dst)[4] = (half_float(*)[4]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - for (comp = 0; comp < 4; comp++) { - float aj, ak, bj, bk; - aj = util_half_to_float(rowA[j][comp]); - ak = util_half_to_float(rowA[k][comp]); - bj = util_half_to_float(rowB[j][comp]); - bk = util_half_to_float(rowB[k][comp]); - dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F); - } - } - } - 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; - half_float(*dst)[3] = (half_float(*)[3]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - for (comp = 0; comp < 3; comp++) { - float aj, ak, bj, bk; - aj = util_half_to_float(rowA[j][comp]); - ak = util_half_to_float(rowA[k][comp]); - bj = util_half_to_float(rowB[j][comp]); - bk = util_half_to_float(rowB[k][comp]); - dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F); - } - } - } - 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; - half_float(*dst)[2] = (half_float(*)[2]) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - for (comp = 0; comp < 2; comp++) { - float aj, ak, bj, bk; - aj = util_half_to_float(rowA[j][comp]); - ak = util_half_to_float(rowA[k][comp]); - bj = util_half_to_float(rowB[j][comp]); - bk = util_half_to_float(rowB[k][comp]); - dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F); - } - } - } - 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; - half_float *dst = (half_float *) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - float aj, ak, bj, bk; - aj = util_half_to_float(rowA[j]); - ak = util_half_to_float(rowA[k]); - bj = util_half_to_float(rowB[j]); - bk = util_half_to_float(rowB[k]); - dst[i] = util_float_to_half((aj + ak + bj + bk) * 0.25F); - } - } - - else if (datatype == DTYPE_UINT && comps == 1) { - uint i, j, k; - const uint *rowA = (const uint *) srcRowA; - const uint *rowB = (const uint *) srcRowB; - uint *dst = (uint *) dstRow; - for (i = j = 0, k = k0; i < (uint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; - } - } - - 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; - ushort *dst = (ushort *) dstRow; - 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 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 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 red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; - const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; - const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; - dst[i] = (blue << 11) | (green << 5) | red; - } - } - 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; - ushort *dst = (ushort *) dstRow; - 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 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 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 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 red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; - const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; - const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; - const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; - dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; - } - } - 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; - ushort *dst = (ushort *) dstRow; - 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 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 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 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 red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; - const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; - const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; - const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; - dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; - } - } - 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; - ubyte *dst = (ubyte *) dstRow; - 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 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 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 red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; - const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; - const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; - dst[i] = (blue << 5) | (green << 2) | red; - } - } - else { - debug_printf("bad format in do_row()"); - } -} - - -/** - * 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) -{ - /* XXX I think this could be implemented in terms of the pf_*() functions */ - switch (pformat) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_A8B8G8R8_SRGB: - case PIPE_FORMAT_X8B8G8R8_SRGB: - case PIPE_FORMAT_B8G8R8A8_SRGB: - case PIPE_FORMAT_B8G8R8X8_SRGB: - case PIPE_FORMAT_A8R8G8B8_SRGB: - case PIPE_FORMAT_X8R8G8B8_SRGB: - case PIPE_FORMAT_R8G8B8_SRGB: - *datatype = DTYPE_UBYTE; - *comps = 4; - return; - case PIPE_FORMAT_B5G5R5X1_UNORM: - case PIPE_FORMAT_B5G5R5A1_UNORM: - *datatype = DTYPE_USHORT_1_5_5_5_REV; - *comps = 4; - return; - case PIPE_FORMAT_B4G4R4A4_UNORM: - *datatype = DTYPE_USHORT_4_4_4_4; - *comps = 4; - return; - case PIPE_FORMAT_B5G6R5_UNORM: - *datatype = DTYPE_USHORT_5_6_5; - *comps = 3; - return; - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_L8_SRGB: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - *datatype = DTYPE_UBYTE; - *comps = 1; - return; - case PIPE_FORMAT_L8A8_UNORM: - case PIPE_FORMAT_L8A8_SRGB: - *datatype = DTYPE_UBYTE; - *comps = 2; - return; - default: - assert(0); - *datatype = DTYPE_UBYTE; - *comps = 0; - break; - } -} - - -static void -reduce_1d(enum pipe_format pformat, - int srcWidth, const ubyte *srcPtr, - int dstWidth, ubyte *dstPtr) -{ - enum dtype datatype; - uint comps; - - format_to_type_comps(pformat, &datatype, &comps); - - /* we just duplicate the input row, kind of hack, saves code */ - do_row(datatype, comps, - srcWidth, srcPtr, srcPtr, - dstWidth, dstPtr); -} - - -/** - * Strides are in bytes. If zero, it'll be computed as width * bpp. - */ -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) -{ - enum dtype datatype; - uint comps; - const int bpt = util_format_get_blocksize(pformat); - const ubyte *srcA, *srcB; - ubyte *dst; - int row; - - format_to_type_comps(pformat, &datatype, &comps); - - if (!srcRowStride) - srcRowStride = bpt * srcWidth; - - if (!dstRowStride) - dstRowStride = bpt * dstWidth; - - /* Compute src and dst pointers */ - srcA = srcPtr; - if (srcHeight > 1) - srcB = srcA + srcRowStride; - else - srcB = srcA; - dst = dstPtr; - - for (row = 0; row < dstHeight; row++) { - do_row(datatype, comps, - srcWidth, srcA, srcB, - dstWidth, dst); - srcA += 2 * srcRowStride; - srcB += 2 * srcRowStride; - dst += dstRowStride; - } -} - - -static void -reduce_3d(enum pipe_format pformat, - int srcWidth, int srcHeight, int srcDepth, - int srcRowStride, int srcImageStride, const ubyte *srcPtr, - int dstWidth, int dstHeight, int dstDepth, - int dstRowStride, int dstImageStride, ubyte *dstPtr) -{ - const int bpt = util_format_get_blocksize(pformat); - int img, row; - int srcImageOffset, srcRowOffset; - enum dtype datatype; - uint comps; - - format_to_type_comps(pformat, &datatype, &comps); - - /* XXX I think we should rather assert those strides */ - if (!srcImageStride) - srcImageStride = srcWidth * srcHeight * bpt; - if (!dstImageStride) - dstImageStride = dstWidth * dstHeight * bpt; - - if (!srcRowStride) - srcRowStride = srcWidth * bpt; - if (!dstRowStride) - dstRowStride = dstWidth * bpt; - - /* Offset between adjacent src images to be averaged together */ - srcImageOffset = (srcDepth == dstDepth) ? 0 : srcImageStride; - - /* Offset between adjacent src rows to be averaged together */ - srcRowOffset = (srcHeight == dstHeight) ? 0 : srcRowStride; - - /* - * 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. - */ - - /* - 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 */ - const ubyte *imgSrcA = srcPtr - + img * (srcImageStride + srcImageOffset); - /* second source image pointer */ - const ubyte *imgSrcB = imgSrcA + srcImageOffset; - /* address of the dest image */ - ubyte *imgDst = dstPtr + img * dstImageStride; - - /* 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 += srcRowStride + srcRowOffset; - srcImgARowB += srcRowStride + srcRowOffset; - srcImgBRowA += srcRowStride + srcRowOffset; - srcImgBRowB += srcRowStride + srcRowOffset; - dstImgRow += dstImageStride; - } - } -} - - - - -static void -make_1d_mipmap(struct gen_mipmap_state *ctx, - struct pipe_resource *pt, - uint layer, uint baseLevel, uint lastLevel) -{ - struct pipe_context *pipe = ctx->pipe; - uint dstLevel; - - for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { - const uint srcLevel = dstLevel - 1; - struct pipe_transfer *srcTrans, *dstTrans; - void *srcMap, *dstMap; - - srcMap = pipe_transfer_map(pipe, pt, srcLevel, layer, - PIPE_TRANSFER_READ, 0, 0, - u_minify(pt->width0, srcLevel), - u_minify(pt->height0, srcLevel), &srcTrans); - dstMap = pipe_transfer_map(pipe, pt, dstLevel, layer, - PIPE_TRANSFER_WRITE, 0, 0, - u_minify(pt->width0, dstLevel), - u_minify(pt->height0, dstLevel), &dstTrans); - - reduce_1d(pt->format, - srcTrans->box.width, srcMap, - dstTrans->box.width, dstMap); - - pipe->transfer_unmap(pipe, srcTrans); - pipe->transfer_unmap(pipe, dstTrans); - } -} - - -static void -make_2d_mipmap(struct gen_mipmap_state *ctx, - struct pipe_resource *pt, - uint layer, uint baseLevel, uint lastLevel) -{ - struct pipe_context *pipe = ctx->pipe; - uint dstLevel; - - assert(util_format_get_blockwidth(pt->format) == 1); - assert(util_format_get_blockheight(pt->format) == 1); - - for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { - const uint srcLevel = dstLevel - 1; - struct pipe_transfer *srcTrans, *dstTrans; - ubyte *srcMap, *dstMap; - - srcMap = pipe_transfer_map(pipe, pt, srcLevel, layer, - PIPE_TRANSFER_READ, 0, 0, - u_minify(pt->width0, srcLevel), - u_minify(pt->height0, srcLevel), &srcTrans); - dstMap = pipe_transfer_map(pipe, pt, dstLevel, layer, - PIPE_TRANSFER_WRITE, 0, 0, - u_minify(pt->width0, dstLevel), - u_minify(pt->height0, dstLevel), &dstTrans); - - reduce_2d(pt->format, - srcTrans->box.width, srcTrans->box.height, - srcTrans->stride, srcMap, - dstTrans->box.width, dstTrans->box.height, - dstTrans->stride, dstMap); - - pipe->transfer_unmap(pipe, srcTrans); - pipe->transfer_unmap(pipe, dstTrans); - } -} - - -/* XXX looks a bit more like it could work now but need to test */ -static void -make_3d_mipmap(struct gen_mipmap_state *ctx, - struct pipe_resource *pt, - uint face, uint baseLevel, uint lastLevel) -{ - struct pipe_context *pipe = ctx->pipe; - uint dstLevel; - struct pipe_box src_box, dst_box; - - assert(util_format_get_blockwidth(pt->format) == 1); - assert(util_format_get_blockheight(pt->format) == 1); - - src_box.x = src_box.y = src_box.z = 0; - dst_box.x = dst_box.y = dst_box.z = 0; - - for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { - const uint srcLevel = dstLevel - 1; - struct pipe_transfer *srcTrans, *dstTrans; - ubyte *srcMap, *dstMap; - struct pipe_box src_box, dst_box; - src_box.width = u_minify(pt->width0, srcLevel); - src_box.height = u_minify(pt->height0, srcLevel); - src_box.depth = u_minify(pt->depth0, srcLevel); - dst_box.width = u_minify(pt->width0, dstLevel); - dst_box.height = u_minify(pt->height0, dstLevel); - dst_box.depth = u_minify(pt->depth0, dstLevel); - - srcMap = pipe->transfer_map(pipe, pt, srcLevel, - PIPE_TRANSFER_READ, - &src_box, &srcTrans); - dstMap = pipe->transfer_map(pipe, pt, dstLevel, - PIPE_TRANSFER_WRITE, - &dst_box, &dstTrans); - - reduce_3d(pt->format, - srcTrans->box.width, srcTrans->box.height, srcTrans->box.depth, - srcTrans->stride, srcTrans->layer_stride, srcMap, - dstTrans->box.width, dstTrans->box.height, dstTrans->box.depth, - dstTrans->stride, dstTrans->layer_stride, dstMap); - - pipe->transfer_unmap(pipe, srcTrans); - pipe->transfer_unmap(pipe, dstTrans); - } -} - - -static void -fallback_gen_mipmap(struct gen_mipmap_state *ctx, - struct pipe_resource *pt, - uint layer, uint baseLevel, uint lastLevel) -{ - switch (pt->target) { - case PIPE_TEXTURE_1D: - make_1d_mipmap(ctx, pt, layer, baseLevel, lastLevel); - break; - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_RECT: - case PIPE_TEXTURE_CUBE: - make_2d_mipmap(ctx, pt, layer, baseLevel, lastLevel); - break; - case PIPE_TEXTURE_3D: - make_3d_mipmap(ctx, pt, layer, baseLevel, lastLevel); - break; - default: - assert(0); - } -} - - /** * Create a mipmap generation context. * The idea is to create one of these and re-use it each time we need to @@ -1382,7 +223,7 @@ get_next_slot(struct gen_mipmap_state *ctx) static unsigned set_vertex_data(struct gen_mipmap_state *ctx, enum pipe_texture_target tex_target, - uint layer, float r) + uint face, float r) { unsigned offset; @@ -1403,14 +244,21 @@ set_vertex_data(struct gen_mipmap_state *ctx, ctx->vertices[3][0][1] = 1.0f; /* Setup vertex texcoords. This is a little tricky for cube maps. */ - if (tex_target == PIPE_TEXTURE_CUBE) { + if (tex_target == PIPE_TEXTURE_CUBE || + tex_target == PIPE_TEXTURE_CUBE_ARRAY) { static const float st[4][2] = { {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} }; - util_map_texcoords2d_onto_cubemap(layer, &st[0][0], 2, + util_map_texcoords2d_onto_cubemap(face, &st[0][0], 2, &ctx->vertices[0][1][0], 8, FALSE); + + /* set the layer for cube arrays */ + ctx->vertices[0][1][3] = r; + ctx->vertices[1][1][3] = r; + ctx->vertices[2][1][3] = r; + ctx->vertices[3][1][3] = r; } else if (tex_target == PIPE_TEXTURE_1D_ARRAY) { /* 1D texture array */ @@ -1520,36 +368,15 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, assert(filter == PIPE_TEX_FILTER_LINEAR || filter == PIPE_TEX_FILTER_NEAREST); - switch (pt->target) { - case PIPE_TEXTURE_1D: - type = TGSI_TEXTURE_1D; - break; - case PIPE_TEXTURE_2D: - type = TGSI_TEXTURE_2D; - break; - case PIPE_TEXTURE_3D: - type = TGSI_TEXTURE_3D; - break; - case PIPE_TEXTURE_CUBE: - type = TGSI_TEXTURE_CUBE; - break; - case PIPE_TEXTURE_1D_ARRAY: - type = TGSI_TEXTURE_1D_ARRAY; - break; - case PIPE_TEXTURE_2D_ARRAY: - type = TGSI_TEXTURE_2D_ARRAY; - break; - default: - assert(0); - type = TGSI_TEXTURE_2D; - } + type = util_pipe_tex_to_tgsi_tex(pt->target, 1); /* check if we can render in the texture's format */ if (!screen->is_format_supported(screen, psv->format, pt->target, pt->nr_samples, is_depth ? PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET)) { - fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); + /* The caller should check if the format is renderable. */ + assert(0); return; } @@ -1600,7 +427,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, if (pt->target == PIPE_TEXTURE_3D) nr_layers = u_minify(pt->depth0, dstLevel); - else if (pt->target == PIPE_TEXTURE_2D_ARRAY || pt->target == PIPE_TEXTURE_1D_ARRAY) + else if (pt->target == PIPE_TEXTURE_2D_ARRAY || + pt->target == PIPE_TEXTURE_1D_ARRAY || + pt->target == PIPE_TEXTURE_CUBE_ARRAY) nr_layers = pt->array_size; else nr_layers = 1; @@ -1613,9 +442,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, layer = i; /* XXX hmm really? */ rcoord = (float)layer / (float)nr_layers + 1.0f / (float)(nr_layers * 2); - } else if (pt->target == PIPE_TEXTURE_2D_ARRAY || pt->target == PIPE_TEXTURE_1D_ARRAY) { + } else if (pt->target == PIPE_TEXTURE_2D_ARRAY || + pt->target == PIPE_TEXTURE_1D_ARRAY) { layer = i; rcoord = (float)layer; + } else if (pt->target == PIPE_TEXTURE_CUBE_ARRAY) { + layer = i; + face = layer % 6; + rcoord = layer / 6; } else layer = face; diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp index c4f39abb7..43746f055 100755 --- a/mesalib/src/glsl/builtin_functions.cpp +++ b/mesalib/src/glsl/builtin_functions.cpp @@ -194,16 +194,17 @@ shader_integer_mix(const _mesa_glsl_parse_state *state) } static bool -shader_packing(const _mesa_glsl_parse_state *state) +shader_packing_or_es3(const _mesa_glsl_parse_state *state) { return state->ARB_shading_language_packing_enable || - state->is_version(400, 0); + state->is_version(400, 300); } static bool -shader_packing_or_es3(const _mesa_glsl_parse_state *state) +shader_packing_or_es3_or_gpu_shader5(const _mesa_glsl_parse_state *state) { return state->ARB_shading_language_packing_enable || + state->ARB_gpu_shader5_enable || state->is_version(400, 300); } @@ -214,6 +215,13 @@ gpu_shader5(const _mesa_glsl_parse_state *state) } static bool +shader_packing_or_gpu_shader5(const _mesa_glsl_parse_state *state) +{ + return state->ARB_shading_language_packing_enable || + gpu_shader5(state); +} + +static bool texture_array_lod(const _mesa_glsl_parse_state *state) { return lod_exists_in_stage(state) && @@ -991,16 +999,16 @@ builtin_builder::create_builtins() _uintBitsToFloat(glsl_type::uvec4_type), NULL); - add_function("packUnorm2x16", _packUnorm2x16(shader_packing_or_es3), NULL); - add_function("packSnorm2x16", _packSnorm2x16(shader_packing_or_es3), NULL); - add_function("packUnorm4x8", _packUnorm4x8(shader_packing), NULL); - add_function("packSnorm4x8", _packSnorm4x8(shader_packing), NULL); - add_function("unpackUnorm2x16", _unpackUnorm2x16(shader_packing_or_es3), NULL); - add_function("unpackSnorm2x16", _unpackSnorm2x16(shader_packing_or_es3), NULL); - add_function("unpackUnorm4x8", _unpackUnorm4x8(shader_packing), NULL); - add_function("unpackSnorm4x8", _unpackSnorm4x8(shader_packing), NULL); - add_function("packHalf2x16", _packHalf2x16(shader_packing_or_es3), NULL); - add_function("unpackHalf2x16", _unpackHalf2x16(shader_packing_or_es3), NULL); + add_function("packUnorm2x16", _packUnorm2x16(shader_packing_or_es3_or_gpu_shader5), NULL); + add_function("packSnorm2x16", _packSnorm2x16(shader_packing_or_es3), NULL); + add_function("packUnorm4x8", _packUnorm4x8(shader_packing_or_gpu_shader5), NULL); + add_function("packSnorm4x8", _packSnorm4x8(shader_packing_or_gpu_shader5), NULL); + add_function("unpackUnorm2x16", _unpackUnorm2x16(shader_packing_or_es3_or_gpu_shader5), NULL); + add_function("unpackSnorm2x16", _unpackSnorm2x16(shader_packing_or_es3), NULL); + add_function("unpackUnorm4x8", _unpackUnorm4x8(shader_packing_or_gpu_shader5), NULL); + add_function("unpackSnorm4x8", _unpackSnorm4x8(shader_packing_or_gpu_shader5), NULL); + add_function("packHalf2x16", _packHalf2x16(shader_packing_or_es3), NULL); + add_function("unpackHalf2x16", _unpackHalf2x16(shader_packing_or_es3), NULL); F(length) F(distance) @@ -3041,7 +3049,7 @@ builtin_builder::_length(const glsl_type *type) ir_variable *x = in_var(type, "x"); MAKE_SIG(glsl_type::float_type, always_available, 1, x); - body.emit(ret(sqrt(dotlike(x, x)))); + body.emit(ret(sqrt(dot(x, x)))); return sig; } @@ -3131,7 +3139,7 @@ builtin_builder::_faceforward(const glsl_type *type) ir_variable *Nref = in_var(type, "Nref"); MAKE_SIG(type, always_available, 3, N, I, Nref); - body.emit(if_tree(less(dotlike(Nref, I), imm(0.0f)), + body.emit(if_tree(less(dot(Nref, I), imm(0.0f)), ret(N), ret(neg(N)))); return sig; @@ -3145,7 +3153,7 @@ builtin_builder::_reflect(const glsl_type *type) MAKE_SIG(type, always_available, 2, I, N); /* I - 2 * dot(N, I) * N */ - body.emit(ret(sub(I, mul(imm(2.0f), mul(dotlike(N, I), N))))); + body.emit(ret(sub(I, mul(imm(2.0f), mul(dot(N, I), N))))); return sig; } @@ -3159,7 +3167,7 @@ builtin_builder::_refract(const glsl_type *type) MAKE_SIG(type, always_available, 3, I, N, eta); ir_variable *n_dot_i = body.make_temp(glsl_type::float_type, "n_dot_i"); - body.emit(assign(n_dot_i, dotlike(N, I))); + body.emit(assign(n_dot_i, dot(N, I))); /* From the GLSL 1.10 specification: * k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)) diff --git a/mesalib/src/glsl/ir_builder.cpp b/mesalib/src/glsl/ir_builder.cpp index 7f41ed69e..f4a1c6efa 100644 --- a/mesalib/src/glsl/ir_builder.cpp +++ b/mesalib/src/glsl/ir_builder.cpp @@ -251,13 +251,8 @@ ir_expression *round_even(operand a) return expr(ir_unop_round_even, a); } -ir_expression *dot(operand a, operand b) -{ - return expr(ir_binop_dot, a, b); -} - /* dot for vectors, mul for scalars */ -ir_expression *dotlike(operand a, operand b) +ir_expression *dot(operand a, operand b) { assert(a.val->type == b.val->type); diff --git a/mesalib/src/glsl/ir_builder.h b/mesalib/src/glsl/ir_builder.h index f00e6f3b3..108b53a5e 100644 --- a/mesalib/src/glsl/ir_builder.h +++ b/mesalib/src/glsl/ir_builder.h @@ -139,7 +139,6 @@ ir_expression *carry(operand a, operand b); ir_expression *borrow(operand a, operand b); ir_expression *round_even(operand a); ir_expression *dot(operand a, operand b); -ir_expression *dotlike(operand a, operand b); ir_expression *clamp(operand a, operand b, operand c); ir_expression *saturate(operand a); ir_expression *abs(operand a); diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index f6b266185..3bf278965 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -2303,17 +2303,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) } /* Mark all generic shader inputs and outputs as unpaired. */ - if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { - link_invalidate_variable_locations( - prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir); - } - if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { - link_invalidate_variable_locations( - prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir); - } - if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) { - link_invalidate_variable_locations( - prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir); + for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) { + if (prog->_LinkedShaders[i] != NULL) { + link_invalidate_variable_locations(prog->_LinkedShaders[i]->ir); + } } /* FINISHME: The value of the max_attribute_index parameter is diff --git a/mesalib/src/glsl/lower_packed_varyings.cpp b/mesalib/src/glsl/lower_packed_varyings.cpp index c23d1801b..8c1b8850b 100644 --- a/mesalib/src/glsl/lower_packed_varyings.cpp +++ b/mesalib/src/glsl/lower_packed_varyings.cpp @@ -199,8 +199,8 @@ private: /** * Number of generic varying slots which are used by this shader. This is - * used to allocate temporary intermediate data structures. If any any - * varying used by this shader has a location greater than or equal to + * used to allocate temporary intermediate data structures. If any varying + * used by this shader has a location greater than or equal to * location_base + locations_used, an assertion will fire. */ const unsigned locations_used; diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp index 5c49a785c..8494bd9ec 100644 --- a/mesalib/src/glsl/opt_algebraic.cpp +++ b/mesalib/src/glsl/opt_algebraic.cpp @@ -528,6 +528,14 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) if (is_vec_two(op_const[0])) return expr(ir_unop_exp2, ir->operands[1]); + if (is_vec_two(op_const[1])) { + ir_variable *x = new(ir) ir_variable(ir->operands[1]->type, "x", + ir_var_temporary); + base_ir->insert_before(x); + base_ir->insert_before(assign(x, ir->operands[0])); + return mul(x, x); + } + break; case ir_unop_rcp: diff --git a/mesalib/src/glsl/opt_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp index e7d46edbe..0c5c684a4 100644 --- a/mesalib/src/glsl/opt_dead_code_local.cpp +++ b/mesalib/src/glsl/opt_dead_code_local.cpp @@ -51,14 +51,14 @@ public: assert(ir); this->lhs = lhs; this->ir = ir; - this->available = ir->write_mask; + this->unused = ir->write_mask; } ir_variable *lhs; ir_assignment *ir; /* bitmask of xyzw channels written that haven't been used so far. */ - int available; + int unused; }; class kill_for_derefs_visitor : public ir_hierarchical_visitor { @@ -68,7 +68,7 @@ public: this->assignments = assignments; } - void kill_channels(ir_variable *const var, int used) + void use_channels(ir_variable *const var, int used) { foreach_list_safe(n, this->assignments) { assignment_entry *entry = (assignment_entry *) n; @@ -76,14 +76,14 @@ public: if (entry->lhs == var) { if (var->type->is_scalar() || var->type->is_vector()) { if (debug) - printf("kill %s (0x%01x - 0x%01x)\n", entry->lhs->name, - entry->available, used); - entry->available &= ~used; - if (!entry->available) + printf("used %s (0x%01x - 0x%01x)\n", entry->lhs->name, + entry->unused, used & 0xf); + entry->unused &= ~used; + if (!entry->unused) entry->remove(); } else { if (debug) - printf("kill %s\n", entry->lhs->name); + printf("used %s\n", entry->lhs->name); entry->remove(); } } @@ -92,7 +92,7 @@ public: virtual ir_visitor_status visit(ir_dereference_variable *ir) { - kill_channels(ir->var, ~0); + use_channels(ir->var, ~0); return visit_continue; } @@ -109,7 +109,7 @@ public: used |= 1 << ir->mask.z; used |= 1 << ir->mask.w; - kill_channels(deref->var, used); + use_channels(deref->var, used); return visit_continue_with_parent; } @@ -202,7 +202,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) if (entry->lhs != var) continue; - int remove = entry->available & ir->write_mask; + int remove = entry->unused & ir->write_mask; if (debug) { printf("%s 0x%01x - 0x%01x = 0x%01x\n", var->name, @@ -219,7 +219,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) } entry->ir->write_mask &= ~remove; - entry->available &= ~remove; + entry->unused &= ~remove; if (entry->ir->write_mask == 0) { /* Delete the dead assignment. */ entry->ir->remove(); @@ -283,7 +283,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) foreach_list(n, assignments) { assignment_entry *entry = (assignment_entry *) n; - printf(" %s (0x%01x)\n", entry->lhs->name, entry->available); + printf(" %s (0x%01x)\n", entry->lhs->name, entry->unused); } } diff --git a/mesalib/src/loader/Makefile.sources b/mesalib/src/loader/Makefile.sources index 51a64ea6a..1a1345fcd 100644 --- a/mesalib/src/loader/Makefile.sources +++ b/mesalib/src/loader/Makefile.sources @@ -1,2 +1,3 @@ LOADER_C_FILES := \ - loader.c
\ No newline at end of file + loader.c \ + pci_id_driver_map.c diff --git a/mesalib/src/loader/loader.c b/mesalib/src/loader/loader.c index 811f8a257..e343f4a57 100644 --- a/mesalib/src/loader/loader.c +++ b/mesalib/src/loader/loader.c @@ -78,7 +78,7 @@ #endif #define __IS_LOADER -#include "pci_ids/pci_id_driver_map.h" +#include "pci_id_driver_map.h" static void default_logger(int level, const char *fmt, ...) { @@ -352,6 +352,9 @@ loader_get_driver_for_fd(int fd, unsigned driver_types) if (!(driver_types & driver_map[i].driver_types)) continue; + if (driver_map[i].predicate && !driver_map[i].predicate(fd)) + continue; + if (driver_map[i].num_chips_ids == -1) { driver = strdup(driver_map[i].driver); goto out; diff --git a/mesalib/src/loader/pci_id_driver_map.c b/mesalib/src/loader/pci_id_driver_map.c new file mode 100644 index 000000000..cb6f705ac --- /dev/null +++ b/mesalib/src/loader/pci_id_driver_map.c @@ -0,0 +1,55 @@ +/* + * Copyright 2014 Ilia Mirkin + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +int is_nouveau_vieux(int fd); + +#ifndef __NOT_HAVE_DRM_H + +#include <xf86drm.h> +#include <nouveau_drm.h> + +static int +nouveau_chipset(int fd) +{ + struct drm_nouveau_getparam gp = { NOUVEAU_GETPARAM_CHIPSET_ID, 0 }; + int ret; + + ret = drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &gp, sizeof(gp)); + if (ret) + return -1; + + return gp.value; +} + +int +is_nouveau_vieux(int fd) +{ + int chipset = nouveau_chipset(fd); + return chipset > 0 && chipset < 0x30; +} + +#else + +int is_nouveau_vieux(int fd) { return 0; } + +#endif diff --git a/mesalib/src/loader/pci_id_driver_map.h b/mesalib/src/loader/pci_id_driver_map.h new file mode 100644 index 000000000..11e39d3a2 --- /dev/null +++ b/mesalib/src/loader/pci_id_driver_map.h @@ -0,0 +1,85 @@ +#ifndef _PCI_ID_DRIVER_MAP_H_ +#define _PCI_ID_DRIVER_MAP_H_ + +#include <stddef.h> + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#ifndef __IS_LOADER +# error "Only include from loader.c" +#endif + +static const int i915_chip_ids[] = { +#define CHIPSET(chip, desc, name) chip, +#include "pci_ids/i915_pci_ids.h" +#undef CHIPSET +}; + +static const int i965_chip_ids[] = { +#define CHIPSET(chip, family, name) chip, +#include "pci_ids/i965_pci_ids.h" +#undef CHIPSET +}; + +static const int r100_chip_ids[] = { +#define CHIPSET(chip, name, family) chip, +#include "pci_ids/radeon_pci_ids.h" +#undef CHIPSET +}; + +static const int r200_chip_ids[] = { +#define CHIPSET(chip, name, family) chip, +#include "pci_ids/r200_pci_ids.h" +#undef CHIPSET +}; + +static const int r300_chip_ids[] = { +#define CHIPSET(chip, name, family) chip, +#include "pci_ids/r300_pci_ids.h" +#undef CHIPSET +}; + +static const int r600_chip_ids[] = { +#define CHIPSET(chip, name, family) chip, +#include "pci_ids/r600_pci_ids.h" +#undef CHIPSET +}; + +static const int radeonsi_chip_ids[] = { +#define CHIPSET(chip, name, family) chip, +#include "pci_ids/radeonsi_pci_ids.h" +#undef CHIPSET +}; + +static const int vmwgfx_chip_ids[] = { +#define CHIPSET(chip, name, family) chip, +#include "pci_ids/vmwgfx_pci_ids.h" +#undef CHIPSET +}; + +int is_nouveau_vieux(int fd); + +static const struct { + int vendor_id; + const char *driver; + const int *chip_ids; + int num_chips_ids; + unsigned driver_types; + int (*predicate)(int fd); +} driver_map[] = { + { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids), _LOADER_DRI | _LOADER_GALLIUM }, + { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids), _LOADER_DRI | _LOADER_GALLIUM }, + { 0x1002, "radeon", r100_chip_ids, ARRAY_SIZE(r100_chip_ids), _LOADER_DRI }, + { 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids), _LOADER_DRI }, + { 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids), _LOADER_GALLIUM }, + { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids), _LOADER_GALLIUM }, + { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids), _LOADER_GALLIUM}, + { 0x10de, "nouveau_vieux", NULL, -1, _LOADER_DRI, is_nouveau_vieux }, + { 0x10de, "nouveau", NULL, -1, _LOADER_GALLIUM }, + { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids), _LOADER_GALLIUM }, + { 0x0000, NULL, NULL, 0 }, +}; + +#endif /* _PCI_ID_DRIVER_MAP_H_ */ diff --git a/mesalib/src/mapi/mapi_glapi.c b/mesalib/src/mapi/mapi_glapi.c index 7b0903be9..127dfafac 100644 --- a/mesalib/src/mapi/mapi_glapi.c +++ b/mesalib/src/mapi/mapi_glapi.c @@ -222,6 +222,16 @@ _glapi_get_proc_name(unsigned int offset) return stub ? stub_get_name(stub) : NULL; } +/** + * This is a deprecated function which should not be used anymore. + * It's only present to satisfy linking with older versions of libGL. + */ +unsigned long +_glthread_GetID(void) +{ + return 0; +} + void _glapi_noop_enable_warnings(unsigned char enable) { diff --git a/mesalib/src/mesa/main/blend.c b/mesalib/src/mesa/main/blend.c index eb4f1d6be..c37c0fea5 100644 --- a/mesalib/src/mesa/main/blend.c +++ b/mesalib/src/mesa/main/blend.c @@ -911,7 +911,9 @@ void _mesa_init_color( struct gl_context * ctx ) ctx->Color.LogicOp = GL_COPY; ctx->Color.DitherFlag = GL_TRUE; - if (ctx->Visual.doubleBufferMode) { + /* GL_FRONT is not possible on GLES. Instead GL_BACK will render to either + * the front or the back buffer depending on the config */ + if (ctx->Visual.doubleBufferMode || _mesa_is_gles(ctx)) { ctx->Color.DrawBuffer[0] = GL_BACK; } else { diff --git a/mesalib/src/mesa/main/buffers.c b/mesalib/src/mesa/main/buffers.c index 6cbce9d5d..b13a7af65 100644 --- a/mesalib/src/mesa/main/buffers.c +++ b/mesalib/src/mesa/main/buffers.c @@ -101,7 +101,7 @@ draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer) case GL_FRONT: return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT; case GL_BACK: - if (_mesa_is_gles3(ctx)) { + if (_mesa_is_gles(ctx)) { /* Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL * ES 3.0.1 specification says: * @@ -111,6 +111,11 @@ draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer) * * Since there is no stereo rendering in ES 3.0, only return the * LEFT bits. This also satisfies the "n must be 1" requirement. + * + * We also do this for GLES 1 and 2 because those APIs have no + * concept of selecting the front and back buffer anyway and it's + * convenient to be able to maintain the magic behaviour of + * GL_BACK in that case. */ if (ctx->DrawBuffer->Visual.doubleBufferMode) return BUFFER_BIT_BACK_LEFT; diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index a19180870..21dee98b6 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -1013,7 +1013,8 @@ _mesa_initialize_dispatch_tables(struct gl_context *ctx) * * \param ctx the context to initialize * \param api the GL API type to create the context for - * \param visual describes the visual attributes for this context + * \param visual describes the visual attributes for this context or NULL to + * create a configless context * \param share_list points to context to share textures, display lists, * etc with, or NULL * \param driverFunctions table of device driver functions for this context @@ -1033,12 +1034,20 @@ _mesa_initialize_context(struct gl_context *ctx, assert(driverFunctions->FreeTextureImageBuffer); ctx->API = api; - ctx->Visual = *visual; ctx->DrawBuffer = NULL; ctx->ReadBuffer = NULL; ctx->WinSysDrawBuffer = NULL; ctx->WinSysReadBuffer = NULL; + if (visual) { + ctx->Visual = *visual; + ctx->HasConfig = GL_TRUE; + } + else { + memset(&ctx->Visual, 0, sizeof ctx->Visual); + ctx->HasConfig = GL_FALSE; + } + if (_mesa_is_desktop_gl(ctx)) { _mesa_override_gl_version(ctx); } @@ -1145,7 +1154,8 @@ fail: * the rendering context. * * \param api the GL API type to create the context for - * \param visual a struct gl_config pointer (we copy the struct contents) + * \param visual a struct gl_config pointer (we copy the struct contents) or + * NULL to create a configless context * \param share_list another context to share display lists with or NULL * \param driverFunctions points to the dd_function_table into which the * driver has plugged in all its special functions. @@ -1160,8 +1170,6 @@ _mesa_create_context(gl_api api, { struct gl_context *ctx; - ASSERT(visual); - ctx = calloc(1, sizeof(struct gl_context)); if (!ctx) return NULL; @@ -1475,6 +1483,54 @@ _mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height) } } +static void +handle_first_current(struct gl_context *ctx) +{ + GLenum buffer; + GLint bufferIndex; + + assert(ctx->Version > 0); + + ctx->Extensions.String = _mesa_make_extension_string(ctx); + + check_context_limits(ctx); + + /* According to GL_MESA_configless_context the default value of + * glDrawBuffers depends on the config of the first surface it is bound to. + * For GLES it is always GL_BACK which has a magic interpretation */ + if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) { + if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) { + if (ctx->DrawBuffer->Visual.doubleBufferMode) + buffer = GL_BACK; + else + buffer = GL_FRONT; + + _mesa_drawbuffers(ctx, 1, &buffer, NULL /* destMask */); + } + + if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) { + if (ctx->ReadBuffer->Visual.doubleBufferMode) { + buffer = GL_BACK; + bufferIndex = BUFFER_BACK_LEFT; + } + else { + buffer = GL_FRONT; + bufferIndex = BUFFER_FRONT_LEFT; + } + + _mesa_readbuffer(ctx, buffer, bufferIndex); + } + } + + /* We can use this to help debug user's problems. Tell them to set + * the MESA_INFO env variable before running their app. Then the + * first time each context is made current we'll print some useful + * information. + */ + if (_mesa_getenv("MESA_INFO")) { + _mesa_print_info(ctx); + } +} /** * Bind the given context to the given drawBuffer and readBuffer and @@ -1567,21 +1623,7 @@ _mesa_make_current( struct gl_context *newCtx, } if (newCtx->FirstTimeCurrent) { - assert(newCtx->Version > 0); - - newCtx->Extensions.String = _mesa_make_extension_string(newCtx); - - check_context_limits(newCtx); - - /* We can use this to help debug user's problems. Tell them to set - * the MESA_INFO env variable before running their app. Then the - * first time each context is made current we'll print some useful - * information. - */ - if (_mesa_getenv("MESA_INFO")) { - _mesa_print_info(newCtx); - } - + handle_first_current(newCtx); newCtx->FirstTimeCurrent = GL_FALSE; } } diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index 8ec6a8c33..9151718ea 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -969,7 +969,7 @@ _mesa_init_errors(struct gl_context *ctx) /** * Loop through debug group stack tearing down states for - * filtering debug messages. + * filtering debug messages. Then free debug output state. */ void _mesa_free_errors_data(struct gl_context *ctx) @@ -980,6 +980,9 @@ _mesa_free_errors_data(struct gl_context *ctx) for (i = 0; i <= ctx->Debug->GroupStackDepth; i++) { free_errors_data(ctx, i); } + FREE(ctx->Debug); + /* set to NULL just in case it is used before context is completely gone. */ + ctx->Debug = NULL; } } diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index a9dcc5144..dfe2f1e93 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -1565,10 +1565,6 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) return ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_texture_float && ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0; - case GL_RGB9_E5: - return (_mesa_is_desktop_gl(ctx) - && ctx->Extensions.EXT_texture_shared_exponent) - ? GL_RGB : 0; case GL_R11F_G11F_B10F: return ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_packed_float) || _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ ) diff --git a/mesalib/src/mesa/main/genmipmap.c b/mesalib/src/mesa/main/genmipmap.c index dcd482da2..9d111cab2 100644 --- a/mesalib/src/mesa/main/genmipmap.c +++ b/mesalib/src/mesa/main/genmipmap.c @@ -74,6 +74,10 @@ _mesa_GenerateMipmap(GLenum target) error = (_mesa_is_gles(ctx) && ctx->Version < 30) || !ctx->Extensions.EXT_texture_array; break; + case GL_TEXTURE_CUBE_MAP_ARRAY: + error = _mesa_is_gles(ctx) || + !ctx->Extensions.ARB_texture_cube_map_array; + break; default: error = GL_TRUE; } diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index b1908515c..88cf202df 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -1997,7 +1997,7 @@ _mesa_GetBooleani_v( GLenum pname, GLuint index, GLboolean *params ) params[3] = INT_TO_BOOLEAN(v.value_int_4[3]); break; case TYPE_INT64: - params[0] = INT64_TO_BOOLEAN(v.value_int); + params[0] = INT64_TO_BOOLEAN(v.value_int64); break; default: ; /* nothing - GL error was recorded */ @@ -2042,7 +2042,7 @@ _mesa_GetIntegeri_v( GLenum pname, GLuint index, GLint *params ) params[3] = v.value_int_4[3]; break; case TYPE_INT64: - params[0] = INT64_TO_INT(v.value_int); + params[0] = INT64_TO_INT(v.value_int64); break; default: ; /* nothing - GL error was recorded */ @@ -2067,7 +2067,7 @@ _mesa_GetInteger64i_v( GLenum pname, GLuint index, GLint64 *params ) params[3] = v.value_int_4[3]; break; case TYPE_INT64: - params[0] = v.value_int; + params[0] = v.value_int64; break; default: ; /* nothing - GL error was recorded */ diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index 521b2d8eb..cc109cc52 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -1548,23 +1548,18 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, const GLint dstDepthNB = dstDepth - 2 * border; GLint img, row; GLint bytesPerSrcImage, bytesPerDstImage; - GLint bytesPerSrcRow, bytesPerDstRow; GLint srcImageOffset, srcRowOffset; (void) srcDepthNB; /* silence warnings */ - - bytesPerSrcImage = srcWidth * srcHeight * bpt; - bytesPerDstImage = dstWidth * dstHeight * bpt; - - bytesPerSrcRow = srcWidth * bpt; - bytesPerDstRow = dstWidth * bpt; + bytesPerSrcImage = srcRowStride * srcHeight * bpt; + bytesPerDstImage = dstRowStride * dstHeight * bpt; /* Offset between adjacent src images to be averaged together */ srcImageOffset = (srcDepth == dstDepth) ? 0 : 1; /* Offset between adjacent src rows to be averaged together */ - srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt; + srcRowOffset = (srcHeight == dstHeight) ? 0 : srcRowStride; /* * Need to average together up to 8 src pixels for each dest pixel. @@ -1582,14 +1577,14 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, for (img = 0; img < dstDepthNB; img++) { /* first source image pointer, skipping border */ const GLubyte *imgSrcA = srcPtr[img * 2 + border] - + bytesPerSrcRow * border + bpt * border; + + srcRowStride * border + bpt * border; /* second source image pointer, skipping border */ const GLubyte *imgSrcB = srcPtr[img * 2 + srcImageOffset + border] - + bytesPerSrcRow * border + bpt * border; + + srcRowStride * border + bpt * border; /* address of the dest image, skipping border */ GLubyte *imgDst = dstPtr[img + border] - + bytesPerDstRow * border + bpt * border; + + dstRowStride * border + bpt * border; /* setup the four source row pointers and the dest row pointer */ const GLubyte *srcImgARowA = imgSrcA; @@ -1605,11 +1600,11 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, dstWidthNB, dstImgRow); /* advance to next rows */ - srcImgARowA += bytesPerSrcRow + srcRowOffset; - srcImgARowB += bytesPerSrcRow + srcRowOffset; - srcImgBRowA += bytesPerSrcRow + srcRowOffset; - srcImgBRowB += bytesPerSrcRow + srcRowOffset; - dstImgRow += bytesPerDstRow; + srcImgARowA += srcRowStride + srcRowOffset; + srcImgARowB += srcRowStride + srcRowOffset; + srcImgBRowA += srcRowStride + srcRowOffset; + srcImgBRowB += srcRowStride + srcRowOffset; + dstImgRow += dstRowStride; } } @@ -1638,8 +1633,8 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, memcpy(dst, src, bpt); /* do border along [img][row=dstHeight-1][col=0] */ - src = srcPtr[img * 2] + (srcHeight - 1) * bytesPerSrcRow; - dst = dstPtr[img] + (dstHeight - 1) * bytesPerDstRow; + src = srcPtr[img * 2] + (srcHeight - 1) * srcRowStride; + dst = dstPtr[img] + (dstHeight - 1) * dstRowStride; memcpy(dst, src, bpt); /* do border along [img][row=0][col=dstWidth-1] */ @@ -1668,10 +1663,10 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, /* do border along [img][row=dstHeight-1][col=0] */ srcA = srcPtr[img * 2 + 0] - + (srcHeight - 1) * bytesPerSrcRow; + + (srcHeight - 1) * srcRowStride; srcB = srcPtr[img * 2 + srcImageOffset] - + (srcHeight - 1) * bytesPerSrcRow; - dst = dstPtr[img] + (dstHeight - 1) * bytesPerDstRow; + + (srcHeight - 1) * srcRowStride; + dst = dstPtr[img] + (dstHeight - 1) * dstRowStride; do_row(datatype, comps, 1, srcA, srcB, 1, dst); /* do border along [img][row=0][col=dstWidth-1] */ @@ -1746,6 +1741,7 @@ _mesa_generate_mipmap_level(GLenum target, } break; case GL_TEXTURE_2D_ARRAY_EXT: + case GL_TEXTURE_CUBE_MAP_ARRAY: for (i = 0; i < dstDepth; i++) { make_2d_mipmap(datatype, comps, border, srcWidth, srcHeight, srcData[i], srcRowStride, @@ -1788,7 +1784,8 @@ _mesa_next_mipmap_level_size(GLenum target, GLint border, } if ((srcDepth - 2 * border > 1) && - (target != GL_TEXTURE_2D_ARRAY_EXT)) { + (target != GL_TEXTURE_2D_ARRAY_EXT && + target != GL_TEXTURE_CUBE_MAP_ARRAY)) { *dstDepth = (srcDepth - 2 * border) / 2 + 2 * border; } else { @@ -2029,7 +2026,8 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target, /* only two types of compressed textures at this time */ assert(texObj->Target == GL_TEXTURE_2D || texObj->Target == GL_TEXTURE_2D_ARRAY || - texObj->Target == GL_TEXTURE_CUBE_MAP_ARB); + texObj->Target == GL_TEXTURE_CUBE_MAP_ARB || + texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY); /* * Choose a format for the temporary, uncompressed base image. diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 7c83d664f..c6d90c579 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -4212,6 +4212,12 @@ struct gl_context GLboolean FirstTimeCurrent; /*@}*/ + /** + * False if this context was created without a config. This is needed + * because the initial state of glDrawBuffers depends on this + */ + GLboolean HasConfig; + /** software compression/decompression supported or not */ GLboolean Mesa_DXTn; diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index a6c3581bf..57a766f99 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -160,6 +160,9 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32: return GL_DEPTH_COMPONENT; + case GL_DEPTH_STENCIL: + case GL_DEPTH24_STENCIL8: + return GL_DEPTH_STENCIL; default: ; /* fallthrough */ } @@ -301,14 +304,6 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) } } - switch (internalFormat) { - case GL_DEPTH_STENCIL: - case GL_DEPTH24_STENCIL8: - return GL_DEPTH_STENCIL; - default: - ; /* fallthrough */ - } - if (ctx->Extensions.EXT_texture_sRGB) { switch (internalFormat) { case GL_SRGB_EXT: @@ -1662,7 +1657,10 @@ error_check_subtexture_dimensions(struct gl_context *ctx, /* check zoffset and depth */ if (dims > 2) { - GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : destImage->Border; + GLint zBorder = (target == GL_TEXTURE_2D_ARRAY || + target == GL_TEXTURE_CUBE_MAP_ARRAY) ? + 0 : destImage->Border; + if (zoffset < -zBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset)", function); return GL_TRUE; diff --git a/mesalib/src/mesa/program/register_allocate.c b/mesalib/src/mesa/program/register_allocate.c index 4eed0b5aa..6fac69033 100644 --- a/mesalib/src/mesa/program/register_allocate.c +++ b/mesalib/src/mesa/program/register_allocate.c @@ -82,7 +82,7 @@ #define NO_REG ~0 struct ra_reg { - GLboolean *conflicts; + BITSET_WORD *conflicts; unsigned int *conflict_list; unsigned int conflict_list_size; unsigned int num_conflicts; @@ -99,7 +99,12 @@ struct ra_regs { }; struct ra_class { - GLboolean *regs; + /** + * Bitset indicating which registers belong to this class. + * + * (If bit N is set, then register N belongs to this class.) + */ + BITSET_WORD *regs; /** * p(B) in Runeson/Nyström paper. @@ -139,7 +144,7 @@ struct ra_node { * "remove the edge from the graph" in simplification without * having to actually modify the adjacency_list. */ - GLboolean in_stack; + bool in_stack; /* For an implementation that needs register spilling, this is the * approximate cost of spilling this node. @@ -186,8 +191,9 @@ ra_alloc_reg_set(void *mem_ctx, unsigned int count) regs->regs = rzalloc_array(regs, struct ra_reg, count); for (i = 0; i < count; i++) { - regs->regs[i].conflicts = rzalloc_array(regs->regs, GLboolean, count); - regs->regs[i].conflicts[i] = GL_TRUE; + regs->regs[i].conflicts = rzalloc_array(regs->regs, BITSET_WORD, + BITSET_WORDS(count)); + BITSET_SET(regs->regs[i].conflicts, i); regs->regs[i].conflict_list = ralloc_array(regs->regs, unsigned int, 4); regs->regs[i].conflict_list_size = 4; @@ -225,13 +231,13 @@ ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2) unsigned int, reg1->conflict_list_size); } reg1->conflict_list[reg1->num_conflicts++] = r2; - reg1->conflicts[r2] = GL_TRUE; + BITSET_SET(reg1->conflicts, r2); } void ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2) { - if (!regs->regs[r1].conflicts[r2]) { + if (!BITSET_TEST(regs->regs[r1].conflicts, r2)) { ra_add_conflict_list(regs, r1, r2); ra_add_conflict_list(regs, r2, r1); } @@ -269,7 +275,7 @@ ra_alloc_reg_class(struct ra_regs *regs) class = rzalloc(regs, struct ra_class); regs->classes[regs->class_count] = class; - class->regs = rzalloc_array(class, GLboolean, regs->count); + class->regs = rzalloc_array(class, BITSET_WORD, BITSET_WORDS(regs->count)); return regs->class_count++; } @@ -279,11 +285,20 @@ ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int r) { struct ra_class *class = regs->classes[c]; - class->regs[r] = GL_TRUE; + BITSET_SET(class->regs, r); class->p++; } /** + * Returns true if the register belongs to the given class. + */ +static bool +reg_belongs_to_class(unsigned int r, struct ra_class *c) +{ + return BITSET_TEST(c->regs, r); +} + +/** * Must be called after all conflicts and register classes have been * set up and before the register set is used for allocation. * To avoid costly q value computation, use the q_values paramater @@ -319,12 +334,12 @@ ra_set_finalize(struct ra_regs *regs, unsigned int **q_values) int conflicts = 0; int i; - if (!regs->classes[c]->regs[rc]) + if (!reg_belongs_to_class(rc, regs->classes[c])) continue; for (i = 0; i < regs->regs[rc].num_conflicts; i++) { unsigned int rb = regs->regs[rc].conflict_list[i]; - if (regs->classes[b]->regs[rb]) + if (BITSET_TEST(regs->classes[b]->regs, rb)) conflicts++; } max_conflicts = MAX2(max_conflicts, conflicts); @@ -397,7 +412,8 @@ ra_add_node_interference(struct ra_graph *g, } } -static GLboolean pq_test(struct ra_graph *g, unsigned int n) +static bool +pq_test(struct ra_graph *g, unsigned int n) { unsigned int j; unsigned int q = 0; @@ -420,18 +436,18 @@ static GLboolean pq_test(struct ra_graph *g, unsigned int n) * trivially-colorable nodes into a stack of nodes to be colored, * removing them from the graph, and rinsing and repeating. * - * Returns GL_TRUE if all nodes were removed from the graph. GL_FALSE + * Returns true if all nodes were removed from the graph. false * means that either spilling will be required, or optimistic coloring * should be applied. */ -GLboolean +bool ra_simplify(struct ra_graph *g) { - GLboolean progress = GL_TRUE; + bool progress = true; int i; while (progress) { - progress = GL_FALSE; + progress = false; for (i = g->count - 1; i >= 0; i--) { if (g->nodes[i].in_stack || g->nodes[i].reg != NO_REG) @@ -440,18 +456,18 @@ ra_simplify(struct ra_graph *g) if (pq_test(g, i)) { g->stack[g->stack_count] = i; g->stack_count++; - g->nodes[i].in_stack = GL_TRUE; - progress = GL_TRUE; + g->nodes[i].in_stack = true; + progress = true; } } } for (i = 0; i < g->count; i++) { if (!g->nodes[i].in_stack && g->nodes[i].reg == -1) - return GL_FALSE; + return false; } - return GL_TRUE; + return true; } /** @@ -459,9 +475,9 @@ ra_simplify(struct ra_graph *g) * registers as they go. * * If all nodes were trivially colorable, then this must succeed. If - * not (optimistic coloring), then it may return GL_FALSE; + * not (optimistic coloring), then it may return false; */ -GLboolean +bool ra_select(struct ra_graph *g) { int i; @@ -478,7 +494,7 @@ ra_select(struct ra_graph *g) */ for (ri = 0; ri < g->regs->count; ri++) { r = (start_search_reg + ri) % g->regs->count; - if (!c->regs[r]) + if (!reg_belongs_to_class(r, c)) continue; /* Check if any of our neighbors conflict with this register choice. */ @@ -486,7 +502,7 @@ ra_select(struct ra_graph *g) unsigned int n2 = g->nodes[n].adjacency_list[i]; if (!g->nodes[n2].in_stack && - g->regs->regs[r].conflicts[g->nodes[n2].reg]) { + BITSET_TEST(g->regs->regs[r].conflicts, g->nodes[n2].reg)) { break; } } @@ -494,17 +510,17 @@ ra_select(struct ra_graph *g) break; } if (ri == g->regs->count) - return GL_FALSE; + return false; g->nodes[n].reg = r; - g->nodes[n].in_stack = GL_FALSE; + g->nodes[n].in_stack = false; g->stack_count--; if (g->regs->round_robin) start_search_reg = r + 1; } - return GL_TRUE; + return true; } /** @@ -526,11 +542,11 @@ ra_optimistic_color(struct ra_graph *g) g->stack[g->stack_count] = i; g->stack_count++; - g->nodes[i].in_stack = GL_TRUE; + g->nodes[i].in_stack = true; } } -GLboolean +bool ra_allocate_no_spills(struct ra_graph *g) { if (!ra_simplify(g)) { @@ -562,7 +578,7 @@ void ra_set_node_reg(struct ra_graph *g, unsigned int n, unsigned int reg) { g->nodes[n].reg = reg; - g->nodes[n].in_stack = GL_FALSE; + g->nodes[n].in_stack = false; } static float diff --git a/mesalib/src/mesa/program/register_allocate.h b/mesalib/src/mesa/program/register_allocate.h index fa119e320..337dcf709 100644 --- a/mesalib/src/mesa/program/register_allocate.h +++ b/mesalib/src/mesa/program/register_allocate.h @@ -25,6 +25,8 @@ * */ +#include <stdbool.h> + struct ra_class; struct ra_regs; @@ -64,10 +66,10 @@ void ra_add_node_interference(struct ra_graph *g, /** @} */ /** @{ Graph-coloring register allocation */ -GLboolean ra_simplify(struct ra_graph *g); +bool ra_simplify(struct ra_graph *g); void ra_optimistic_color(struct ra_graph *g); -GLboolean ra_select(struct ra_graph *g); -GLboolean ra_allocate_no_spills(struct ra_graph *g); +bool ra_select(struct ra_graph *g); +bool ra_allocate_no_spills(struct ra_graph *g); unsigned int ra_get_node_reg(struct ra_graph *g, unsigned int n); void ra_set_node_reg(struct ra_graph * g, unsigned int n, unsigned int reg); diff --git a/mesalib/src/mesa/state_tracker/st_atom.c b/mesalib/src/mesa/state_tracker/st_atom.c index 32ce1eaaa..99e9df26b 100644 --- a/mesalib/src/mesa/state_tracker/st_atom.c +++ b/mesalib/src/mesa/state_tracker/st_atom.c @@ -132,16 +132,26 @@ static void check_program_state( struct st_context *st ) static void check_attrib_edgeflag(struct st_context *st) { const struct gl_client_array **arrays = st->ctx->Array._DrawArrays; - GLboolean vertDataEdgeFlags; + GLboolean vertdata_edgeflags, edgeflag_culls_prims, edgeflags_enabled; if (!arrays) return; - vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj && - arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name; - if (vertDataEdgeFlags != st->vertdata_edgeflags) { - st->vertdata_edgeflags = vertDataEdgeFlags; - st->dirty.st |= ST_NEW_EDGEFLAGS_DATA; + edgeflags_enabled = st->ctx->Polygon.FrontMode != GL_FILL || + st->ctx->Polygon.BackMode != GL_FILL; + + vertdata_edgeflags = edgeflags_enabled && + arrays[VERT_ATTRIB_EDGEFLAG]->StrideB != 0; + if (vertdata_edgeflags != st->vertdata_edgeflags) { + st->vertdata_edgeflags = vertdata_edgeflags; + st->dirty.st |= ST_NEW_VERTEX_PROGRAM; + } + + edgeflag_culls_prims = edgeflags_enabled && !vertdata_edgeflags && + !st->ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0]; + if (edgeflag_culls_prims != st->edgeflag_culls_prims) { + st->edgeflag_culls_prims = edgeflag_culls_prims; + st->dirty.st |= ST_NEW_RASTERIZER; } } diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c index a4f3ffee3..ee5e9e574 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c @@ -236,6 +236,14 @@ static void update_raster_state( struct st_context *st ) /* ST_NEW_RASTERIZER */ raster->rasterizer_discard = ctx->RasterDiscard; + if (st->edgeflag_culls_prims) { + /* All edge flags are FALSE. Cull the affected faces. */ + if (raster->fill_front != PIPE_POLYGON_MODE_FILL) + raster->cull_face |= PIPE_FACE_FRONT; + if (raster->fill_back != PIPE_POLYGON_MODE_FILL) + raster->cull_face |= PIPE_FACE_BACK; + } + /* _NEW_TRANSFORM */ raster->depth_clip = ctx->Transform.DepthClamp == GL_FALSE; raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled; diff --git a/mesalib/src/mesa/state_tracker/st_atom_shader.c b/mesalib/src/mesa/state_tracker/st_atom_shader.c index ba04c1fb7..67c615713 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_shader.c +++ b/mesalib/src/mesa/state_tracker/st_atom_shader.c @@ -141,11 +141,8 @@ update_vp( struct st_context *st ) * edgeflag semantics, and extend the vertex shader to pass through * the input to the output. We'll need to use similar logic to set * up the extra vertex_element input for edgeflags. - * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA */ - key.passthrough_edgeflags = (st->vertdata_edgeflags && ( - st->ctx->Polygon.FrontMode != GL_FILL || - st->ctx->Polygon.BackMode != GL_FILL)); + key.passthrough_edgeflags = st->vertdata_edgeflags; key.clamp_color = st->clamp_vert_color_in_shader && st->ctx->Light._ClampVertexColor; @@ -164,8 +161,8 @@ update_vp( struct st_context *st ) const struct st_tracked_state st_update_vp = { "st_update_vp", /* name */ { /* dirty */ - _NEW_POLYGON, /* mesa */ - ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA /* st */ + 0, /* mesa */ + ST_NEW_VERTEX_PROGRAM /* st */ }, update_vp /* update */ }; diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 9c699a015..0e00dd4fa 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -47,7 +47,7 @@ struct u_upload_mgr; #define ST_NEW_FRAGMENT_PROGRAM (1 << 1) #define ST_NEW_VERTEX_PROGRAM (1 << 2) #define ST_NEW_FRAMEBUFFER (1 << 3) -#define ST_NEW_EDGEFLAGS_DATA (1 << 4) +/* gap, re-use it */ #define ST_NEW_GEOMETRY_PROGRAM (1 << 5) #define ST_NEW_VERTEX_ARRAYS (1 << 6) #define ST_NEW_RASTERIZER (1 << 7) @@ -131,6 +131,7 @@ struct st_context GLboolean missing_textures; GLboolean vertdata_edgeflags; + GLboolean edgeflag_culls_prims; /** Mapping from VARYING_SLOT_x to post-transformed vertex slot */ const GLuint *vertex_result_to_slot; diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index 355c180f8..dba5870a0 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -164,16 +164,6 @@ translate_prim(const struct gl_context *ctx, unsigned prim) STATIC_ASSERT(GL_QUADS == PIPE_PRIM_QUADS); STATIC_ASSERT(GL_TRIANGLE_STRIP_ADJACENCY == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY); - /* Avoid quadstrips if it's easy to do so: - * Note: it's important to do the correct trimming if we change the - * prim type! We do that wherever this function is called. - */ - if (prim == GL_QUAD_STRIP && - ctx->Light.ShadeModel != GL_FLAT && - ctx->Polygon.FrontMode == GL_FILL && - ctx->Polygon.BackMode == GL_FILL) - prim = GL_TRIANGLE_STRIP; - return prim; } diff --git a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c index 04333f75e..b615575b5 100644 --- a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c +++ b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c @@ -221,7 +221,8 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, else { dstHeight = u_minify(pt->height0, dstLevel); } - if (texObj->Target == GL_TEXTURE_2D_ARRAY) { + if (texObj->Target == GL_TEXTURE_2D_ARRAY || + texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) { dstDepth = pt->array_size; } else { diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index e9074ac97..692a57008 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -342,14 +342,14 @@ st_translate_vertex_program(struct st_context *st, stvp->glsl_to_tgsi, &stvp->Base.Base, /* inputs */ - stvp->num_inputs, + vpv->num_inputs, stvp->input_to_index, NULL, /* input semantic name */ NULL, /* input semantic index */ NULL, /* interp mode */ NULL, /* is centroid */ /* outputs */ - stvp->num_outputs, + num_outputs, stvp->result_to_output, stvp->output_semantic_name, stvp->output_semantic_index, |