Add MESA_FORMAT_XRGB8888_REV.
[mesa.git] / src / mesa / main / texstore.c
index dd146254b4a84bf188d8848e1142110e13a3a005..abb4ed26631c82a263a0de3e391888bac5fd4f62 100644 (file)
@@ -277,16 +277,6 @@ compute_component_mapping(GLenum inFormat, GLenum outFormat,
 }
 
 
-#if !FEATURE_convolve
-static void
-_mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims,
-                                   GLsizei *srcWidth, GLsizei *srcHeight)
-{
-   /* no-op */
-}
-#endif
-
-
 /**
  * Make a temporary (color) texture image with GLfloat components.
  * Apply all needed pixel unpacking and pixel transfer operations.
@@ -353,7 +343,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
       const GLuint postConvTransferOps
          = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
       GLint img, row;
-      GLint convWidth, convHeight;
+      GLint convWidth = srcWidth, convHeight = srcHeight;
       GLfloat *convImage;
 
       /* pre-convolution image buffer (3D) */
@@ -594,8 +584,12 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
    /* unpack and transfer the source image */
    tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
                                        * components * sizeof(GLchan));
-   if (!tempImage)
+   if (!tempImage) {
+      if (freeSrcImage) {
+         _mesa_free((void *) srcAddr);
+      }
       return NULL;
+   }
 
    dst = tempImage;
    for (img = 0; img < srcDepth; img++) {
@@ -1083,7 +1077,43 @@ _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
 }
 
 
