mesa: Remove target parameter from dd_function_table::MapBuffer
[mesa.git] / src / mesa / main / texgetimage.c
index b23317c46a06d79058ca371f07e6efa4f8e0a27c..a54da7160c71dd4f1d7ffeedbced7fea17a8c9a9 100644 (file)
@@ -40,6 +40,7 @@
 #include "pack.h"
 #include "pbo.h"
 #include "texgetimage.h"
+#include "texfetch.h"
 #include "teximage.h"
 
 
@@ -220,146 +221,61 @@ get_tex_ycbcr(struct gl_context *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(struct gl_context *ctx, GLuint dimensions,
-             GLenum format, GLenum type, GLvoid *pixels,
-             const struct gl_texture_image *texImage)
-{
-   const GLint width = texImage->Width;
-   const GLint height = texImage->Height;
-   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++) {
-         void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
-                                          width, height, format, type,
-                                          img, row, 0);
-
-         GLint col;
-
-         /* convert row to RGBA format */
-         for (col = 0; col < width; col++) {
-            texImage->FetchTexelf(texImage, col, row, img, rgba[col]);
-            if (texImage->_BaseFormat == GL_LUMINANCE) {
-               rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
-               rgba[col][GCOMP] = 0.0;
-               rgba[col][BCOMP] = 0.0;
-            }
-            else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
-               rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
-               rgba[col][GCOMP] = 0.0;
-               rgba[col][BCOMP] = 0.0;
-            }
-            else if (texImage->_BaseFormat == GL_RGB ||
-                     texImage->_BaseFormat == GL_RGBA) {
-               rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
-               rgba[col][GCOMP] = linear_to_nonlinear(rgba[col][GCOMP]);
-               rgba[col][BCOMP] = linear_to_nonlinear(rgba[col][BCOMP]);
-            }
-         }
-         _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
-                                    format, type, dest,
-                                    &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.
+ * glGetTexImage for (s)RGBA, Luminance, etc. pixels.
  * This is the slow way since we use texture sampling.
  */
 static void
 get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
              GLenum format, GLenum type, GLvoid *pixels,
-             const struct gl_texture_image *texImage)
+             struct gl_texture_image *texImage)
 {
    const GLint width = texImage->Width;
    const GLint height = texImage->Height;
    const GLint depth = texImage->Depth;
+   const GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
    /* Normally, no pixel transfer ops are performed during glGetTexImage.
     * The only possible exception is component clamping to [0,1].
     */
    GLbitfield transferOps = 0x0;
    GLint img, row;
    GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+   const GLboolean is_sampler_srgb_decode =
+       _mesa_get_format_color_encoding(texImage->TexFormat) == GL_SRGB &&
+       texImage->TexObject->Sampler.sRGBDecode == GL_DECODE_EXT;
 
    if (!rgba) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
       return;
    }
 
+   /* Clamping does not apply to GetTexImage (final conversion)?
+    * Looks like we need clamp though when going from format
+    * containing negative values to unsigned format.
+    */
+   if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
+      transferOps |= IMAGE_CLAMP_BIT;
+   }
+   else if (!type_with_negative_values(type) &&
+            (dataType == GL_FLOAT ||
+             dataType == GL_SIGNED_NORMALIZED)) {
+      transferOps |= IMAGE_CLAMP_BIT;
+   }
+
+   /* glGetTexImage always returns sRGB data for sRGB textures. Make sure the
+    * fetch functions return sRGB data without linearizing it.
+    */
+   if (is_sampler_srgb_decode) {
+      texImage->TexObject->Sampler.sRGBDecode = GL_SKIP_DECODE_EXT;
+      _mesa_set_fetch_functions(texImage, dimensions);
+   }
+
    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);
          GLint col;
-         GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
-
-         /* clamp does not apply to GetTexImage (final conversion)?
-          * Looks like we need clamp though when going from format
-          * containing negative values to unsigned format.
-          */
-         if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
-            transferOps |= IMAGE_CLAMP_BIT;
-         }
-         else if (!type_with_negative_values(type) &&
-                  (dataType == GL_FLOAT ||
-                   dataType == GL_SIGNED_NORMALIZED)) {
-            transferOps |= IMAGE_CLAMP_BIT;
-         }
 
          for (col = 0; col < width; col++) {
             texImage->FetchTexelf(texImage, col, row, img, rgba[col]);
@@ -389,6 +305,11 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
       }
    }
 
+   if (is_sampler_srgb_decode) {
+      texImage->TexObject->Sampler.sRGBDecode = GL_DECODE_EXT;
+      _mesa_set_fetch_functions(texImage, dimensions);
+   }
+
    free(rgba);
 }
 
@@ -520,8 +441,7 @@ _mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
        * texture data to the PBO if the PBO is in VRAM along with the texture.
        */
       GLubyte *buf = (GLubyte *)
-         ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                               GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
+         ctx->Driver.MapBuffer(ctx, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
       if (!buf) {
          /* out of memory or other unexpected error */
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage(map PBO failed)");
@@ -548,16 +468,12 @@ _mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
    else if (format == GL_YCBCR_MESA) {
       get_tex_ycbcr(ctx, dimensions, format, type, pixels, texImage);
    }
-   else if (_mesa_get_format_color_encoding(texImage->TexFormat) == GL_SRGB) {
-      get_tex_srgb(ctx, dimensions, format, type, pixels, texImage);
-   }
    else {
       get_tex_rgba(ctx, dimensions, format, type, pixels, texImage);
    }
 
    if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
-      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                              ctx->Pack.BufferObj);
+      ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj);
    }
 }
 
@@ -582,8 +498,7 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, GLenum target, GLint level
    if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
       /* pack texture image into a PBO */
       GLubyte *buf = (GLubyte *)
-         ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                               GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
+         ctx->Driver.MapBuffer(ctx, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
       if (!buf) {
          /* out of memory or other unexpected error */
          _mesa_error(ctx, GL_OUT_OF_MEMORY,
@@ -613,8 +528,7 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, GLenum target, GLint level
    }
 
    if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
-      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                              ctx->Pack.BufferObj);
+      ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj);
    }
 }