Mesa (master): ARB_texture_rg: Add R8, R16, RG88, and RG1616 internal formats

Ian Romanick idr at kemper.freedesktop.org
Fri Oct 1 22:56:19 UTC 2010


Module: Mesa
Branch: master
Commit: 5d1387b2da3626326410804026f8b92f1a121fdc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5d1387b2da3626326410804026f8b92f1a121fdc

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Tue Sep 28 17:24:39 2010 -0700

ARB_texture_rg: Add R8, R16, RG88, and RG1616 internal formats

---

 src/mesa/main/formats.c      |   80 +++++++++++++++++++++
 src/mesa/main/formats.h      |    6 ++
 src/mesa/main/image.c        |   88 +++++++++++++++++++++++
 src/mesa/main/readpix.c      |    1 +
 src/mesa/main/texfetch.c     |   42 +++++++++++
 src/mesa/main/texfetch_tmp.h |  144 +++++++++++++++++++++++++++++++++++++
 src/mesa/main/texformat.c    |   23 ++++++
 src/mesa/main/texstore.c     |  161 ++++++++++++++++++++++++++++++++++--------
 8 files changed, 515 insertions(+), 30 deletions(-)

diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index 9db9f1c..a82aa9c 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -321,6 +321,60 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
       1, 1, 2                      /* BlockWidth/Height,Bytes */
    },
    {
+      MESA_FORMAT_R8,
+      "MESA_FORMAT_R8",
+      GL_RED,
+      GL_UNSIGNED_NORMALIZED,
+      8, 0, 0, 0,
+      0, 0, 0, 0, 0,
+      1, 1, 1
+   },
+   {
+      MESA_FORMAT_RG88,
+      "MESA_FORMAT_RG88",
+      GL_RG,
+      GL_UNSIGNED_NORMALIZED,
+      8, 8, 0, 0,
+      0, 0, 0, 0, 0,
+      1, 1, 2
+   },
+   {
+      MESA_FORMAT_RG88_REV,
+      "MESA_FORMAT_RG88_REV",
+      GL_RG,
+      GL_UNSIGNED_NORMALIZED,
+      8, 8, 0, 0,
+      0, 0, 0, 0, 0,
+      1, 1, 2
+   },
+   {
+      MESA_FORMAT_R16,
+      "MESA_FORMAT_R16",
+      GL_RED,
+      GL_UNSIGNED_NORMALIZED,
+      16, 0, 0, 0,
+      0, 0, 0, 0, 0,
+      1, 1, 2
+   },
+   {
+      MESA_FORMAT_RG1616,
+      "MESA_FORMAT_RG1616",
+      GL_RG,
+      GL_UNSIGNED_NORMALIZED,
+      16, 16, 0, 0,
+      0, 0, 0, 0, 0,
+      1, 1, 4
+   },
+   {
+      MESA_FORMAT_RG1616_REV,
+      "MESA_FORMAT_RG1616_REV",
+      GL_RG,
+      GL_UNSIGNED_NORMALIZED,
+      16, 16, 0, 0,
+      0, 0, 0, 0, 0,
+      1, 1, 4
+   },
+   {
       MESA_FORMAT_Z24_S8,          /* Name */
       "MESA_FORMAT_Z24_S8",        /* StrName */
       GL_DEPTH_STENCIL,            /* BaseFormat */
@@ -1073,6 +1127,22 @@ _mesa_test_formats(void)
          assert(info->LuminanceBits == 0);
          assert(info->IntensityBits == 0);
       }