-#define STRIDE_3D 0
+/**
+ * Store a 24-bit integer depth component texture image.
+ */
+static GLboolean
+_mesa_texstore_z24_x8(TEXSTORE_PARAMS)
+{
+   const GLuint depthScale = 0xffffff;
+   const GLuint texelBytes = 4;
+
+   (void) dims;
+   ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
+
+   {
+      /* general path */
+      GLint img, row;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            const GLvoid *src = _mesa_image_address(dims, srcPacking,
+                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+            GLuint *dst = (GLuint *) dstRow;
+            GLint i;
+            _mesa_unpack_depth_span(ctx, srcWidth,
+                                    GL_UNSIGNED_INT, dst,
+                                    depthScale, srcType, src, srcPacking);
+            for (i = 0; i < srcWidth; i++)
+               dst[i] <<= 8;
+            dstRow += dstRowStride;
+         }
+      }
+   }
+   return GL_TRUE;
+}
+
 
 /**
  * Store a 16-bit integer depth component texture image.
@@ -1376,11 +1406,12 @@ _mesa_texstore_argb8888(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);
+   const GLenum baseFormat = GL_RGBA;
 
    ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
           dstFormat == MESA_FORMAT_ARGB8888_REV ||
-          dstFormat == MESA_FORMAT_XRGB8888);
+          dstFormat == MESA_FORMAT_XRGB8888 ||
+          dstFormat == MESA_FORMAT_XRGB8888_REV );
    ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
@@ -1401,7 +1432,8 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
    }
    else if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == MESA_FORMAT_ARGB8888_REV &&
+       (dstFormat == MESA_FORMAT_ARGB8888_REV ||
+        dstFormat == MESA_FORMAT_XRGB8888_REV) &&
        baseInternalFormat == GL_RGBA &&
        srcFormat == GL_BGRA &&
        ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
@@ -1494,7 +1526,8 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
        */
       if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
           (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
-         (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV)) {
+         (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
+         (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
         dstmap[3] = 3;         /* alpha */
         dstmap[2] = 0;         /* red */
         dstmap[1] = 1;         /* green */
@@ -1503,6 +1536,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
       else {
         assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
                (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
+               (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
                (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
         dstmap[3] = 2;
         dstmap[2] = 1;
@@ -2115,6 +2149,77 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
 }
 
 
+static GLboolean
+_mesa_texstore_al1616(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);
+   ASSERT(texelBytes == 4);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == MESA_FORMAT_AL1616 &&
+       baseInternalFormat == GL_LUMINANCE_ALPHA &&
+       srcFormat == GL_LUMINANCE_ALPHA &&
+       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;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstUI = (GLuint *) dstRow;
+            if (dstFormat == MESA_FORMAT_AL1616) {
+               for (col = 0; col < srcWidth; col++) {
+                  /* src[0] is luminance, src[1] is alpha */
+                 dstUI[col] = PACK_COLOR_88( FLOAT_TO_USHORT(src[1]),
+                                             FLOAT_TO_USHORT(src[0]) );
+                 src += 2;
+               }
+            }
+            else {
+               for (col = 0; col < srcWidth; col++) {
+                  /* src[0] is luminance, src[1] is alpha */
+                 dstUI[col] = PACK_COLOR_1616_REV( FLOAT_TO_UBYTE(src[1]),
+                                                  FLOAT_TO_UBYTE(src[0]) );
+                 src += 2;
+               }
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      _mesa_free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
 static GLboolean
 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
 {
@@ -3002,6 +3107,15 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
    return k;
 }
 
+#else
+
+/* these are used only in texstore_funcs[] below */
+#define _mesa_texstore_srgb8 NULL
+#define _mesa_texstore_srgba8 NULL
+#define _mesa_texstore_sargb8 NULL
+#define _mesa_texstore_sl8 NULL
+#define _mesa_texstore_sla8 NULL
+
 #endif /* FEATURE_EXT_texture_sRGB */
 
 
@@ -3011,7 +3125,7 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
  * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
  * XXX this is somewhat temporary.
  */
-static struct {
+static const struct {
    gl_format Name;
    StoreTexImageFunc Store;
 }
@@ -3023,6 +3137,7 @@ texstore_funcs[MESA_FORMAT_COUNT] =
    { MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 },
    { MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 },
    { MESA_FORMAT_XRGB8888, _mesa_texstore_argb8888 },
+   { MESA_FORMAT_XRGB8888_REV, _mesa_texstore_argb8888 },
    { MESA_FORMAT_RGB888, _mesa_texstore_rgb888 },
    { MESA_FORMAT_BGR888, _mesa_texstore_bgr888 },
    { MESA_FORMAT_RGB565, _mesa_texstore_rgb565 },
@@ -3034,6 +3149,8 @@ texstore_funcs[MESA_FORMAT_COUNT] =
    { 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_RGB332, _mesa_texstore_rgb332 },
    { MESA_FORMAT_A8, _mesa_texstore_a8 },
    { MESA_FORMAT_L8, _mesa_texstore_a8 },
@@ -3045,6 +3162,7 @@ texstore_funcs[MESA_FORMAT_COUNT] =
    { MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 },
    { MESA_FORMAT_Z16, _mesa_texstore_z16 },
    { MESA_FORMAT_X8_Z24, _mesa_texstore_x8_z24 },
+   { MESA_FORMAT_Z24_X8, _mesa_texstore_z24_x8 },
    { MESA_FORMAT_Z32, _mesa_texstore_z32 },
    { MESA_FORMAT_S8, NULL/*_mesa_texstore_s8*/ },
    { MESA_FORMAT_SRGB8, _mesa_texstore_srgb8 },
@@ -3081,20 +3199,44 @@ texstore_funcs[MESA_FORMAT_COUNT] =
 };
 
 
+static GLboolean
+_mesa_texstore_null(TEXSTORE_PARAMS)
+{
+   (void) ctx; (void) dims;
+   (void) baseInternalFormat;
+   (void) dstFormat;
+   (void) dstAddr;
+   (void) dstXoffset; (void) dstYoffset; (void) dstZoffset;
+   (void) dstRowStride; (void) dstImageOffsets;
+   (void) srcWidth; (void) srcHeight; (void) srcDepth;
+   (void) srcFormat; (void) srcType;
+   (void) srcAddr;
+   (void) srcPacking;
+
+   /* should never happen */
+   _mesa_problem(NULL, "_mesa_texstore_null() is called");
+   return GL_FALSE;
+}
+
+
 /**
  * Return the StoreTexImageFunc pointer to store an image in the given format.
  */
 static StoreTexImageFunc
 _mesa_get_texstore_func(gl_format format)
 {
-   GLuint i;
 #ifdef DEBUG
+   GLuint i;
    for (i = 0; i < MESA_FORMAT_COUNT; i++) {
       ASSERT(texstore_funcs[i].Name == i);
    }
 #endif
    ASSERT(texstore_funcs[format].Name == format);
-   return texstore_funcs[format].Store;
+
+   if (texstore_funcs[format].Store)
+      return texstore_funcs[format].Store;
+   else
+      return _mesa_texstore_null;
 }
 
 
@@ -3110,8 +3252,6 @@ _mesa_texstore(TEXSTORE_PARAMS)
 
    storeImage = _mesa_get_texstore_func(dstFormat);
 
-   assert(storeImage);
-
    success = storeImage(ctx, dims, baseInternalFormat,
                         dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
                         dstRowStride, dstImageOffsets,
@@ -3250,10 +3390,6 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
    GLuint sizeInBytes;
    (void) border;
 
-   texImage->TexFormat
-      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
-   ASSERT(texImage->TexFormat);
-
    /* allocate memory */
    sizeInBytes = texture_size(texImage);
    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
@@ -3311,10 +3447,6 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    GLuint sizeInBytes;
    (void) border;
 
-   texImage->TexFormat
-      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
-   ASSERT(texImage->TexFormat);
-
    /* allocate memory */
    sizeInBytes = texture_size(texImage);
    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
@@ -3368,10 +3500,6 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
    GLuint sizeInBytes;
    (void) border;
 
-   texImage->TexFormat
-      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
-   ASSERT(texImage->TexFormat);
-
    /* allocate memory */
    sizeInBytes = texture_size(texImage);
    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
@@ -3570,10 +3698,6 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    ASSERT(texImage->Depth == 1);
    ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
 
-   texImage->TexFormat
-      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 0, 0);
-   ASSERT(texImage->TexFormat);
-
    /* allocate storage */
    texImage->Data = _mesa_alloc_texmemory(imageSize);
    if (!texImage->Data) {