mesa: fix _mesa_store_texsubimage2d() for GL_TEXTURE_1D_ARRAY
[mesa.git] / src / mesa / main / texstore.c
index 6319e70e6c567f98d02dcb2b9e5eabd649b4283c..fb1ad04e014162b5ce7a19a5bf629a6f7a6d997d 100644 (file)
@@ -67,6 +67,7 @@
 #include "texcompress_fxt1.h"
 #include "texcompress_rgtc.h"
 #include "texcompress_s3tc.h"
+#include "texcompress_etc.h"
 #include "teximage.h"
 #include "texstore.h"
 #include "enums.h"
@@ -953,8 +954,7 @@ memcpy_texture(struct gl_context *ctx,
          GLubyte *dstImage = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
-         ctx->Driver.TextureMemCpy(dstImage, srcImage,
-                                   bytesPerRow * srcHeight);
+         memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
          srcImage += srcImageStride;
       }
    }
@@ -967,7 +967,7 @@ memcpy_texture(struct gl_context *ctx,
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
+            memcpy(dstRow, srcRow, bytesPerRow);
             dstRow += dstRowStride;
             srcRow += srcRowStride;
          }
@@ -2141,8 +2141,8 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
 
    ASSERT(dstFormat == MESA_FORMAT_AL88 ||
           dstFormat == MESA_FORMAT_AL88_REV ||
-          dstFormat == MESA_FORMAT_RG88 ||
-          dstFormat == MESA_FORMAT_RG88_REV);
+          dstFormat == MESA_FORMAT_GR88 ||
+          dstFormat == MESA_FORMAT_RG88);
    ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