+      else if (info->BaseFormat == GL_RG) {
+         assert(info->RedBits > 0);
+         assert(info->GreenBits > 0);
+         assert(info->BlueBits == 0);
+         assert(info->AlphaBits == 0);
+         assert(info->LuminanceBits == 0);
+         assert(info->IntensityBits == 0);
+      }
+      else if (info->BaseFormat == GL_RED) {
+         assert(info->RedBits > 0);
+         assert(info->GreenBits == 0);
+         assert(info->BlueBits == 0);
+         assert(info->AlphaBits == 0);
+         assert(info->LuminanceBits == 0);
+         assert(info->IntensityBits == 0);
+      }
       else if (info->BaseFormat == GL_LUMINANCE) {
          assert(info->RedBits == 0);
          assert(info->GreenBits == 0);
@@ -1137,16 +1207,25 @@ _mesa_format_to_type_and_comps(gl_format format,
 
    case MESA_FORMAT_AL88:
    case MESA_FORMAT_AL88_REV:
+   case MESA_FORMAT_RG88:
+   case MESA_FORMAT_RG88_REV:
       *datatype = GL_UNSIGNED_BYTE;
       *comps = 2;
       return;
 
    case MESA_FORMAT_AL1616:
    case MESA_FORMAT_AL1616_REV:
+   case MESA_FORMAT_RG1616:
+   case MESA_FORMAT_RG1616_REV:
       *datatype = GL_UNSIGNED_SHORT;
       *comps = 2;
       return;
 
+   case MESA_FORMAT_R16:
+      *datatype = GL_UNSIGNED_SHORT;
+      *comps = 1;
+      return;
+
    case MESA_FORMAT_RGB332:
       *datatype = GL_UNSIGNED_BYTE_3_3_2;
       *comps = 3;
@@ -1156,6 +1235,7 @@ _mesa_format_to_type_and_comps(gl_format format,
    case MESA_FORMAT_L8:
    case MESA_FORMAT_I8:
    case MESA_FORMAT_CI8:
+   case MESA_FORMAT_R8:
       *datatype = GL_UNSIGNED_BYTE;
       *comps = 1;
       return;
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index e9467f4..7674d8e 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -76,6 +76,12 @@ typedef enum
    MESA_FORMAT_CI8,		/*                               CCCC CCCC */
    MESA_FORMAT_YCBCR,		/*                     YYYY YYYY UorV UorV */
    MESA_FORMAT_YCBCR_REV,	/*                     UorV UorV YYYY YYYY */
+   MESA_FORMAT_R8,		/*                               RRRR RRRR */
+   MESA_FORMAT_RG88,		/*                     RRRR RRRR GGGG GGGG */
+   MESA_FORMAT_RG88_REV,	/*                     GGGG GGGG RRRR RRRR */
+   MESA_FORMAT_R16,		/*                     RRRR RRRR RRRR RRRR */
+   MESA_FORMAT_RG1616,		/* RRRR RRRR RRRR RRRR GGGG GGGG GGGG GGGG */
+   MESA_FORMAT_RG1616_REV,	/* GGGG GGGG GGGG GGGG RRRR RRRR RRRR RRRR */
    MESA_FORMAT_Z24_S8,          /* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ SSSS SSSS */
    MESA_FORMAT_S8_Z24,          /* SSSS SSSS ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */
    MESA_FORMAT_Z16,             /*                     ZZZZ ZZZZ ZZZZ ZZZZ */
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 029d2fe..1992c74 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -286,6 +286,7 @@ _mesa_components_in_format( GLenum format )
          return 1;
       case GL_LUMINANCE_ALPHA:
       case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+      case GL_RG:
 	 return 2;
       case GL_RGB:
       case GL_RGB_INTEGER_EXT:
@@ -442,6 +443,24 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
             default:
                return GL_FALSE;
          }
+      case GL_RG:
+	 if (!ctx->Extensions.ARB_texture_rg)
+	    return GL_FALSE;
+
+         switch (type) {
+            case GL_BYTE:
+            case GL_UNSIGNED_BYTE:
+            case GL_SHORT:
+            case GL_UNSIGNED_SHORT:
+            case GL_INT:
+            case GL_UNSIGNED_INT:
+            case GL_FLOAT:
+               return GL_TRUE;
+            case GL_HALF_FLOAT_ARB:
+               return ctx->Extensions.ARB_half_float_pixel;
+            default:
+               return GL_FALSE;
+         }
       case GL_RGB:
          switch (type) {
             case GL_BYTE:
@@ -596,6 +615,11 @@ _mesa_is_color_format(GLenum format)
       case GL_INTENSITY8:
       case GL_INTENSITY12:
       case GL_INTENSITY16:
+      case GL_R8:
+      case GL_R16:
+      case GL_RG:
+      case GL_RG8:
+      case GL_RG16:
       case 3:
       case GL_RGB:
       case GL_BGR:
@@ -626,6 +650,10 @@ _mesa_is_color_format(GLenum format)
       case GL_LUMINANCE_ALPHA32F_ARB:
       case GL_INTENSITY16F_ARB:
       case GL_INTENSITY32F_ARB:
+      case GL_R16F:
+      case GL_R32F:
+      case GL_RG16F:
+      case GL_RG32F:
       case GL_RGB16F_ARB:
       case GL_RGB32F_ARB:
       case GL_RGBA16F_ARB:
@@ -1585,6 +1613,25 @@ _mesa_lookup_rgba_float(const struct gl_color_table *table,
             rgba[i][ACOMP] = alpha;;
          }
          break;
+      case GL_RED:
+         /* replace RGB with RGB */
+         for (i = 0; i < n; i++) {
+            GLint jR = IROUND(rgba[i][RCOMP] * scale);
+            jR = CLAMP(jR, 0, max);
+            rgba[i][RCOMP] = lut[jR * 3 + 0];
+         }
+         break;
+      case GL_RG:
+         /* replace RG with RG */
+         for (i = 0; i < n; i++) {
+            GLint jR = IROUND(rgba[i][RCOMP] * scale);
+            GLint jG = IROUND(rgba[i][GCOMP] * scale);
+            jR = CLAMP(jR, 0, max);
+            jG = CLAMP(jG, 0, max);
+            rgba[i][RCOMP] = lut[jR * 3 + 0];
+            rgba[i][GCOMP] = lut[jG * 3 + 1];
+         }
+         break;
       case GL_RGB:
          /* replace RGB with RGB */
          for (i = 0; i < n; i++) {
@@ -3201,6 +3248,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
           srcFormat == GL_LUMINANCE ||
           srcFormat == GL_LUMINANCE_ALPHA ||
           srcFormat == GL_INTENSITY ||
+          srcFormat == GL_RG ||
           srcFormat == GL_RGB ||
           srcFormat == GL_BGR ||
           srcFormat == GL_RGBA ||
@@ -3283,6 +3331,18 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          redIndex = greenIndex = blueIndex = alphaIndex = 0;
          stride = 1;
          break;
+      case GL_RG:
+      case GL_RG_INTEGER:
+         redIndex = 0;
+         greenIndex = 1;
+         blueIndex = -1;
+         alphaIndex = -1;
+         rComp = 0;
+         gComp = 1;
+         bComp = 2;
+         aComp = 3;
+         stride = 2;
+         break;
       case GL_RGB:
       case GL_RGB_INTEGER:
          redIndex = 0;
@@ -3852,6 +3912,8 @@ _mesa_unpack_color_span_chan( GLcontext *ctx,
           dstFormat == GL_LUMINANCE ||
           dstFormat == GL_LUMINANCE_ALPHA ||
           dstFormat == GL_INTENSITY ||
+          dstFormat == GL_RED ||
+          dstFormat == GL_RG ||
           dstFormat == GL_RGB ||
           dstFormat == GL_RGBA ||
           dstFormat == GL_COLOR_INDEX);
@@ -3863,6 +3925,7 @@ _mesa_unpack_color_span_chan( GLcontext *ctx,
           srcFormat == GL_LUMINANCE ||
           srcFormat == GL_LUMINANCE_ALPHA ||
           srcFormat == GL_INTENSITY ||
+          srcFormat == GL_RG ||
           srcFormat == GL_RGB ||
           srcFormat == GL_BGR ||
           srcFormat == GL_RGBA ||
@@ -4090,6 +4153,17 @@ _mesa_unpack_color_span_chan( GLcontext *ctx,
             dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
             dstLuminanceIndex = -1;
             break;
+         case GL_RED:
+            dstRedIndex = 0;
+            dstGreenIndex = dstBlueIndex = -1;
+            dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
+            break;
+         case GL_RG:
+            dstRedIndex = 0;
+            dstGreenIndex = 1;
+            dstBlueIndex = -1;
+            dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
+            break;
          case GL_RGB:
             dstRedIndex = 0;
             dstGreenIndex = 1;
@@ -4188,6 +4262,8 @@ _mesa_unpack_color_span_float( GLcontext *ctx,
           dstFormat == GL_LUMINANCE ||
           dstFormat == GL_LUMINANCE_ALPHA ||
           dstFormat == GL_INTENSITY ||
+          dstFormat == GL_RED ||
+          dstFormat == GL_RG ||
           dstFormat == GL_RGB ||
           dstFormat == GL_RGBA ||
           dstFormat == GL_COLOR_INDEX);
@@ -4199,6 +4275,7 @@ _mesa_unpack_color_span_float( GLcontext *ctx,
           srcFormat == GL_LUMINANCE ||
           srcFormat == GL_LUMINANCE_ALPHA ||
           srcFormat == GL_INTENSITY ||
+          srcFormat == GL_RG ||
           srcFormat == GL_RGB ||
           srcFormat == GL_BGR ||
           srcFormat == GL_RGBA ||
@@ -4315,6 +4392,17 @@ _mesa_unpack_color_span_float( GLcontext *ctx,
             dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
             dstLuminanceIndex = -1;
             break;
+         case GL_RED:
+            dstRedIndex = 0;
+            dstGreenIndex = dstBlueIndex = -1;
+            dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
+            break;
+         case GL_RG:
+            dstRedIndex = 0;
+            dstGreenIndex = 1;
+            dstBlueIndex = -1;
+            dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
+            break;
          case GL_RGB:
             dstRedIndex = 0;
             dstGreenIndex = 1;
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 93f2bd3..bb3fb9e 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -66,6 +66,7 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
 
    /* additional checks */
    switch (format) {
+   case GL_RG:
    case GL_RED:
    case GL_GREEN:
    case GL_BLUE:
diff --git a/src/mesa/main/texfetch.c b/src/mesa/main/texfetch.c
index c03bc71..aa3a696 100644
--- a/src/mesa/main/texfetch.c
+++ b/src/mesa/main/texfetch.c
@@ -314,6 +314,48 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
       store_texel_ycbcr_rev
    },
    {
+      MESA_FORMAT_R8,
+      fetch_texel_1d_f_r8,
+      fetch_texel_2d_f_r8,
+      fetch_texel_3d_f_r8,
+      store_texel_r8,
+   },
+   {
+      MESA_FORMAT_RG88,
+      fetch_texel_1d_f_rg88,
+      fetch_texel_2d_f_rg88,
+      fetch_texel_3d_f_rg88,
+      store_texel_rg88,
+   },
+   {
+      MESA_FORMAT_RG88_REV,
+      fetch_texel_1d_f_rg88_rev,
+      fetch_texel_2d_f_rg88_rev,
+      fetch_texel_3d_f_rg88_rev,
+      store_texel_rg88_rev,
+   },
+   {
+      MESA_FORMAT_R16,
+      fetch_texel_1d_f_r16,
+      fetch_texel_2d_f_r16,
+      fetch_texel_3d_f_r16,
+      store_texel_r16,
+   },
+   {
+      MESA_FORMAT_RG1616,
+      fetch_texel_1d_f_rg1616,
+      fetch_texel_2d_f_rg1616,
+      fetch_texel_3d_f_rg1616,
+      store_texel_rg1616,
+   },
+   {
+      MESA_FORMAT_RG1616_REV,
+      fetch_texel_1d_f_rg1616_rev,
+      fetch_texel_2d_f_rg1616_rev,
+      fetch_texel_3d_f_rg1616_rev,
+      store_texel_rg1616_rev,
+   },
+   {
       MESA_FORMAT_Z24_S8,
       fetch_texel_1d_f_z24_s8,
       fetch_texel_2d_f_z24_s8,
diff --git a/src/mesa/main/texfetch_tmp.h b/src/mesa/main/texfetch_tmp.h
index f943554..2f583ed 100644
--- a/src/mesa/main/texfetch_tmp.h
+++ b/src/mesa/main/texfetch_tmp.h
@@ -810,6 +810,54 @@ static void store_texel_argb1555_rev(struct gl_texture_image *texImage,
 #endif
 
 
+/* MESA_FORMAT_RG88 **********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rg88 texture, return 4 GLchans */
+static void FETCH(f_rg88)( const struct gl_texture_image *texImage,
+                           GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+   texel[RCOMP] = UBYTE_TO_FLOAT( s & 0xff );
+   texel[GCOMP] = UBYTE_TO_FLOAT( s >> 8 );
+   texel[BCOMP] = 0.0;
+   texel[ACOMP] = 1.0;
+}
+
+#if DIM == 3
+static void store_texel_rg88(struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLubyte *rgba = (const GLubyte *) texel;
+   GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+   *dst = PACK_COLOR_88(rgba[RCOMP], rgba[GCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_RG88_REV ******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rg88_rev texture, return 4 GLchans */
+static void FETCH(f_rg88_rev)( const struct gl_texture_image *texImage,
+                           GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+   texel[RCOMP] = UBYTE_TO_FLOAT( s & 0xff );
+   texel[GCOMP] = UBYTE_TO_FLOAT( s >> 8 );
+   texel[BCOMP] = 0.0;
+   texel[ACOMP] = 1.0;
+}
+
+#if DIM == 3
+static void store_texel_rg88_rev(struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLubyte *rgba = (const GLubyte *) texel;
+   GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+   *dst = PACK_COLOR_88(rgba[GCOMP], rgba[RCOMP]);
+}
+#endif
+
+
 /* MESA_FORMAT_AL88 **********************************************************/
 
 /* Fetch texel from 1D, 2D or 3D al88 texture, return 4 GLchans */
@@ -834,6 +882,54 @@ static void store_texel_al88(struct gl_texture_image *texImage,
 #endif
 
 
+/* MESA_FORMAT_R8 ************************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rg88 texture, return 4 GLchans */
+static void FETCH(f_r8)(const struct gl_texture_image *texImage,
+			GLint i, GLint j, GLint k, GLfloat *texel)
+{
+   const GLubyte s = *TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+   texel[RCOMP] = UBYTE_TO_FLOAT(s);
+   texel[GCOMP] = 0.0;
+   texel[BCOMP] = 0.0;
+   texel[ACOMP] = 1.0;
+}
+
+#if DIM == 3
+static void store_texel_r8(struct gl_texture_image *texImage,
+			   GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLubyte *rgba = (const GLubyte *) texel;
+   GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+   *dst = rgba[RCOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_R16 ***********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D r16 texture, return 4 GLchans */
+static void FETCH(f_r16)(const struct gl_texture_image *texImage,
+			GLint i, GLint j, GLint k, GLfloat *texel)
+{
+   const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+   texel[RCOMP] = USHORT_TO_FLOAT(s);
+   texel[GCOMP] = 0.0;
+   texel[BCOMP] = 0.0;
+   texel[ACOMP] = 1.0;
+}
+
+#if DIM == 3
+static void store_texel_r16(struct gl_texture_image *texImage,
+			    GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLushort *rgba = (const GLushort *) texel;
+   GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+   *dst = rgba[RCOMP];
+}
+#endif
+
+
 /* MESA_FORMAT_AL88_REV ******************************************************/
 
 /* Fetch texel from 1D, 2D or 3D al88_rev texture, return 4 GLchans */
@@ -858,6 +954,54 @@ static void store_texel_al88_rev(struct gl_texture_image *texImage,
 #endif
 
 
+/* MESA_FORMAT_RG1616 ********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rg1616 texture, return 4 GLchans */
+static void FETCH(f_rg1616)( const struct gl_texture_image *texImage,
+                           GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+   texel[RCOMP] = USHORT_TO_FLOAT( s & 0xffff );
+   texel[GCOMP] = USHORT_TO_FLOAT( s >> 16 );
+   texel[BCOMP] = 0.0;
+   texel[ACOMP] = 1.0;
+}
+
+#if DIM == 3
+static void store_texel_rg1616(struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLubyte *rgba = (const GLubyte *) texel;
+   GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+   *dst = PACK_COLOR_1616(rgba[RCOMP], rgba[GCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_RG1616_REV ****************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rg1616_rev texture, return 4 GLchans */
+static void FETCH(f_rg1616_rev)( const struct gl_texture_image *texImage,
+                           GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+   texel[RCOMP] = USHORT_TO_FLOAT( s >> 16 );
+   texel[GCOMP] = USHORT_TO_FLOAT( s & 0xffff );
+   texel[BCOMP] = 0.0;
+   texel[ACOMP] = 1.0;
+}
+
+#if DIM == 3
+static void store_texel_rg1616_rev(struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLubyte *rgba = (const GLubyte *) texel;
+   GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+   *dst = PACK_COLOR_1616(rgba[GCOMP], rgba[RCOMP]);
+}
+#endif
+
+
 /* MESA_FORMAT_AL1616 ********************************************************/
 
 /* Fetch texel from 1D, 2D or 3D al1616 texture, return 4 GLchans */
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index b9271ef..24efb10 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -429,6 +429,29 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
       }
    }
 
+   if (ctx->Extensions.ARB_texture_rg) {
+      switch (internalFormat) {
+      case GL_R8:
+      case GL_RED:
+      case GL_COMPRESSED_RED:
+	 return MESA_FORMAT_R8;
+
+      case GL_R16:
+         return MESA_FORMAT_R16;
+
+      case GL_RG:
+      case GL_RG8:
+      case GL_COMPRESSED_RG:
+	 return MESA_FORMAT_RG88;
+
+      case GL_RG16:
+	 return MESA_FORMAT_RG1616;
+
+      default:
+         ; /* fallthrough */
+      }
+   }
+
    _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
    return MESA_FORMAT_NONE;
 }
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index a1574e6..5ca36d9 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -99,6 +99,7 @@ can_swizzle(GLenum logicalBaseFormat)
    case GL_BGR:
    case GL_BGRA:
    case GL_ABGR_EXT:
+   case GL_RG:
       return GL_TRUE;
    default:
       return GL_FALSE;
@@ -120,6 +121,7 @@ enum {
    IDX_BGR,
    IDX_BGRA,
    IDX_ABGR,
+   IDX_RG,
    MAX_IDX
 };
 
@@ -207,6 +209,12 @@ static const struct {
       MAP4(3,2,1,0),
       MAP4(3,2,1,0)
    },
+
+   {
+      IDX_RG,
+      MAP4(0, 1, ZERO, ONE),
+      MAP2(0, 1)
+   },
 };
 
 
@@ -230,6 +238,7 @@ get_map_idx(GLenum value)
    case GL_BGR: return IDX_BGR;
    case GL_BGRA: return IDX_BGRA;
    case GL_ABGR_EXT: return IDX_ABGR;
+   case GL_RG: return IDX_RG;
    default:
       _mesa_problem(NULL, "Unexpected inFormat");
       return 0;
@@ -319,6 +328,8 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
 
    ASSERT(logicalBaseFormat == GL_RGBA ||
           logicalBaseFormat == GL_RGB ||
+          logicalBaseFormat == GL_RG ||
+          logicalBaseFormat == GL_RED ||
           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
           logicalBaseFormat == GL_LUMINANCE ||
           logicalBaseFormat == GL_ALPHA ||
@@ -328,6 +339,8 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
 
    ASSERT(textureBaseFormat == GL_RGBA ||
           textureBaseFormat == GL_RGB ||
+          textureBaseFormat == GL_RG ||
+          textureBaseFormat == GL_RED ||
           textureBaseFormat == GL_LUMINANCE_ALPHA ||
           textureBaseFormat == GL_LUMINANCE ||
           textureBaseFormat == GL_ALPHA ||
@@ -445,6 +458,8 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
 
    ASSERT(logicalBaseFormat == GL_RGBA ||
           logicalBaseFormat == GL_RGB ||
+          logicalBaseFormat == GL_RG ||
+          logicalBaseFormat == GL_RED ||
           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
           logicalBaseFormat == GL_LUMINANCE ||
           logicalBaseFormat == GL_ALPHA ||
@@ -452,6 +467,8 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
 
    ASSERT(textureBaseFormat == GL_RGBA ||
           textureBaseFormat == GL_RGB ||
+          textureBaseFormat == GL_RG ||
+          textureBaseFormat == GL_RED ||
           textureBaseFormat == GL_LUMINANCE_ALPHA ||
           textureBaseFormat == GL_LUMINANCE ||
           textureBaseFormat == GL_ALPHA ||
@@ -1907,21 +1924,22 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS)
 
 
 static GLboolean
-_mesa_texstore_al88(TEXSTORE_PARAMS)
+_mesa_texstore_unorm88(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
    ASSERT(dstFormat == MESA_FORMAT_AL88 ||
-          dstFormat == MESA_FORMAT_AL88_REV);
+          dstFormat == MESA_FORMAT_AL88_REV ||
+          dstFormat == MESA_FORMAT_RG88 ||
+          dstFormat == MESA_FORMAT_RG88_REV);
    ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == MESA_FORMAT_AL88 &&
-       baseInternalFormat == GL_LUMINANCE_ALPHA &&
-       srcFormat == GL_LUMINANCE_ALPHA &&
+       (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_RG88) &&
+       baseInternalFormat == srcFormat &&
        srcType == GL_UNSIGNED_BYTE &&
        littleEndian) {
       /* simple memcpy path */
@@ -1942,14 +1960,27 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
 
       /* dstmap - how to swizzle from RGBA to dst format:
        */
-      if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
-	  (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
-	 dstmap[0] = 0;
-	 dstmap[1] = 3;
+      if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
+	 if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
+	     (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
+	    dstmap[0] = 0;
+	    dstmap[1] = 3;
+	 }
+	 else {
+	    dstmap[0] = 3;
+	    dstmap[1] = 0;
+	 }
       }
       else {
-	 dstmap[0] = 3;
-	 dstmap[1] = 0;
+	 if ((littleEndian && dstFormat == MESA_FORMAT_RG88) ||
+	     (!littleEndian && dstFormat == MESA_FORMAT_RG88_REV)) {
+	    dstmap[0] = 0;
+	    dstmap[1] = 1;
+	 }
+	 else {
+	    dstmap[0] = 1;
+	    dstmap[1] = 0;
+	 }
       }
       dstmap[2] = ZERO;		/* ? */
       dstmap[3] = ONE;		/* ? */
@@ -1983,7 +2014,8 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
-            if (dstFormat == MESA_FORMAT_AL88) {
+            if (dstFormat == MESA_FORMAT_AL88 ||
+		dstFormat == MESA_FORMAT_RG88) {
                for (col = 0; col < srcWidth; col++) {
                   /* src[0] is luminance, src[1] is alpha */
                  dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
@@ -2009,21 +2041,22 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
 
 
 static GLboolean
-_mesa_texstore_al1616(TEXSTORE_PARAMS)
+_mesa_texstore_unorm1616(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
    ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
-          dstFormat == MESA_FORMAT_AL1616_REV);
+          dstFormat == MESA_FORMAT_AL1616_REV ||
+	  dstFormat == MESA_FORMAT_RG1616 ||
+          dstFormat == MESA_FORMAT_RG1616_REV);
    ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == MESA_FORMAT_AL1616 &&
-       baseInternalFormat == GL_LUMINANCE_ALPHA &&
-       srcFormat == GL_LUMINANCE_ALPHA &&
+       (dstFormat == MESA_FORMAT_AL1616 || dstFormat == MESA_FORMAT_RG1616) &&
+       baseInternalFormat == srcFormat &&
        srcType == GL_UNSIGNED_SHORT &&
        littleEndian) {
       /* simple memcpy path */
@@ -2053,7 +2086,8 @@ _mesa_texstore_al1616(TEXSTORE_PARAMS)
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
-            if (dstFormat == MESA_FORMAT_AL1616) {
+            if (dstFormat == MESA_FORMAT_AL1616 ||
+		dstFormat == MESA_FORMAT_RG1616) {
                for (col = 0; col < srcWidth; col++) {
 		  GLushort l, a;
 
@@ -2083,6 +2117,66 @@ _mesa_texstore_al1616(TEXSTORE_PARAMS)
 
 
 static GLboolean
+_mesa_texstore_r16(TEXSTORE_PARAMS)
+{
+   const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_R16);
+   ASSERT(texelBytes == 2);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == MESA_FORMAT_R16 &&
+       baseInternalFormat == GL_RED &&
+       srcFormat == GL_RED &&
+       srcType == GL_UNSIGNED_SHORT &&
+       littleEndian) {
+      /* 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 = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *src = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLushort *dstUS = (GLushort *) dstRow;
+	    for (col = 0; col < srcWidth; col++) {
+	       GLushort r;
+
+	       UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
+	       dstUS[col] = r;
+	       src += 1;
+	    }
+            dstRow += dstRowStride;
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+static GLboolean
 _mesa_texstore_rgba_16(TEXSTORE_PARAMS)
 {
    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
@@ -2278,7 +2372,8 @@ _mesa_texstore_a8(TEXSTORE_PARAMS)
 
    ASSERT(dstFormat == MESA_FORMAT_A8 ||
           dstFormat == MESA_FORMAT_L8 ||
-          dstFormat == MESA_FORMAT_I8);
+          dstFormat == MESA_FORMAT_I8 ||
+          dstFormat == MESA_FORMAT_R8);
    ASSERT(texelBytes == 1);
 
    if (!ctx->_ImageTransferState &&
@@ -3604,13 +3699,13 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
    /* reuse normal luminance/alpha texstore code */
    newDstFormat = MESA_FORMAT_AL88;
 
-   k = _mesa_texstore_al88(ctx, dims, baseInternalFormat,
-                           newDstFormat, dstAddr,
-                           dstXoffset, dstYoffset, dstZoffset,
-                           dstRowStride, dstImageOffsets,
-                           srcWidth, srcHeight, srcDepth,
-                           srcFormat, srcType,
-                           srcAddr, srcPacking);
+   k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
+			      newDstFormat, dstAddr,
+			      dstXoffset, dstYoffset, dstZoffset,
+			      dstRowStride, dstImageOffsets,
+			      srcWidth, srcHeight, srcDepth,
+			      srcFormat, srcType,
+			      srcAddr, srcPacking);
    return k;
 }
 
@@ -3654,10 +3749,10 @@ texstore_funcs[MESA_FORMAT_COUNT] =
    { MESA_FORMAT_RGBA5551, _mesa_texstore_rgba5551 },
    { MESA_FORMAT_ARGB1555, _mesa_texstore_argb1555 },
    { MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 },
-   { MESA_FORMAT_AL88, _mesa_texstore_al88 },
-   { MESA_FORMAT_AL88_REV, _mesa_texstore_al88 },
-   { MESA_FORMAT_AL1616, _mesa_texstore_al1616 },
-   { MESA_FORMAT_AL1616_REV, _mesa_texstore_al1616 },
+   { MESA_FORMAT_AL88, _mesa_texstore_unorm88 },
+   { MESA_FORMAT_AL88_REV, _mesa_texstore_unorm88 },
+   { MESA_FORMAT_AL1616, _mesa_texstore_unorm1616 },
+   { MESA_FORMAT_AL1616_REV, _mesa_texstore_unorm1616 },
    { MESA_FORMAT_RGB332, _mesa_texstore_rgb332 },
    { MESA_FORMAT_A8, _mesa_texstore_a8 },
    { MESA_FORMAT_L8, _mesa_texstore_a8 },
@@ -3665,6 +3760,12 @@ texstore_funcs[MESA_FORMAT_COUNT] =
    { MESA_FORMAT_CI8, _mesa_texstore_ci8 },
    { MESA_FORMAT_YCBCR, _mesa_texstore_ycbcr },
    { MESA_FORMAT_YCBCR_REV, _mesa_texstore_ycbcr },
+   { MESA_FORMAT_R8, _mesa_texstore_a8 },
+   { MESA_FORMAT_RG88, _mesa_texstore_unorm88 },
+   { MESA_FORMAT_RG88_REV, _mesa_texstore_unorm88 },
+   { MESA_FORMAT_R16, _mesa_texstore_r16 },
+   { MESA_FORMAT_RG1616, _mesa_texstore_unorm1616 },
+   { MESA_FORMAT_RG1616_REV, _mesa_texstore_unorm1616 },
    { MESA_FORMAT_Z24_S8, _mesa_texstore_z24_s8 },
    { MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 },
    { MESA_FORMAT_Z16, _mesa_texstore_z16 },




More information about the mesa-commit mailing list