mesa: implement EXT_packed_float
authorMarek Olšák <maraeo@gmail.com>
Tue, 26 Apr 2011 00:27:25 +0000 (02:27 +0200)
committerMarek Olšák <maraeo@gmail.com>
Fri, 29 Apr 2011 09:31:55 +0000 (11:31 +0200)
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/main/fbobject.c
src/mesa/main/formats.c
src/mesa/main/formats.h
src/mesa/main/image.c
src/mesa/main/mipmap.c
src/mesa/main/pack.c
src/mesa/main/texfetch.c
src/mesa/main/texfetch_tmp.h
src/mesa/main/texformat.c
src/mesa/main/texstore.c

index b07161e5835981e6c44e5e2663b3e0c432f1c737..64f135e21dd498cf9d7bfe51abe326dccef149eb 100644 (file)
@@ -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;
index 6105ba1929ce262d62a0ba3d6c6138fb750b6d07..60e8ae390a5052d0fd076da9e4e9ad0e32556f6b 100644 (file)
@@ -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;
index 68d6e98b174cff4afb796875386d83e2330c6dcf..df9ed70a3e0fd47b8f866145a970ee4cf9e4c402 100644 (file)
@@ -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;
index 3e9f99698dabc79b9fc4491c02bf4955783b313f..6d7bc73588775139f42cb529b1e39fdea1535fb2 100644 (file)
@@ -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 */
index a6e3652c789dca3c3d02fc954b390afe664af607..e9fcb545a1e9dbb2a9ede08ff16c00414c054e7e 100644 (file)
@@ -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()");
    }
index 9c3d08549270c94782e74896b916e6bb7b94e16f..d0b8a4ff3a15a888b0c2bb2fdc302166e45774d4 100644 (file)
@@ -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 */
index d6d7b6b8f16f875c610c804c749868650de2edd9..6716ce1b071d5f54dc4e07183a1387b08b8796bc 100644 (file)
@@ -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
+   }
 };
 
 
index 106b812130bf876f08f7dbd6c6069b5f9f3766dd..e6fd81d4d5773cf9289092617b216359591ffcfb 100644 (file)
@@ -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
index 15fa61f9f79a515c484c0988d7731a23021f6cc6..456687b0c5c073d78348830d62a152e7e39a0982 100644 (file)
@@ -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:
index 39f59e3cbd920aff3fcbaaf0daffec4ce2b473c4..d694ab8e5ad54454f9b5cc16469784a66709319f 100644 (file)
@@ -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 },
 };