mesa: add glTextureParameteri/iv/f/fvEXT
[mesa.git] / src / mesa / main / texstore.c
index 4b13c42ed746f9321e1e418aa4770280fdf3a342..2913d4bc06718b7128be93e82d503b8ba7fe8917 100644 (file)
@@ -51,6 +51,7 @@
  */
 
 
+#include "errors.h"
 #include "glheader.h"
 #include "bufferobj.h"
 #include "format_pack.h"
 #include "enums.h"
 #include "glformats.h"
 #include "pixeltransfer.h"
-#include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
-#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
+#include "util/format_rgb9e5.h"
+#include "util/format_r11g11b10f.h"
 
 
 enum {
-   ZERO = 4, 
+   ZERO = 4,
    ONE = 5
 };
 
@@ -87,9 +88,6 @@ enum {
  * Texture image storage function.
  */
 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
-static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
-static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
-static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE };
 
 
 /**
@@ -433,47 +431,47 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
    for (img = 0; img < srcDepth; img++) {
       GLuint *dstRow = (GLuint *) dstSlices[img];
       const GLubyte *src
-        = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
-                                               srcWidth, srcHeight,
-                                               srcFormat, srcType,
-                                               img, 0, 0);
+         = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+                                                srcWidth, srcHeight,
+                                                srcFormat, srcType,
+                                                img, 0, 0);
       for (row = 0; row < srcHeight; row++) {
-        GLint i;
-        GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
-        
-        if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
-           keepstencil = GL_TRUE;
-        }
+         GLint i;
+         GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
+
+         if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
+            keepstencil = GL_TRUE;
+         }
          else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
-           keepdepth = GL_TRUE;
-        }
-
-        if (keepdepth == GL_FALSE)
-           /* the 24 depth bits will be in the low position: */
-           _mesa_unpack_depth_span(ctx, srcWidth,
-                                   GL_UNSIGNED_INT, /* dst type */
-                                   keepstencil ? depth : dstRow, /* dst addr */
-                                   depthScale,
-                                   srcType, src, srcPacking);   
-
-        if (keepstencil == GL_FALSE)
-           /* get the 8-bit stencil values */
-           _mesa_unpack_stencil_span(ctx, srcWidth,
-                                     GL_UNSIGNED_BYTE, /* dst type */
-                                     stencil, /* dst addr */
-                                     srcType, src, srcPacking,
-                                     ctx->_ImageTransferState);
-
-        /* merge stencil values into depth values */
-        for (i = 0; i < srcWidth; i++) {
-           if (keepstencil)
-              dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
-           else
-              dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
-
-        }
-        src += srcRowStride;
-        dstRow += dstRowStride / sizeof(GLuint);
+            keepdepth = GL_TRUE;
+         }
+
+         if (keepdepth == GL_FALSE)
+            /* the 24 depth bits will be in the low position: */
+            _mesa_unpack_depth_span(ctx, srcWidth,
+                                    GL_UNSIGNED_INT, /* dst type */
+                                    keepstencil ? depth : dstRow, /* dst addr */
+                                    depthScale,
+                                    srcType, src, srcPacking);
+
+         if (keepstencil == GL_FALSE)
+            /* get the 8-bit stencil values */
+            _mesa_unpack_stencil_span(ctx, srcWidth,
+                                      GL_UNSIGNED_BYTE, /* dst type */
+                                      stencil, /* dst addr */
+                                      srcType, src, srcPacking,
+                                      ctx->_ImageTransferState);
+
+         /* merge stencil values into depth values */
+         for (i = 0; i < srcWidth; i++) {
+            if (keepstencil)
+               dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
+            else
+               dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
+
+         }
+         src += srcRowStride;
+         dstRow += dstRowStride / sizeof(GLuint);
       }
    }
 
@@ -495,7 +493,7 @@ _mesa_texstore_s8(TEXSTORE_PARAMS)
 
    {
       const GLint srcRowStride
-        = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+         = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
       GLint img, row;
       GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
 
@@ -675,12 +673,10 @@ texstore_compressed(TEXSTORE_PARAMS)
 static GLboolean
 texstore_rgba(TEXSTORE_PARAMS)
 {
-   void *tempImage = NULL, *tempRGBA = NULL;
-   int srcRowStride, img;
+   void *tempImage = NULL;
+   int img;
    GLubyte *src, *dst;
-   uint32_t srcMesaFormat;
    uint8_t rebaseSwizzle[4];
-   bool needRebase;
    bool transferOpsDone = false;
 
    /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case
@@ -727,7 +723,9 @@ texstore_rgba(TEXSTORE_PARAMS)
        */
       GLint swapSize = _mesa_sizeof_packed_type(srcType);
       if (swapSize == 2 || swapSize == 4) {
-         int imageStride = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, srcType);
+         int imageStride = _mesa_image_image_stride(srcPacking, srcWidth,
+                                                    srcHeight, srcFormat,
+                                                    srcType);
          int bufferSize = imageStride * srcDepth;
          int layer;
          const uint8_t *src;
@@ -750,15 +748,18 @@ texstore_rgba(TEXSTORE_PARAMS)
       }
    }
 