@@ -2150,7 +2150,7 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
        ((dstFormat == MESA_FORMAT_AL88 &&
          baseInternalFormat == GL_LUMINANCE_ALPHA &&
          srcFormat == GL_LUMINANCE_ALPHA) ||
-        (dstFormat == MESA_FORMAT_RG88 &&
+        (dstFormat == MESA_FORMAT_GR88 &&
          baseInternalFormat == srcFormat)) &&
        srcType == GL_UNSIGNED_BYTE &&
        littleEndian) {
@@ -2182,8 +2182,8 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
         }
       }
       else {
-        if ((littleEndian && dstFormat == MESA_FORMAT_RG88) ||
-            (!littleEndian && dstFormat == MESA_FORMAT_RG88_REV)) {
+        if ((littleEndian && dstFormat == MESA_FORMAT_GR88) ||
+            (!littleEndian && dstFormat == MESA_FORMAT_RG88)) {
            dstmap[0] = 0;
            dstmap[1] = 1;
         }
@@ -2224,9 +2224,9 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             if (dstFormat == MESA_FORMAT_AL88 ||
-               dstFormat == MESA_FORMAT_RG88) {
+               dstFormat == MESA_FORMAT_GR88) {
                for (col = 0; col < srcWidth; col++) {
-                  /* src[0] is luminance, src[1] is alpha */
+                  /* src[0] is luminance (or R), src[1] is alpha (or G) */
                  dstUS[col] = PACK_COLOR_88( src[1],
                                              src[0] );
                  src += 2;
@@ -2234,7 +2234,7 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
             }
             else {
                for (col = 0; col < srcWidth; col++) {
-                  /* src[0] is luminance, src[1] is alpha */
+                  /* src[0] is luminance (or R), src[1] is alpha (or G) */
                  dstUS[col] = PACK_COLOR_88_REV( src[1],
                                                  src[0] );
                  src += 2;
@@ -3568,6 +3568,8 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_RG ||
+          baseInternalFormat == GL_RED ||
           baseInternalFormat == GL_ALPHA ||
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
@@ -3638,6 +3640,8 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_RG ||
+          baseInternalFormat == GL_RED ||
           baseInternalFormat == GL_ALPHA ||
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
@@ -3708,6 +3712,8 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_RG ||
+          baseInternalFormat == GL_RED ||
           baseInternalFormat == GL_ALPHA ||
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
@@ -3778,6 +3784,8 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_RG ||
+          baseInternalFormat == GL_RED ||
           baseInternalFormat == GL_ALPHA ||
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
@@ -3846,6 +3854,8 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_RG ||
+          baseInternalFormat == GL_RED ||
           baseInternalFormat == GL_ALPHA ||
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
@@ -3914,6 +3924,8 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_RG ||
+          baseInternalFormat == GL_RED ||
           baseInternalFormat == GL_ALPHA ||
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
@@ -4374,8 +4386,8 @@ _mesa_get_texstore_func(gl_format format)
       table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
       table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
       table[MESA_FORMAT_R8] = _mesa_texstore_unorm8;
+      table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88;
       table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88;
-      table[MESA_FORMAT_RG88_REV] = _mesa_texstore_unorm88;
       table[MESA_FORMAT_R16] = _mesa_texstore_unorm16;
       table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616;
       table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616;
@@ -4437,6 +4449,7 @@ _mesa_get_texstore_func(gl_format format)
       table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1;
       table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
       table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
+      table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
       table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
       table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
       table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
@@ -4832,7 +4845,7 @@ _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
    if (!pixels)
       return;
 
-   /* Map dest texture buffer (write to whole region) */
+   /* Map dest texture buffer */
    ctx->Driver.MapTextureImage(ctx, texImage, 0,
                                xoffset, 0, width, 1,
                                rwMode,
@@ -4875,35 +4888,56 @@ _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
                           struct gl_texture_image *texImage)
 {
    const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
-   GLubyte *dstMap;
-   GLint dstRowStride;
-   GLboolean success;
+   GLboolean success = GL_FALSE;
+   GLuint slice, numSlices, sliceOffset, srcImageStride;
+   const GLubyte *src;
 
    /* get pointer to src pixels (may be in a pbo which we'll map here) */
-   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
-                                        pixels, packing, "glTexSubImage2D");
-   if (!pixels)
+   src = (const GLubyte *)
+      _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
+                                  pixels, packing, "glTexSubImage2D");
+   if (!src)
       return;
 
-   /* Map dest texture buffer (write to whole region) */
-   ctx->Driver.MapTextureImage(ctx, texImage, 0,
-                               xoffset, yoffset, width, height,
-                               rwMode,
-                               &dstMap, &dstRowStride);
-
-   if (dstMap) {
-      success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
-                               texImage->TexFormat,
-                               0, 0, 0,  /* dstX/Y/Zoffset */
-                               dstRowStride,
-                               &dstMap,
-                               width, height, 1,
-                               format, type, pixels, packing);
-
-      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+   if (target == GL_TEXTURE_1D_ARRAY) {
+      /* map each slice of the 1D array separately */
+      numSlices = height;
+      sliceOffset = yoffset;
+      height = 1;
+      yoffset = 0;
+      srcImageStride = _mesa_image_row_stride(packing, width, format, type);
    }
    else {
-      success = GL_FALSE;
+      /* regular 2D image */
+      numSlices = 1;
+      sliceOffset = 0;
+      srcImageStride = 0;
+   }
+
+   for (slice = 0; slice < numSlices; slice++) {
+      GLubyte *dstMap;
+      GLint dstRowStride;
+
+      ctx->Driver.MapTextureImage(ctx, texImage,
+                                  slice + sliceOffset,
+                                  xoffset, yoffset, width, height,
+                                  rwMode, &dstMap, &dstRowStride);
+      if (dstMap) {
+         success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                                  texImage->TexFormat,
+                                  0, 0, 0,  /* dstX/Y/Zoffset */
+                                  dstRowStride,
+                                  &dstMap,
+                                  width, height, 1,  /* w, h, d */
+                                  format, type, src, packing);
+
+         ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
+      }
+
+      src += srcImageStride;
+
+      if (!success)
+         break;
    }
 
    if (!success)
@@ -5015,11 +5049,9 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
                                   struct gl_texture_object *texObj,
                                   struct gl_texture_image *texImage)
 {
-   GLubyte *dstMap;
-   GLint dstRowStride;
-
-   /* This is pretty simple, basically just do a memcpy without worrying
-    * about the usual image unpacking or image transfer operations.
+   /* This is pretty simple, because unlike the general texstore path we don't
+    * have to worry about the usual image unpacking or image transfer
+    * operations.
     */
    ASSERT(texObj);
    ASSERT(texImage);
@@ -5034,29 +5066,12 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
       return;
    }
 
-   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
-                                                 &ctx->Unpack,
-                                                 "glCompressedTexImage2D");
-   if (!data)
-      return;
-
-
-   /* Map dest texture buffer (write to whole region) */
-   ctx->Driver.MapTextureImage(ctx, texImage, 0,
-                               0, 0, width, height,
-                               GL_MAP_WRITE_BIT,
-                               &dstMap, &dstRowStride);
-   if (dstMap) {
-      /* copy the data */
-      memcpy(dstMap, data, imageSize);
-
-      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
-   }
-   else {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
-   }
-
-   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
+   _mesa_store_compressed_texsubimage2d(ctx, target, level,
+                                       0, 0,
+                                       width, height,
+                                       texImage->TexFormat,
+                                       imageSize, data,
+                                       texObj, texImage);
 }
 
 
@@ -5133,8 +5148,8 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
    _mesa_get_format_block_size(texFormat, &bw, &bh);
 
    /* these should have been caught sooner */
-   ASSERT((width % bw) == 0 || width == 2 || width == 1);
-   ASSERT((height % bh) == 0 || height == 2 || height == 1);
+   ASSERT((width % bw) == 0 || width < bw);
+   ASSERT((height % bh) == 0 || height < bh);
    ASSERT((xoffset % bw) == 0);
    ASSERT((yoffset % bh) == 0);
 
@@ -5148,7 +5163,7 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
    srcRowStride = _mesa_format_row_stride(texFormat, width);
    src = (const GLubyte *) data;
 
-   /* Map dest texture buffer (write to whole region) */
+   /* Map dest texture buffer */
    ctx->Driver.MapTextureImage(ctx, texImage, 0,
                                xoffset, yoffset, width, height,
                                GL_MAP_WRITE_BIT,
@@ -5156,7 +5171,7 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
 
    if (dstMap) {
       bytesPerRow = srcRowStride;  /* bytes per row of blocks */
-      rows = height / bh;  /* rows in blocks */
+      rows = (height + bh - 1) / bh;  /* rows in blocks */
 
       /* copy rows of blocks */
       for (i = 0; i < rows; i++) {