From: Marek Olšák Date: Tue, 26 Apr 2011 00:27:25 +0000 (+0200) Subject: mesa: implement EXT_packed_float X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=631d23daa91c569bf268a2191bd466df73a64263;p=mesa.git mesa: implement EXT_packed_float Reviewed-by: Brian Paul Reviewed-by: Eric Anholt --- diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index b07161e5835..64f135e21dd 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -1186,6 +1186,8 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0; case GL_RGB9_E5: return ctx->Extensions.EXT_texture_shared_exponent ? GL_RGB : 0; + case GL_R11F_G11F_B10F: + return ctx->Extensions.EXT_packed_float ? GL_RGB : 0; /* XXX add integer formats eventually */ default: return 0; diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 6105ba1929c..60e8ae390a5 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -1082,6 +1082,15 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = 0, 0, 0, 0, 0, 1, 1, 4 }, + { + MESA_FORMAT_R11_G11_B10_FLOAT, + "MESA_FORMAT_R11_G11_B10_FLOAT", + GL_RGB, + GL_FLOAT, + 11, 11, 10, 0, + 0, 0, 0, 0, 0, + 1, 1, 4 + }, }; @@ -1817,6 +1826,11 @@ _mesa_format_to_type_and_comps(gl_format format, *comps = 3; return; + case MESA_FORMAT_R11_G11_B10_FLOAT: + *datatype = GL_UNSIGNED_INT_10F_11F_11F_REV; + *comps = 3; + return; + case MESA_FORMAT_COUNT: assert(0); return; diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index 68d6e98b174..df9ed70a3e0 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -207,6 +207,7 @@ typedef enum MESA_FORMAT_SIGNED_I16, /* IIII IIII IIII IIII */ MESA_FORMAT_RGB9_E5_FLOAT, + MESA_FORMAT_R11_G11_B10_FLOAT, MESA_FORMAT_COUNT } gl_format; diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 3e9f99698da..6d7bc735887 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -83,6 +83,7 @@ _mesa_type_is_packed(GLenum type) case GL_UNSIGNED_SHORT_8_8_REV_MESA: case GL_UNSIGNED_INT_24_8_EXT: case GL_UNSIGNED_INT_5_9_9_9_REV: + case GL_UNSIGNED_INT_10F_11F_11F_REV: return GL_TRUE; } @@ -225,6 +226,8 @@ _mesa_sizeof_packed_type( GLenum type ) return sizeof(GLuint); case GL_UNSIGNED_INT_5_9_9_9_REV: return sizeof(GLuint); + case GL_UNSIGNED_INT_10F_11F_11F_REV: + return sizeof(GLuint); default: return -1; } @@ -371,6 +374,11 @@ _mesa_bytes_per_pixel( GLenum format, GLenum type ) return sizeof(GLuint); else return -1; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (format == GL_RGB) + return sizeof(GLuint); + else + return -1; default: return -1; } @@ -468,6 +476,8 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx, return ctx->Extensions.ARB_half_float_pixel; case GL_UNSIGNED_INT_5_9_9_9_REV: return ctx->Extensions.EXT_texture_shared_exponent; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + return ctx->Extensions.EXT_packed_float; default: return GL_FALSE; } @@ -832,6 +842,7 @@ _mesa_is_color_format(GLenum format) case GL_INTENSITY8_SNORM: case GL_INTENSITY16_SNORM: case GL_RGB9_E5: + case GL_R11F_G11F_B10F: return GL_TRUE; case GL_YCBCR_MESA: /* not considered to be RGB */ /* fall-through */ diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index a6e3652c789..e9fcb545a1e 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -36,6 +36,7 @@ #include "image.h" #include "macros.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" @@ -686,6 +687,25 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, } } + else if (datatype == GL_UNSIGNED_INT_10F_11F_11F_REV && comps == 3) { + GLuint i, j, k; + const GLuint *rowA = (const GLuint*) srcRowA; + const GLuint *rowB = (const GLuint*) srcRowB; + GLuint *dst = (GLuint*)dstRow; + GLfloat res[3], rowAj[3], rowBj[3], rowAk[3], rowBk[3]; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + r11g11b10f_to_float3(rowA[j], rowAj); + r11g11b10f_to_float3(rowB[j], rowBj); + r11g11b10f_to_float3(rowA[k], rowAk); + r11g11b10f_to_float3(rowB[k], rowBk); + res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0]) * 0.25F; + res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1]) * 0.25F; + res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2]) * 0.25F; + dst[i] = float3_to_r11g11b10f(res); + } + } + else { _mesa_problem(NULL, "bad format in do_row()"); } @@ -1294,6 +1314,33 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, } } + else if (datatype == GL_UNSIGNED_INT_10F_11F_11F_REV && comps == 3) { + DECLARE_ROW_POINTERS0(GLuint); + + GLfloat res[3]; + GLfloat rowAj[3], rowBj[3], rowCj[3], rowDj[3]; + GLfloat rowAk[3], rowBk[3], rowCk[3], rowDk[3]; + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + r11g11b10f_to_float3(rowA[j], rowAj); + r11g11b10f_to_float3(rowB[j], rowBj); + r11g11b10f_to_float3(rowC[j], rowCj); + r11g11b10f_to_float3(rowD[j], rowDj); + r11g11b10f_to_float3(rowA[k], rowAk); + r11g11b10f_to_float3(rowB[k], rowBk); + r11g11b10f_to_float3(rowC[k], rowCk); + r11g11b10f_to_float3(rowD[k], rowDk); + res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0] + + rowCj[0] + rowCk[0] + rowDj[0] + rowDk[0]) * 0.125F; + res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1] + + rowCj[1] + rowCk[1] + rowDj[1] + rowDk[1]) * 0.125F; + res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2] + + rowCj[2] + rowCk[2] + rowDj[2] + rowDk[2]) * 0.125F; + dst[i] = float3_to_r11g11b10f(res); + } + } + else { _mesa_problem(NULL, "bad format in do_row()"); } diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c index 9c3d0854927..d0b8a4ff3a1 100644 --- a/src/mesa/main/pack.c +++ b/src/mesa/main/pack.c @@ -39,6 +39,7 @@ #include "pixeltransfer.h" #include "imports.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" /** @@ -1902,6 +1903,14 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], } } break; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + { + GLuint *dst = (GLuint *) dstAddr; + for (i = 0; i < n; i++) { + dst[i] = float3_to_r11g11b10f(rgba[i]); + } + } + break; default: _mesa_problem(ctx, "bad type in _mesa_pack_rgba_span_float"); return; @@ -2341,7 +2350,8 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV); + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); get_component_mapping(srcFormat, &rSrc, &gSrc, &bSrc, &aSrc, @@ -2839,6 +2849,34 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], } } break; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + GLfloat f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + SWAP4BYTE(p); + r11g11b10f_to_float3(p, f); + rgba[i][rDst] = f[0]; + rgba[i][gDst] = f[1]; + rgba[i][bDst] = f[2]; + rgba[i][aDst] = 1.0F; + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + GLfloat f[3]; + for (i = 0; i < n; i ++) { + r11g11b10f_to_float3(uisrc[i], f); + rgba[i][rDst] = f[0]; + rgba[i][gDst] = f[1]; + rgba[i][bDst] = f[2]; + rgba[i][aDst] = 1.0F; + } + } + break; default: _mesa_problem(NULL, "bad srcType in extract float data"); break; @@ -2942,7 +2980,8 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV); + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); get_component_mapping(srcFormat, &rSrc, &gSrc, &bSrc, &aSrc, @@ -3335,6 +3374,35 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], } } break; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + float f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + SWAP4BYTE(p); + r11g11b10f_to_float3(p, f); + rgba[i][rDst] = clamp_float_to_uint(f[0]); + rgba[i][gDst] = clamp_float_to_uint(f[1]); + rgba[i][bDst] = clamp_float_to_uint(f[2]); + rgba[i][aDst] = 1; + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + float f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + r11g11b10f_to_float3(p, f); + rgba[i][rDst] = clamp_float_to_uint(f[0]); + rgba[i][gDst] = clamp_float_to_uint(f[1]); + rgba[i][bDst] = clamp_float_to_uint(f[2]); + rgba[i][aDst] = 1; + } + } + break; default: _mesa_problem(NULL, "bad srcType in extract uint data"); break; @@ -3415,7 +3483,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV); + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); /* Try simple cases first */ if (transferOps == 0) { @@ -3738,7 +3807,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV); + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); /* general solution, no special cases, yet */ { @@ -3945,7 +4015,8 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx, srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV); + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); /* Extract image data as uint[4] pixels */ diff --git a/src/mesa/main/texfetch.c b/src/mesa/main/texfetch.c index d6d7b6b8f16..6716ce1b071 100644 --- a/src/mesa/main/texfetch.c +++ b/src/mesa/main/texfetch.c @@ -42,6 +42,7 @@ #include "texfetch.h" #include "teximage.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" /** @@ -906,6 +907,13 @@ texfetch_funcs[MESA_FORMAT_COUNT] = fetch_texel_3d_rgb9_e5, store_texel_rgb9_e5 }, + { + MESA_FORMAT_R11_G11_B10_FLOAT, + fetch_texel_1d_r11_g11_b10f, + fetch_texel_2d_r11_g11_b10f, + fetch_texel_3d_r11_g11_b10f, + store_texel_r11_g11_b10f + } }; diff --git a/src/mesa/main/texfetch_tmp.h b/src/mesa/main/texfetch_tmp.h index 106b812130b..e6fd81d4d57 100644 --- a/src/mesa/main/texfetch_tmp.h +++ b/src/mesa/main/texfetch_tmp.h @@ -2353,6 +2353,27 @@ static void store_texel_rgb9_e5(struct gl_texture_image *texImage, #endif +/* MESA_FORMAT_R11_G11_B10_FLOAT *********************************************/ + +static void FETCH(r11_g11_b10f)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); + r11g11b10f_to_float3(*src, texel); + texel[ACOMP] = 1.0F; +} + +#if DIM == 3 +static void store_texel_r11_g11_b10f(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *src = (const GLfloat *) texel; + GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); + *dst = float3_to_r11g11b10f(src); +} +#endif + + #undef TEXEL_ADDR #undef DIM #undef FETCH diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 15fa61f9f79..456687b0c5c 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -392,6 +392,16 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, } } + if (ctx->Extensions.EXT_packed_float) { + switch (internalFormat) { + case GL_R11F_G11F_B10F: + ASSERT(ctx->TextureFormatSupported[MESA_FORMAT_R11_G11_B10_FLOAT]); + return MESA_FORMAT_R11_G11_B10_FLOAT; + default: + ; /* fallthrough */ + } + } + if (ctx->Extensions.EXT_packed_depth_stencil) { switch (internalFormat) { case GL_DEPTH_STENCIL_EXT: diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 39f59e3cbd9..d694ab8e5ad 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -71,6 +71,7 @@ #include "texstore.h" #include "enums.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" enum { @@ -4232,6 +4233,61 @@ _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) return GL_TRUE; } +static GLboolean +_mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) +{ + const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + + ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT); + ASSERT(baseInternalFormat == GL_RGB); + + if (!ctx->_ImageTransferState && + !srcPacking->SwapBytes && + srcFormat == GL_RGB && + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV) { + /* simple memcpy path */ + memcpy_texture(ctx, dims, + dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, + dstRowStride, + dstImageOffsets, + srcWidth, srcHeight, srcDepth, srcFormat, srcType, + srcAddr, srcPacking); + } + else { + /* general path */ + const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, + baseInternalFormat, + baseFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking, + ctx->_ImageTransferState); + const GLfloat *srcRow = tempImage; + GLint bytesPerRow; + GLint img, row, col; + if (!tempImage) + return GL_FALSE; + bytesPerRow = srcWidth * 3 * sizeof(GLfloat); + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = (GLubyte *) dstAddr + + dstImageOffsets[dstZoffset + img] * 4 + + dstYoffset * dstRowStride + + dstXoffset * 4; + for (row = 0; row < srcHeight; row++) { + GLuint *dstUI = (GLuint*)dstRow; + for (col = 0; col < srcWidth; col++) { + dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]); + } + dstRow += dstRowStride; + srcRow += srcWidth * 3; + } + } + + free((void *) tempImage); + } + return GL_TRUE; +} + /** @@ -4366,6 +4422,7 @@ texstore_funcs[MESA_FORMAT_COUNT] = { MESA_FORMAT_SIGNED_I16, _mesa_texstore_snorm16 }, { MESA_FORMAT_RGB9_E5_FLOAT, _mesa_texstore_rgb9_e5 }, + { MESA_FORMAT_R11_G11_B10_FLOAT, _mesa_texstore_r11_g11_b10f }, };