-   srcRowStride =
+   int srcRowStride =
       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
 
-   srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType);
+   uint32_t srcMesaFormat =
+      _mesa_format_from_format_and_type(srcFormat, srcType);
+
    dstFormat = _mesa_get_srgb_format_linear(dstFormat);
 
    /* If we have transferOps then we need to convert to RGBA float first,
       then apply transferOps, then do the conversion to dst
     */
+   void *tempRGBA = NULL;
    if (!transferOpsDone &&
        _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
       /* Allocate RGBA float image */
@@ -766,7 +767,6 @@ texstore_rgba(TEXSTORE_PARAMS)
       tempRGBA = malloc(4 * elementCount * sizeof(float));
       if (!tempRGBA) {
          free(tempImage);
-         free(tempRGBA);
          return GL_FALSE;
       }
 
@@ -800,6 +800,7 @@ texstore_rgba(TEXSTORE_PARAMS)
       _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
                           srcFormat, srcType, 0, 0, 0);
 
+   bool needRebase;
    if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) {
       needRebase =
          _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat,
@@ -906,6 +907,8 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS)
                         srcAddr, srcPacking);
    return GL_TRUE;
 }
+
+
 /**
  * Store user data into texture memory.
  * Called via glTex[Sub]Image1/2/3D()
@@ -1054,7 +1057,8 @@ store_texsubimage(struct gl_context *ctx,
                                                 format, type);
       break;
    default:
-      _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
+      _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()",
+                    target);
       return;
    }
 
@@ -1244,11 +1248,11 @@ _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
       return;
    }
 
-   _mesa_store_compressed_texsubimage(ctx, dims, texImage,
-                                      0, 0, 0,
-                                      texImage->Width, texImage->Height, texImage->Depth,
-                                      texImage->TexFormat,
-                                      imageSize, data);
+   ctx->Driver.CompressedTexSubImage(ctx, dims, texImage,
+                                     0, 0, 0,
+                                     texImage->Width, texImage->Height, texImage->Depth,
+                                     texImage->TexFormat,
+                                     imageSize, data);
 }
 
 
@@ -1268,16 +1272,16 @@ _mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat,
                                     const struct gl_pixelstore_attrib *packing,
                                     struct compressed_pixelstore *store)
 {
-   GLuint bw, bh;
+   GLuint bw, bh, bd;
 
-   _mesa_get_format_block_size(texFormat, &bw, &bh);
+   _mesa_get_format_block_size_3d(texFormat, &bw, &bh, &bd);
 
    store->SkipBytes = 0;
    store->TotalBytesPerRow = store->CopyBytesPerRow =
          _mesa_format_row_stride(texFormat, width);
    store->TotalRowsPerSlice = store->CopyRowsPerSlice =
          (height + bh - 1) / bh;
-   store->CopySlices = depth;
+   store->CopySlices = (depth + bd - 1) / bd;
 
    if (packing->CompressedBlockWidth &&
        packing->CompressedBlockSize) {
@@ -1289,7 +1293,8 @@ _mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat,
             ((packing->RowLength + bw - 1) / bw);
       }
 
-      store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw;
+      store->SkipBytes +=
+         packing->SkipPixels * packing->CompressedBlockSize / bw;
    }
 
    if (dims > 1 && packing->CompressedBlockHeight &&
@@ -1361,16 +1366,24 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
       if (dstMap) {
 
          /* copy rows of blocks */
-         for (i = 0; i < store.CopyRowsPerSlice; i++) {
-            memcpy(dstMap, src, store.CopyBytesPerRow);
-            dstMap += dstRowStride;
-            src += store.TotalBytesPerRow;
+         if (dstRowStride == store.TotalBytesPerRow &&
+             dstRowStride == store.CopyBytesPerRow) {
+            memcpy(dstMap, src, store.CopyBytesPerRow * store.CopyRowsPerSlice);
+            src += store.CopyBytesPerRow * store.CopyRowsPerSlice;
+         }
+         else {
+            for (i = 0; i < store.CopyRowsPerSlice; i++) {
+               memcpy(dstMap, src, store.CopyBytesPerRow);
+               dstMap += dstRowStride;
+               src += store.TotalBytesPerRow;
+            }
          }
 
          ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset);
 
          /* advance to next slice */
-         src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);
+         src += store.TotalBytesPerRow * (store.TotalRowsPerSlice
+                                          - store.CopyRowsPerSlice);
       }
       else {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",