mesa: move PBO-related functions into a new file
[mesa.git] / src / mesa / main / texgetimage.c
index 23765d275305b1b5a5ebbdd56e107e17c725e560..21d9140c5507d48fc8b490ef8c4a82b171c00fa2 100644 (file)
 #include "context.h"
 #include "formats.h"
 #include "image.h"
-#include "texcompress.h"
+#include "mfeatures.h"
+#include "mtypes.h"
+#include "pack.h"
+#include "pbo.h"
 #include "texgetimage.h"
 #include "teximage.h"
-#include "texstate.h"
 
 
 
-#if FEATURE_EXT_texture_sRGB
-
-/**
- * Convert a float value from linear space to a
- * non-linear sRGB value in [0, 255].
- * Not terribly efficient.
- */
-static INLINE GLfloat
-linear_to_nonlinear(GLfloat cl)
-{
-   /* can't have values outside [0, 1] */
-   GLfloat cs;
-   if (cl < 0.0031308f) {
-      cs = 12.92f * cl;
-   }
-   else {
-      cs = (GLfloat)(1.055 * _mesa_pow(cl, 0.41666) - 0.055);
-   }
-   return cs;
-}
-
-#endif /* FEATURE_EXT_texture_sRGB */
-
-
 /**
  * Can the given type represent negative values?
  */
@@ -89,7 +67,7 @@ type_with_negative_values(GLenum type)
  * glGetTexImage for color index pixels.
  */
 static void
-get_tex_color_index(GLcontext *ctx, GLuint dimensions,
+get_tex_color_index(struct gl_context *ctx, GLuint dimensions,
                     GLenum format, GLenum type, GLvoid *pixels,
                     const struct gl_texture_image *texImage)
 {
@@ -103,7 +81,7 @@ get_tex_color_index(GLcontext *ctx, GLuint dimensions,
 
    for (img = 0; img < depth; img++) {
       for (row = 0; row < height; row++) {
-         GLuint indexRow[MAX_WIDTH];
+         GLuint indexRow[MAX_WIDTH] = { 0 };
          void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                           width, height, format, type,
                                           img, row, 0);
@@ -137,7 +115,7 @@ get_tex_color_index(GLcontext *ctx, GLuint dimensions,
  * glGetTexImage for depth/Z pixels.
  */
 static void
-get_tex_depth(GLcontext *ctx, GLuint dimensions,
+get_tex_depth(struct gl_context *ctx, GLuint dimensions,
               GLenum format, GLenum type, GLvoid *pixels,
               const struct gl_texture_image *texImage)
 {
@@ -145,10 +123,15 @@ get_tex_depth(GLcontext *ctx, GLuint dimensions,
    const GLint height = texImage->Height;
    const GLint depth = texImage->Depth;
    GLint img, row, col;
+   GLfloat *depthRow = (GLfloat *) malloc(width * sizeof(GLfloat));
+
+   if (!depthRow) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+      return;
+   }
 
    for (img = 0; img < depth; img++) {
       for (row = 0; row < height; row++) {
-         GLfloat depthRow[MAX_WIDTH];
          void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                           width, height, format, type,
                                           img, row, 0);
@@ -160,6 +143,8 @@ get_tex_depth(GLcontext *ctx, GLuint dimensions,
          _mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack);
       }
    }
+
+   free(depthRow);
 }
 
 
@@ -167,7 +152,7 @@ get_tex_depth(GLcontext *ctx, GLuint dimensions,
  * glGetTexImage for depth/stencil pixels.
  */
 static void
-get_tex_depth_stencil(GLcontext *ctx, GLuint dimensions,
+get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
                       GLenum format, GLenum type, GLvoid *pixels,
                       const struct gl_texture_image *texImage)
 {
@@ -182,7 +167,7 @@ get_tex_depth_stencil(GLcontext *ctx, GLuint dimensions,
          void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                           width, height, format, type,
                                           img, row, 0);
-         _mesa_memcpy(dest, src, width * sizeof(GLuint));
+         memcpy(dest, src, width * sizeof(GLuint));
          if (ctx->Pack.SwapBytes) {
             _mesa_swap4((GLuint *) dest, width);
          }
@@ -197,7 +182,7 @@ get_tex_depth_stencil(GLcontext *ctx, GLuint dimensions,
  * glGetTexImage for YCbCr pixels.
  */
 static void
-get_tex_ycbcr(GLcontext *ctx, GLuint dimensions,
+get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
               GLenum format, GLenum type, GLvoid *pixels,
               const struct gl_texture_image *texImage)
 {
@@ -213,7 +198,7 @@ get_tex_ycbcr(GLcontext *ctx, GLuint dimensions,
          void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                           width, height, format, type,
                                           img, row, 0);
-         _mesa_memcpy(dest, src, width * sizeof(GLushort));
+         memcpy(dest, src, width * sizeof(GLushort));
 
          /* check for byte swapping */
          if ((texImage->TexFormat == MESA_FORMAT_YCBCR
@@ -233,11 +218,34 @@ get_tex_ycbcr(GLcontext *ctx, GLuint dimensions,
 }
 
 
+#if FEATURE_EXT_texture_sRGB
+
+
+/**
+ * Convert a float value from linear space to a
+ * non-linear sRGB value in [0, 255].
+ * Not terribly efficient.
+ */
+static INLINE GLfloat
+linear_to_nonlinear(GLfloat cl)
+{
+   /* can't have values outside [0, 1] */
+   GLfloat cs;
+   if (cl < 0.0031308f) {
+      cs = 12.92f * cl;
+   }
+   else {
+      cs = (GLfloat)(1.055 * pow(cl, 0.41666) - 0.055);
+   }
+   return cs;
+}
+
+
 /**
  * glGetTexImagefor sRGB pixels;
  */
 static void
-get_tex_srgb(GLcontext *ctx, GLuint dimensions,
+get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
              GLenum format, GLenum type, GLvoid *pixels,
              const struct gl_texture_image *texImage)
 {
@@ -246,6 +254,12 @@ get_tex_srgb(GLcontext *ctx, GLuint dimensions,
    const GLint depth = texImage->Depth;
    const GLbitfield transferOps = 0x0;
    GLint img, row;
+   GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+
+   if (!rgba) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+      return;
+   }
 
    for (img = 0; img < depth; img++) {
       for (row = 0; row < height; row++) {
@@ -253,7 +267,6 @@ get_tex_srgb(GLcontext *ctx, GLuint dimensions,
                                           width, height, format, type,
                                           img, row, 0);
 
-         GLfloat rgba[MAX_WIDTH][4];
          GLint col;
 
          /* convert row to RGBA format */
@@ -281,15 +294,32 @@ get_tex_srgb(GLcontext *ctx, GLuint dimensions,
                                     &ctx->Pack, transferOps);
       }
    }
+
+   free(rgba);
 }
 
 
+#else /* FEATURE_EXT_texture_sRGB */
+
+
+static INLINE void
+get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
+             GLenum format, GLenum type, GLvoid *pixels,
+             const struct gl_texture_image *texImage)
+{
+   ASSERT_NO_FEATURE();
+}
+
+
+#endif /* FEATURE_EXT_texture_sRGB */
+
+
 /**
  * glGetTexImagefor RGBA, Luminance, etc. pixels.
  * This is the slow way since we use texture sampling.
  */
 static void
-get_tex_rgba(GLcontext *ctx, GLuint dimensions,
+get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
              GLenum format, GLenum type, GLvoid *pixels,
              const struct gl_texture_image *texImage)
 {
@@ -301,13 +331,18 @@ get_tex_rgba(GLcontext *ctx, GLuint dimensions,
     */
    GLbitfield transferOps = 0x0;
    GLint img, row;
+   GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+
+   if (!rgba) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+      return;
+   }
 
    for (img = 0; img < depth; img++) {
       for (row = 0; row < height; row++) {
          void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                           width, height, format, type,
                                           img, row, 0);
-         GLfloat rgba[MAX_WIDTH][4];
          GLint col;
          GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
 
@@ -351,6 +386,8 @@ get_tex_rgba(GLcontext *ctx, GLuint dimensions,
                                     &ctx->Pack, transferOps);
       }
    }
+
+   free(rgba);
 }
 
 
@@ -359,7 +396,7 @@ get_tex_rgba(GLcontext *ctx, GLuint dimensions,
  * \return GL_TRUE if done, GL_FALSE otherwise
  */
 static GLboolean
-get_tex_memcpy(GLcontext *ctx, GLenum format, GLenum type, GLvoid *pixels,
+get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels,
                const struct gl_texture_object *texObj,
                const struct gl_texture_image *texImage)
 {
@@ -398,11 +435,21 @@ get_tex_memcpy(GLcontext *ctx, GLenum format, GLenum type, GLvoid *pixels,
                type == GL_UNSIGNED_BYTE) {
          memCopy = GL_TRUE;
       }
+      else if (texImage->TexFormat == MESA_FORMAT_L16 &&
+               format == GL_LUMINANCE &&
+               type == GL_UNSIGNED_SHORT) {
+         memCopy = GL_TRUE;
+      }
       else if (texImage->TexFormat == MESA_FORMAT_A8 &&
                format == GL_ALPHA &&
                type == GL_UNSIGNED_BYTE) {
          memCopy = GL_TRUE;
       }
+      else if (texImage->TexFormat == MESA_FORMAT_A16 &&
+               format == GL_ALPHA &&
+               type == GL_UNSIGNED_SHORT) {
+         memCopy = GL_TRUE;
+      }
    }
 
    if (memCopy) {
@@ -439,7 +486,7 @@ get_tex_memcpy(GLcontext *ctx, GLenum format, GLenum type, GLvoid *pixels,
  * The texture image must be mapped.
  */
 void
-_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
+_mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
                    GLenum format, GLenum type, GLvoid *pixels,
                    struct gl_texture_object *texObj,
                    struct gl_texture_image *texImage)
@@ -516,7 +563,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
  * All error checking will have been done before this routine is called.
  */
 void
-_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
+_mesa_get_compressed_teximage(struct gl_context *ctx, GLenum target, GLint level,
                               GLvoid *img,
                               struct gl_texture_object *texObj,
                               struct gl_texture_image *texImage)
@@ -548,14 +595,15 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
                                                   texImage->Width,
                                                   texImage->Height,
                                                   texImage->Depth);
-      _mesa_memcpy(img, texImage->Data, size);
+      memcpy(img, texImage->Data, size);
    }
    else {
       GLuint bw, bh;
       _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
       for (i = 0; i < (texImage->Height + bh - 1) / bh; i++) {
          memcpy((GLubyte *)img + i * row_stride,
-                (GLubyte *)texImage->Data + i * row_stride_stored, row_stride);
+                (GLubyte *)texImage->Data + i * row_stride_stored,
+                row_stride);
       }
    }
 
@@ -572,12 +620,12 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
  * \return GL_TRUE if any error, GL_FALSE if no errors.
  */
 static GLboolean
-getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
+getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
                         GLenum format, GLenum type, GLvoid *pixels )
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
+   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
    GLenum baseFormat;
 
    if (maxLevels == 0) {
@@ -758,12 +806,12 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
  * \return GL_TRUE if any error, GL_FALSE if no errors.
  */
 static GLboolean
-getcompressedteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
-                                  GLvoid *img)
+getcompressedteximage_error_check(struct gl_context *ctx, GLenum target,
+                                  GLint level, GLvoid *img)
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
+   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
 
    if (maxLevels == 0) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)",